ProfitsRepository.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. namespace app\common\repositories\profits;
  3. use app\common\dao\profit\ZeroUserProfitDao;
  4. use app\common\dao\store\order\OldUserOfGoodsDao;
  5. use app\common\dao\store\order\StoreOrderDao;
  6. use app\common\dao\user\UserDao;
  7. use app\common\dao\user\ZeroUserLineDao;
  8. use app\common\enum\user\ZeroUserEnum;
  9. use app\common\model\profit\ZeroUserProfitsDetail;
  10. use app\jobs\ZeroUserProfits;
  11. use think\db\exception\DataNotFoundException;
  12. use think\db\exception\DbException;
  13. use think\db\exception\ModelNotFoundException;
  14. use think\facade\Db;
  15. class ProfitsRepository
  16. {
  17. // 初级合伙人id
  18. const BASIC = 4;
  19. // 初级合伙人佣金比例
  20. const BASIC_PERCENT = 0.15;
  21. // 中级合伙人id
  22. const MIDDLE = 5;
  23. // 中级合伙人佣金比例
  24. const MIDDLE_PERCENT = 0.15;
  25. // 高级合伙人id
  26. const HIGH = 6;
  27. // 高级合伙人佣金比例
  28. const HIGH_PERCENT = 0.15;
  29. // 合伙人数据映射
  30. private $parents = [
  31. self::BASIC => self::BASIC_PERCENT,
  32. self::MIDDLE => self::MIDDLE_PERCENT,
  33. self::HIGH => self::HIGH_PERCENT,
  34. ];
  35. // 业绩数据映射(pv)
  36. private $pv = [
  37. 1180 => 700,
  38. 11800 => 7000,
  39. 10620 => 6300,
  40. 9440 => 5600,
  41. 2360 => 1400
  42. ];
  43. // 用户
  44. private $userDao;
  45. // 订单(老)
  46. // private $oldUserOfGoodsDao;
  47. // 订单(新)
  48. // private $storeOrder;
  49. public function __construct()
  50. {
  51. $this->userDao = new UserDao();
  52. // $this->oldUserOfGoodsDao = new OldUserOfGoodsDao();
  53. // $this->storeOrder = new StoreOrderDao();
  54. }
  55. /**
  56. * @param $param
  57. * @return string|true
  58. * @throws DataNotFoundException
  59. * @throws DbException
  60. * @throws ModelNotFoundException
  61. * 获取需要分红的0号线用户并加入队列
  62. */
  63. public function getZeroUser($param)
  64. {
  65. $zeroUserId = $param['zeroUserId'];
  66. // 0号线用户id是0的时候,获取全部0号线用户
  67. if ($zeroUserId == 0) {
  68. $zeroUserId = $this->getAllZeroUserIds();
  69. }
  70. if (is_string($zeroUserId)) {
  71. $zeroUserId = explode(',', $zeroUserId);
  72. }
  73. // 拼接队列需要的数据
  74. $queueData = [
  75. 'startTime' => $param['startTime'],
  76. 'endTime' => $param['endTime'],
  77. 'is_test' => $param['isTest'],
  78. 'amount' => $param['amount']
  79. ];
  80. // 记录日志
  81. $insertData = [
  82. 'start_time' => $param['startTime'],
  83. 'end_time' => $param['endTime'],
  84. 'is_test' => $param['isTest'],
  85. 'amount' => $param['amount']
  86. ];
  87. $dao = new ZeroUserProfitDao();
  88. // 加入队列
  89. try {
  90. foreach ($zeroUserId as $value) {
  91. $insertData['user_id'] = $value;
  92. $logId = $dao->insertGetId($insertData);
  93. $queueData['zeroUserId'] = $value;
  94. $queueData['logId'] = $logId;
  95. queue(ZeroUserProfits::class, $queueData, 0, 'zeroProfit');
  96. }
  97. return true;
  98. } catch (\Exception $e) {
  99. return $e->getMessage();
  100. }
  101. }
  102. /**
  103. * @throws DataNotFoundException
  104. * @throws ModelNotFoundException
  105. * @throws DbException
  106. * 执行分红
  107. */
  108. public function profits($param)
  109. {
  110. try {
  111. // 获取0号线用户的所有下级用户
  112. $userIds = $this->getAllUser($param['zeroUserId']);
  113. // 获取分红总额(业绩)
  114. $amount = $param['amount'];
  115. if ($param['amount'] == 0) {
  116. $amount = $this->getAmount($userIds);
  117. }
  118. // 计算分红
  119. $directUids = [];
  120. foreach ($this->parents as $key => $value) {
  121. // 获取初,中,高用户
  122. unset($groupData);
  123. $groupData = $this->getUserByGroup($userIds, $key);
  124. if (!empty($groupData)) {
  125. // 获取初中高用户直推和团队业绩
  126. $profitDetail = $this->getDirect($groupData, $amount * $value);
  127. $directUids[$key] = $profitDetail;
  128. $this->recordLog($param, $amount, $profitDetail);
  129. }
  130. }
  131. return true;
  132. } catch (\Exception $e) {
  133. return false;
  134. }
  135. }
  136. /**
  137. * @param $param
  138. * @return array
  139. * 获取要分红的用户ids
  140. */
  141. private function getUserIds($param): array
  142. {
  143. $res = $this->getAllZeroUser($param['zeroUserId']);
  144. return $res;
  145. }
  146. /**
  147. * @return array
  148. * @throws \think\db\exception\DataNotFoundException
  149. * @throws \think\db\exception\DbException
  150. * @throws \think\db\exception\ModelNotFoundException
  151. * 获取所有下级用户
  152. */
  153. private function getAllUser($zeroUid)
  154. {
  155. $sql = "select getUserLevelId($zeroUid) as teamUids";
  156. $teamUids = Db::query($sql)[0]['teamUids'];
  157. // $resArr[$zeroUid] = $teamUids;
  158. return $teamUids;
  159. }
  160. /**
  161. * @return array
  162. * @throws DataNotFoundException
  163. * @throws DbException
  164. * @throws ModelNotFoundException
  165. * 获取全部0号线用户
  166. */
  167. private function getAllZeroUserIds()
  168. {
  169. $zeroUserDao = new ZeroUserLineDao();
  170. $zeroUserIds = $zeroUserDao->selectWhere([
  171. 'is_remove' => ZeroUserEnum::IS_REMOVE_MAP['YES']['code'],
  172. 'status' => ZeroUserEnum::STATUS_MAP['NORMAL']['code']
  173. ])->column('team_uid');
  174. if (empty($zeroUserIds)) {
  175. return [];
  176. }
  177. // // 循环获取0号线用户团队
  178. // $resArr = [];
  179. // foreach ($zeroUserIds as $zeroUserId) {
  180. // $zeroUid = $zeroUserId['team_uid'];
  181. // $sql = "select getUserLevelId($zeroUid) as teamUids";
  182. // $teamUids = Db::query($sql)[0]['teamUids'];
  183. // $resArr[$zeroUid] = $teamUids;
  184. // }
  185. return $zeroUserIds;
  186. }
  187. /**
  188. * @param $userIds
  189. * @return int
  190. * 获取分红总额
  191. */
  192. private function getAmount($userIds): int
  193. {
  194. return 10000;
  195. }
  196. /**
  197. * @param $uids
  198. * @param $userGroup
  199. * @return array
  200. * @throws \think\db\exception\DataNotFoundException
  201. * @throws \think\db\exception\DbException
  202. * @throws \think\db\exception\ModelNotFoundException
  203. * 获取符合合伙人等级的用户
  204. */
  205. private function getUserByGroup($uid, $userGroup): array
  206. {
  207. $userDao = new UserDao();
  208. return $userDao->getUsersByGroup($uid, $userGroup);
  209. }
  210. /**
  211. * @param $data
  212. * @return array
  213. * @throws DataNotFoundException
  214. * @throws DbException
  215. * @throws ModelNotFoundException
  216. * 获取直推用户业绩
  217. */
  218. private function getDirect($data, $amount): array
  219. {
  220. $money = $amount / 2;
  221. $res = [];
  222. foreach ($data as $key => $value) {
  223. if (empty($value)) {
  224. unset($data[$key]);
  225. continue;
  226. }
  227. // 获取直推
  228. $directUids = $this->userDao->selectWhere(['level_id' => $value])->column('uid');
  229. // 获取直推用户pv
  230. $pvArr = $this->getPv($directUids);
  231. $all = 0;
  232. $all += array_sum($pvArr);
  233. $max = max($pvArr);
  234. $min = $all - $max;
  235. $res[$value]['all'] = $all;
  236. $res[$value]['min'] = $min;
  237. $res[$value]['max'] = $max;
  238. }
  239. $res = $this->countPrice($res, $money);
  240. return $res;
  241. }
  242. /**
  243. * @param $directUids
  244. * @param $pvConfig
  245. * @return array
  246. * 计算pv
  247. */
  248. private function getPv($directUids)
  249. {
  250. $res = [];
  251. foreach ($directUids as $uid) {
  252. // 获取直推用户的团队uid
  253. $teamUids = $this->getTeamUids($uid);
  254. // 去除自己
  255. $teamUids = array_slice($teamUids, 1);
  256. // 获取团队的pv
  257. $pvArr = $this->userDao->selectWhereIn('uid', $teamUids)->column('pv', 'uid');
  258. if (($pvArr)) {
  259. $all = array_sum($pvArr);
  260. $res[$uid] = $all;
  261. }
  262. }
  263. return $res;
  264. }
  265. /**
  266. * @param $uid
  267. * @return mixed
  268. * 获取团队所有人uids [1,2,3]
  269. */
  270. private function getTeamUids($uid): array
  271. {
  272. $sql = "select getUserLevelId($uid) as uids";
  273. return explode(',', Db::query($sql)[0]['uids']);
  274. }
  275. /**
  276. * @param $pvArr
  277. * @param $money
  278. * @return mixed
  279. * 计算分佣
  280. */
  281. private function countPrice($pvArr, $money)
  282. {
  283. $minAll = array_sum(array_column($pvArr, 'min'));
  284. $maxAll = array_sum(array_column($pvArr, 'all'));
  285. foreach ($pvArr as $k => $v) {
  286. $pvArr[$k]['minCount'] = floor($money * ($v['min'] / $minAll) * 100) / 100;
  287. $pvArr[$k]['maxCount'] = floor($money * ($v['all'] / $maxAll) * 100) / 100;
  288. }
  289. return $pvArr;
  290. }
  291. /**
  292. * @param $param
  293. * @param $amount
  294. * @param $detail
  295. * @return string|true
  296. * 记录日志
  297. */
  298. private function recordLog($param, $amount, $detail)
  299. {
  300. $logDao = new ZeroUserProfitDao();
  301. $detailDao = new ZeroUserProfitsDetail();
  302. // 记录分红明细日志,修改主表数据
  303. $updateData = [
  304. 'amount' => $amount,
  305. 'status' => 1
  306. ];
  307. foreach ($detail as $key => $value) {
  308. $insertData = [
  309. 'zero_user_profit_id' => $param['logId'],
  310. 'zero_user_id' => $param['zeroUserId'],
  311. 'user_id' => $key,
  312. 'amount' => $amount,
  313. 'all' => $value['all'],
  314. 'min' => $value['min'],
  315. 'max' => $value['max'],
  316. 'min_count' => $value['minCount'],
  317. 'max_count' => $value['maxCount'],
  318. ];
  319. try {
  320. Db::startTrans();
  321. $logDao->update($param['logId'], $updateData);
  322. $detailDao->create($insertData);
  323. Db::commit();
  324. } catch (\Exception $e) {
  325. Db::rollback();
  326. return $e->getMessage();
  327. }
  328. }
  329. return true;
  330. }
  331. }