PoolLogic.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace addons\DoubleCopy\common\logic;
  3. use addons\DoubleCopy\common\enums\DoubleCopyEnum;
  4. use addons\DoubleCopy\common\models\DoubleCopyAchievement;
  5. use addons\DoubleCopy\common\models\DoubleCopyLevel;
  6. use addons\DoubleCopy\common\models\DoubleCopyPoolLevel;
  7. use addons\DoubleCopy\common\models\DoubleCopyPoolSource;
  8. use addons\DoubleCopy\common\models\DoubleCopyPoolUser;
  9. use addons\DoubleCopy\common\models\DoubleCopyUser;
  10. use common\enums\OrderStatusEnum;
  11. use common\enums\StatusEnum;
  12. use common\helpers\ArrayHelper;
  13. use common\helpers\FormatHelper;
  14. use common\models\order\Order;
  15. use common\models\order\OrderDetail;
  16. use common\models\user\UserPartitionRelationship;
  17. use common\traits\ErrorTrait;
  18. use Yii;
  19. use yii\db\Exception;
  20. use yii\helpers\Json;
  21. /**
  22. * 分红池逻辑处理
  23. * @Author: lun
  24. * @DateTime: 2022/9/8 0008 16:10
  25. * @Copyright: copyright (c) 2021 广东七件事集团
  26. * @package addons\DoubleCopy\common\logic
  27. */
  28. class PoolLogic
  29. {
  30. use ErrorTrait;
  31. public $mall_id;
  32. public $user_id;
  33. public $order_id;
  34. public $config;
  35. public $order_detail;
  36. public $order_status;
  37. public $task_counter_arr;
  38. public function __construct($order, $order_status, $task_counter_arr = [])
  39. {
  40. $this->mall_id = $order['mall_id'];
  41. $this->user_id = $order['user_id'];
  42. $this->order_id = $order['id'];
  43. $this->order_detail = $order['detail'];
  44. $this->order_status = $order_status;
  45. $this->task_counter_arr = $task_counter_arr;
  46. // 获取配置
  47. $this->config = Yii::$app->services->setting->addons->get($order['mall_id'], DoubleCopyEnum::ADDONS_NAME, 'basic');
  48. }
  49. /**
  50. * 执行
  51. * @Author: lun
  52. * @DateTime: 2022/9/16 0016 14:54
  53. * @Copyright: copyright (c) 2021 广东七件事集团
  54. * @return bool
  55. */
  56. public function exec()
  57. {
  58. try {
  59. $this->placePool();
  60. $this->upgrade();
  61. return true;
  62. } catch (\Exception $e) {
  63. $this->setError($e->getMessage());
  64. return false;
  65. }
  66. }
  67. /**
  68. * 计入分红池金额
  69. * @Author: lun
  70. * @DateTime: 2022/9/16 0016 14:45
  71. * @Copyright: copyright (c) 2021 广东七件事集团
  72. * @return bool
  73. * @throws Exception
  74. */
  75. public function placePool()
  76. {
  77. $trans = Yii::$app->db->beginTransaction();
  78. try {
  79. // 检查是否可以插入分红池
  80. if (empty($this->config['deposit_type']) && $this->order_status == OrderStatusEnum::PAY) {
  81. $trans->commit();
  82. return true;
  83. }
  84. if (!empty($this->config['deposit_type']) && $this->config['deposit_type'] == 1 && $this->order_status == OrderStatusEnum::ACCOMPLISH) {
  85. $trans->commit();
  86. return true;
  87. }
  88. // 获取等级中的商品设置
  89. $pool_level = DoubleCopyPoolLevel::find()->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])->asArray()->all();
  90. if (empty($pool_level)) {
  91. $trans->commit();
  92. return true;
  93. }
  94. $time = time();
  95. $commission_arr = [];
  96. $reward_currency = $this->config['reward_currency'] ?? 'commission';
  97. foreach ($pool_level as $pool) {
  98. $goods_setting = json_decode($pool['goods_setting'], true);
  99. $goods_ids = array_column($goods_setting, 'goods_id');// 获取该等级中的商品id
  100. $goods = array_column($goods_setting, null, 'goods_id');// 将商品id作为key
  101. foreach ($this->order_detail as $detail) {
  102. // 检查是否已插入过,防止多次插入增加分红池额度
  103. $check = DoubleCopyPoolSource::find()->where(['mall_id' => $this->mall_id, 'level' => $pool['level'], 'order_detail_id' => $detail['id'], 'status' => StatusEnum::ENABLED])->scalar();
  104. if ($check) continue;
  105. // 获取插入分红池金额
  106. if (!empty($goods[$detail['goods_id']]['is_percent'])) {
  107. // 按实付金额的百分比插入
  108. $percent = $goods[$detail['goods_id']]['money'] ?? 0;// 获取比例
  109. $total_place_money = $percent == 0 ? 0 : bcdiv($detail['goods_price'] * $percent , 100, 2);
  110. } else {
  111. // 按照具体金额插入
  112. $place_money = $goods[$detail['goods_id']]['money'] ?? 0;// 插入分红池金额
  113. $total_place_money = empty($place_money) ? 0 : $place_money * $detail['num'];// 需要加上商品数量
  114. }
  115. if (empty($total_place_money)) continue;
  116. // 订单商品在设置中
  117. if (in_array($detail['goods_id'], $goods_ids)) {
  118. //判断当前奖励类型
  119. if($reward_currency == 'commission'){
  120. // 增加分红池金额
  121. DoubleCopyPoolLevel::savePoolMoney($this->mall_id, $pool['level'], [
  122. 'current_money' => $total_place_money,
  123. 'total_money' => $total_place_money,
  124. ]);
  125. }else{
  126. DoubleCopyPoolLevel::savePoolMoney($this->mall_id, $pool['level'], [
  127. 'current_score' => $total_place_money,
  128. 'total_score' => $total_place_money,
  129. ]);
  130. }
  131. // 生成记录
  132. $rows[] = [
  133. 'mall_id' => $this->mall_id,
  134. 'level' => $pool['level'],
  135. 'order_detail_id' => $detail['id'],
  136. 'money' => $total_place_money,
  137. 'created_at' => $time,
  138. 'updated_at' => $time,
  139. 'reward_currency' => $reward_currency
  140. ];
  141. // 放进云库存计数器
  142. if ($this->order_status == OrderStatusEnum::PAY && $reward_currency == 'commission') {
  143. if(isset($this->task_counter_arr[$detail['id']][DoubleCopyEnum::ADDONS_NAME]['commission'])){
  144. $this->task_counter_arr[$detail['id']][DoubleCopyEnum::ADDONS_NAME]['commission'] += $total_place_money;
  145. }else{
  146. $this->task_counter_arr[$detail['id']][DoubleCopyEnum::ADDONS_NAME]['commission'] = $total_place_money;
  147. }
  148. }
  149. }
  150. }
  151. }
  152. if (!empty($rows)) {
  153. $field = ['mall_id','level','order_detail_id','money', 'created_at','updated_at','reward_currency'];
  154. $res = Yii::$app->db->createCommand()->batchInsert(DoubleCopyPoolSource::tableName(), $field, $rows)->execute();
  155. if ($res == false) throw new Exception("批量插入计入分红池商品记录失败");
  156. }
  157. // 插入云库存计数器
  158. if (!empty($commission_arr)) {
  159. Yii::$app->services->taskCounter->set($this->order_id)->callBack($this->mall_id, $this->order_id, $commission_arr);
  160. }
  161. $trans->commit();
  162. return true;
  163. } catch (\Exception $e) {
  164. $trans->rollBack();
  165. $exception = FormatHelper::exception($e, "插入分红池");
  166. echo $exception;
  167. $this->setError($exception);
  168. return false;
  169. }
  170. }
  171. /**
  172. * 升级成为分红池等级用户
  173. * @Author: lun
  174. * @DateTime: 2022/9/16 0016 10:51
  175. * @Copyright: copyright (c) 2021 广东七件事集团
  176. * @return bool
  177. */
  178. public function upgrade()
  179. {
  180. $trans = Yii::$app->db->beginTransaction();
  181. try {
  182. // 获取用户所有上级
  183. $parent_ids = UserPartitionRelationship::getParentIdArr($this->user_id);
  184. if (empty($parent_ids)) {
  185. $trans->commit();
  186. return true;
  187. }
  188. // 查询二二复制用户的所有上级
  189. $copy_parent_ids = DoubleCopyUser::find()->select('user_id')->where(['user_id' => $parent_ids, 'status' => StatusEnum::ENABLED])->column();
  190. if (empty($copy_parent_ids)) {
  191. $trans->commit();
  192. return true;
  193. }
  194. // 获取分红池用户
  195. $pool_parent_users = DoubleCopyPoolUser::find()->select('user_id,level')->where(['user_id' => $parent_ids, 'status' => StatusEnum::ENABLED])->indexBy('user_id')->asArray()->all();
  196. // 用户升级处理
  197. $this->check($copy_parent_ids, $pool_parent_users);
  198. $trans->commit();
  199. return true;
  200. } catch (\Exception $e) {
  201. $trans->rollBack();
  202. $exception = FormatHelper::exception($e, "分红池用户升级");
  203. $this->setError($exception);
  204. return true;
  205. }
  206. }
  207. /**
  208. * 检查用户升级
  209. * @Author: lun
  210. * @DateTime: 2022/9/16 0016 11:28
  211. * @Copyright: copyright (c) 2021 广东七件事集团
  212. * @param $copy_parent_ids
  213. * @param $pool_parent_users
  214. * @throws \Exception
  215. */
  216. public function check($copy_parent_ids, $pool_parent_users)
  217. {
  218. // 获取等级
  219. $pool_level = DoubleCopyPoolLevel::find()->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED])->orderBy('level desc')->asArray()->all();
  220. foreach ($copy_parent_ids as $user_id) {
  221. // 统计用户12市场的业绩
  222. $team = DoubleCopyUser::find()->select('achievement')->where(['pid' => $user_id, 'status' => StatusEnum::ENABLED])->andWhere(['<=', 'pos', 2])->asArray()->all();
  223. if (empty($team)) continue;
  224. if (count($team) < 2) continue;// 小于两个市场不能升级
  225. $level = 0;
  226. foreach ($pool_level as $item) {
  227. $is_single_pass = true;
  228. $achievement = 0;// 总业绩
  229. $team_num = 0;
  230. foreach ($team as $info) {
  231. // 判断单个市场是否及格
  232. if ($info['achievement'] < $item['single_market']) {
  233. $is_single_pass = false;
  234. break;
  235. }else{
  236. $team_num++;
  237. }
  238. $achievement += $info['achievement'];
  239. }
  240. // 单个市场业绩符合并且团队业绩也符合才可升级
  241. // 所有助力会员需满足
  242. if ($is_single_pass == true && $achievement >= $item['achievement'] && $team_num >= 2) {
  243. $level = $item['level'];
  244. break;
  245. }
  246. }
  247. if ($level == 0) continue;// 无升级直接跳过
  248. // 判断当前等级用户是否符合升级条件
  249. if (!empty($pool_parent_users[$user_id])) {
  250. // 已存在的用户升级
  251. if (!empty($pool_parent_users[$user_id]['level']) && $level > $pool_parent_users[$user_id]['level']) {
  252. $res = DoubleCopyPoolUser::create(['user_id' => $user_id, 'level' => $level, 'upgrade_status' => DoubleCopyEnum::UPGRADE_STATUS_CONDITION, 'upgrade_level_at' => time()]);
  253. if ($res == false) throw new \Exception(DoubleCopyPoolUser::getStaticError());
  254. }
  255. } else {
  256. // 新用户升级
  257. if ($level) {
  258. $res = DoubleCopyPoolUser::create(['mall_id' => $this->mall_id, 'user_id' => $user_id, 'level' => $level, 'upgrade_status' => DoubleCopyEnum::UPGRADE_STATUS_CONDITION, 'upgrade_level_at' => time()]);
  259. if ($res == false) throw new \Exception(DoubleCopyPoolUser::getStaticError());
  260. }
  261. }
  262. }
  263. }
  264. }