IndependentAreaBase.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace addons\Area\common\logic\independent;
  3. use addons\Area\common\enums\AreaEnum;
  4. use addons\Area\common\models\AreaAgent;
  5. use addons\Area\common\models\AreaCommissionLog;
  6. use addons\Area\common\models\AreaCumulativeRewardLog;
  7. use addons\Area\common\models\AreaGoods;
  8. use common\enums\StatusEnum;
  9. use common\models\user\UserDigital;
  10. use common\models\user\UserPartitionRelationship;
  11. use services\common\UserWalletService;
  12. abstract class IndependentAreaBase
  13. {
  14. public $mall_id;
  15. public $user_id;
  16. public $basic_conf;
  17. public $name = '';//佣金:commission;积分:score
  18. public $order_detail = [];
  19. public $order = [];
  20. public function __construct($mall_id, $user_id, $basic_conf, array $order, array $order_detail, $name = 'commission')
  21. {
  22. $this->mall_id = $mall_id;
  23. $this->name = $name;
  24. $this->user_id = $user_id;
  25. $this->basic_conf = $basic_conf;
  26. $this->order = $order;
  27. $this->order_detail = $order_detail;
  28. }
  29. public function addFrozenCommission($level, &$last_level, $address_id)
  30. {
  31. //地区id = 0,不进行分红
  32. if($address_id <=0 ) return 0;
  33. //查询镇一级的区域代理
  34. $area_agent_list = AreaAgent::getAreaAgentByLevel($level, $address_id, $this->mall_id);
  35. $config = $this->getLevelConfig();
  36. if (!empty($area_agent_list)) {
  37. foreach ($area_agent_list as $key => $item) {
  38. if (!$this->valid($item)) unset($area_agent_list[$key]);
  39. }
  40. // 过滤后是否还有能拿的
  41. if (empty($area_agent_list)) return 0;
  42. $team_prize_list = $equal_prize_list = [];
  43. ['money' => $money, 'multiple' => $multiple, 'extension' => $extension] = $this->getRules();
  44. $area_agent_num = count($area_agent_list);
  45. $area_agent_prize = self::computing($config, $money, 'team', $area_agent_num, $level, $last_level, $multiple);
  46. $equal_area_agent_prize = self::computing($config, $money, 'equal', 0, $level, 0, $multiple, $area_agent_prize);
  47. foreach ($area_agent_list as $area_agent) {
  48. //默认分红
  49. if (!empty($area_agent_prize)) {
  50. $team_prize_list[$area_agent->user_id] = ['price' => $area_agent_prize, 'user_id' => $area_agent['user_id'], 'level' => $level];
  51. $last_level = $level;
  52. }
  53. //平级奖
  54. if (!empty($equal_area_agent_prize)) {
  55. $parent_id_arr = UserPartitionRelationship::getParentIdArr($area_agent->user_id);
  56. $parent_agent_list = AreaAgent::lists(['where' => [['user_id' => $parent_id_arr], ['level' => $level],['status'=>StatusEnum::ENABLED]],'index'=>'user_id']);
  57. $parent_id_arr = array_reverse($parent_id_arr);
  58. $parent_agent_list_new = [];
  59. foreach ($parent_id_arr as $user_id){
  60. if(isset($parent_agent_list[$user_id])){
  61. $parent_agent_list_new[]=$parent_agent_list[$user_id];
  62. }
  63. }
  64. if (!empty($parent_agent_list_new)) {
  65. $equal_prize_deep = 0;
  66. $equal_prize_max_deep = $this->basic_conf['equal_prize_deep'];
  67. $equal_prize_deep_temp = 0;
  68. if(!empty($this->basic_conf['equal_reward_is_equal'])){
  69. foreach ($parent_agent_list_new as $equal_area_agent) {
  70. if ($equal_prize_deep_temp >= $equal_prize_max_deep) break;
  71. $equal_prize_deep_temp++;
  72. }
  73. if($equal_prize_deep_temp>0){
  74. $equal_area_agent_prize = bcdiv($equal_area_agent_prize,$equal_prize_deep_temp,2);
  75. }
  76. }
  77. foreach ($parent_agent_list_new as $equal_area_agent) {
  78. if ($equal_prize_deep >= $equal_prize_max_deep) break;
  79. $equal_prize_list[] = ['price' => $equal_area_agent_prize, 'user_id' => $equal_area_agent['user_id'], 'level' => $level];
  80. $equal_prize_deep++;
  81. }
  82. }
  83. }
  84. }
  85. $money = 0;
  86. try {
  87. //投递到资产队列
  88. $insert_wallet = $this->getInsertWalletData($team_prize_list, $equal_prize_list);
  89. if (!empty($insert_wallet)) {
  90. if($this->name != 'digital') {
  91. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  92. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  93. }
  94. foreach ($insert_wallet as $k => $user) {
  95. if($user['wallet_type'] == 'digital'){
  96. $res = UserDigital::handleUserDigital($user['mall_id'],$user['user_id'],$user['money'],$user['is_frozen'],$user);
  97. if($res === false) continue;
  98. }
  99. $agent = AreaAgent::getAreaAgentOneByLevel($user['user_id'],$level, $address_id, $this->mall_id);
  100. if(empty($agent)) continue;
  101. $field = 'total_' . $this->name;
  102. $agent->$field += $user['money'];
  103. $money+=$user['money'];
  104. $res = $agent->save();
  105. if (empty($res)) throw new \Exception($agent->getErrorMessage());
  106. // 这里做处理
  107. AreaCommissionLog::setData($user, $this->order_detail, $user['___is_fixed___'], $user['___rate___'], $level);
  108. // 记录佣金累计
  109. AreaCumulativeRewardLog::setData([
  110. 'mall_id' => $this->mall_id,
  111. 'source_table' => $user['source_table'],
  112. 'source_table_id' => $user['source_table_id'],
  113. 'wallet_type' => $this->name,
  114. 'change_num' => $user['money'],
  115. 'agent_id' => $agent->id,
  116. 'user_id' => $agent->user_id,
  117. 'level' => $agent->level,
  118. 'agent_area' => $agent[AreaAgent::LEVEL_FIELD_MAP[$agent->level]] ?? 0,
  119. 'reward_type' => $user['capital_type'],
  120. ]);
  121. }
  122. }
  123. return $money;
  124. } catch (\Exception $e) {
  125. echo 'AreaBase:addFrozenCommission' . $e->getMessage();
  126. return 0;
  127. }
  128. }
  129. }
  130. /**
  131. * @desc:计算
  132. * @Author: hua
  133. * @Date: 2022/1/21
  134. * @Time: 17:13
  135. * @Copyright: copyright (c) 2021 广东七件事集团
  136. * @param $config
  137. * @param $money
  138. * @param $type
  139. * @param $agent_num
  140. * @param $level
  141. * @param $last_level
  142. * @param int $multiple
  143. * @param int $parent_commission
  144. * @return array
  145. */
  146. public function computing($config, $money, $type, $agent_num, $level, $last_level, $multiple = 1, $parent_commission = 0)
  147. {
  148. $is_percent_key = "is_percent_{$type}";
  149. $prize = self::getPrizeByLevel($config, $level, $type);
  150. if (empty($prize)) return [];
  151. if ($type == 'team' && !empty($this->basic_conf['is_level'])) {
  152. //走级差
  153. $last_price = $last_level === 0 ? 0 : self::getPrizeByLevel($config, $last_level, $type);
  154. $prize -= $last_price;
  155. }
  156. if ($type == 'equal' && $this->basic_conf['equal_compute_type'] == 2) $money = $parent_commission;
  157. $commission = empty($config[$is_percent_key]) == 0 ? $multiple * $prize : $money * $prize / 100;
  158. // 平分
  159. if ($type == 'team' && !empty($this->basic_conf['is_equal'])) {
  160. if ($agent_num == 0) return [];
  161. $commission /= $agent_num;
  162. }
  163. $commission = bcmul($commission, 1,2);
  164. return ['commission' => $commission,
  165. 'is_fixed' => !empty($config[$is_percent_key]) ? StatusEnum::ENABLED : StatusEnum::DISABLED,
  166. 'rate' => $prize];
  167. }
  168. /**
  169. * @desc:获取对应等级的奖励值
  170. * @Author: hua
  171. * @Date: 2022/1/21
  172. * @Time: 16:57
  173. * @Copyright: copyright (c) 2021 广东七件事集团
  174. * @param $config
  175. * @param $level
  176. * @param $type
  177. * @return int|mixed
  178. */
  179. public static function getPrizeByLevel($config, $level, $type)
  180. {
  181. switch ($level) {
  182. case AreaEnum::PROVINCE:
  183. $prize_key = "province_{$type}_prize";
  184. break;
  185. case AreaEnum::CITY:
  186. $prize_key = "city_{$type}_prize";
  187. break;
  188. case AreaEnum::DISTRICT:
  189. $prize_key = "district_{$type}_prize";
  190. break;
  191. case AreaEnum::TOWN:
  192. $prize_key = "town_{$type}_prize";
  193. break;
  194. case AreaEnum::COMMUNITY:
  195. $prize_key = "community_{$type}_prize";
  196. break;
  197. case AreaEnum::REGIONAL:
  198. $prize_key = "regional_{$type}_prize";
  199. break;
  200. }
  201. if (empty($config[$prize_key])) return 0;
  202. return $config[$prize_key];
  203. }
  204. /**
  205. * @param AreaAgent $agent
  206. * @return mixed|true|null
  207. */
  208. public function valid(AreaAgent $agent)
  209. {
  210. // 当前用户有无分佣权限
  211. if ($agent->is_enable_dividend == StatusEnum::DISABLED) return false;
  212. // 当前用户是否有当前商品的分佣权限
  213. if ($this->basic_conf['only_dividend_goods_type'] == StatusEnum::DISABLED &&
  214. !AreaGoods::existByAgentIdAndGoodsId($agent->mall_id, $agent->id, $this->order_detail['goods_id'])) return false;
  215. // 当前用户是否与当前买家在同一关系链中 - 上级/下级
  216. // 上级
  217. $parent_id_arr = UserPartitionRelationship::getParentIdArr($this->user_id);
  218. if (!empty($parent_id_arr) && in_array($agent->user_id, $parent_id_arr)) return false;
  219. // 下级
  220. $child_id_arr = UserPartitionRelationship::getChildIdArr($this->user_id);
  221. if (!empty($child_id_arr) && in_array($agent->user_id, $child_id_arr)) return false;
  222. return true;
  223. }
  224. abstract public function getLevelConfig();
  225. abstract public function getRules();
  226. abstract public function getInsertWalletData($team_prize_list, $equal_prize_list);
  227. }