PoolSeedLogic.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. namespace addons\DoubleCopy\common\logic;
  3. use addons\DoubleCopy\common\enums\DoubleCopyEnum;
  4. use addons\DoubleCopy\common\models\DoubleCopyPoolLevel;
  5. use addons\DoubleCopy\common\models\DoubleCopyPoolLog;
  6. use addons\DoubleCopy\common\models\DoubleCopyPoolSend;
  7. use addons\DoubleCopy\common\models\DoubleCopyPoolUser;
  8. use common\enums\StatusEnum;
  9. use common\enums\UserWalletEnum;
  10. use common\helpers\FormatHelper;
  11. use common\models\mall\Mall;
  12. use common\traits\ErrorTrait;
  13. use services\common\UserWalletService;
  14. use Yii;
  15. use yii\db\Exception;
  16. use yii\db\Expression;
  17. use yii\helpers\Json;
  18. /**
  19. * 分红池逻辑处理
  20. * @Author: lun
  21. * @DateTime: 2022/9/8 0008 16:10
  22. * @Copyright: copyright (c) 2021 广东七件事集团
  23. * @package addons\DoubleCopy\common\logic
  24. */
  25. class PoolSeedLogic
  26. {
  27. use ErrorTrait;
  28. /**
  29. * 执行
  30. * @Author: lun
  31. * @DateTime: 2022/9/16 0016 14:54
  32. * @Copyright: copyright (c) 2021 广东七件事集团
  33. * @return bool
  34. */
  35. public function exec()
  36. {
  37. try {
  38. // 获取有效的商城
  39. $mall_list = Mall::getEnableMallList(true);
  40. if(!empty($mall_list)){
  41. foreach ($mall_list as $mall){
  42. $mall_id = $mall['id'];
  43. // 获取基础配置
  44. $config = Yii::$app->services->setting->addons->get($mall_id, DoubleCopyEnum::ADDONS_NAME, 'basic');
  45. if (!empty($config['is_open_pool']) && $config['is_open_pool'] == StatusEnum::ENABLED) {
  46. $continue = false;
  47. // 获取结算周期,0=天,1=周,2=月
  48. $cycle_type = $config['cycle_type'];
  49. switch ($cycle_type) {
  50. case 1:
  51. if (date('w') != 1) $continue = true;// 非周一直接退出
  52. break;
  53. case 2:
  54. if (date('d') != 1) $continue = true;// 非当月1号直接退出
  55. break;
  56. }
  57. if ($continue) continue;
  58. $res = $this->send($mall_id, $cycle_type);
  59. if($res === false) throw new Exception($this->getError());
  60. //return true;
  61. }
  62. }
  63. }
  64. return true;
  65. } catch (\Exception $e) {
  66. $this->setError($e->getMessage());
  67. return false;
  68. }
  69. }
  70. /**
  71. * 分红发放处理
  72. * @Author: lun
  73. * @DateTime: 2022/9/19 0019 17:26
  74. * @Copyright: copyright (c) 2021 广东七件事集团
  75. * @param $mall_id
  76. * @param $cycle_type
  77. * @return bool
  78. */
  79. public function send($mall_id, $cycle_type, $is_test = false)
  80. {
  81. $trans = Yii::$app->db->beginTransaction();
  82. try {
  83. $time = time();
  84. $date = date('Ymd', $time);
  85. $config = Yii::$app->services->setting->addons->get($mall_id, DoubleCopyEnum::ADDONS_NAME, 'basic');
  86. $reward_currency = $config['reward_currency'] ?? 'commission';
  87. // 获取等级
  88. if($reward_currency == 'commission'){
  89. $level_list = DoubleCopyPoolLevel::find()->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->andWhere(['>', 'current_money' , 0])->asArray()->all();
  90. }else{
  91. $level_list = DoubleCopyPoolLevel::find()->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->andWhere(['>', 'current_score' , 0])->asArray()->all();
  92. }
  93. foreach ($level_list as $item) {
  94. // 检查今天是否已发放过
  95. $is_send = DoubleCopyPoolSend::find()->where(['mall_id' => $mall_id, 'level' => $item['level'], 'date' => $date, 'status' => StatusEnum::ENABLED])->asArray()->one();
  96. if ($is_test == false && $is_send) continue;
  97. // 统计当前等级的总人数
  98. $user_arr = DoubleCopyPoolUser::find()->select('id,user_id,level')->where(['mall_id' => $mall_id, 'level' => $item['level'], 'status' => StatusEnum::ENABLED])->asArray()->all();
  99. $t_user_arr = [];
  100. if (!empty($user_arr)) {
  101. foreach ($user_arr as $t_item) {
  102. $t_user_arr[$t_item['user_id']] = $t_item;
  103. }
  104. }
  105. foreach ($level_list as $tl_item) {
  106. if (!empty($tl_item['is_enable_extra_pool']) && !empty($tl_item['extra_pool_level'])) {
  107. $extra_pool_level = Json::decode($tl_item['extra_pool_level']);
  108. if (!empty($extra_pool_level) && in_array($item['level'], $extra_pool_level)) {
  109. $tt_user_arr = DoubleCopyPoolUser::find()->select('id,user_id,level')
  110. ->where(['mall_id' => $mall_id, 'level' => $tl_item['level'], 'status' => StatusEnum::ENABLED])->asArray()->all();
  111. if (!empty($tt_user_arr)) {
  112. foreach ($tt_user_arr as $tt_item) { // 执行去重
  113. if (empty($t_user_arr[$tt_item['user_id']])) $t_user_arr[$tt_item['user_id']] = $tt_item;
  114. }
  115. }
  116. }
  117. }
  118. }
  119. $user_arr = $t_user_arr;
  120. $bonus_num = count($user_arr);
  121. if ($bonus_num <= 0) continue;
  122. $current_money = $reward_currency == 'commission' ? $item['current_money'] : $item['current_score'];
  123. // 计算该等级每人可得分红金额,金额不得小于一分钱
  124. $bonus = sprintf("%.2f",substr(sprintf("%.3f", ($current_money / $bonus_num)), 0, -1));// 不四舍五入保留两位小数
  125. if ($bonus < 0.01) continue;
  126. $send_total_money = $bonus * $bonus_num;// 已分红金额
  127. // 修改该等级分红池剩余金额
  128. if($reward_currency == 'commission'){
  129. $res = DoubleCopyPoolLevel::updateAll([
  130. 'current_money' => new Expression('`current_money`-'.$send_total_money),
  131. 'updated_at' => $time
  132. ], ['id' => $item['id']]);
  133. }else{
  134. $res = DoubleCopyPoolLevel::updateAll([
  135. 'current_score' => new Expression('`current_score`-'.$send_total_money),
  136. 'updated_at' => $time
  137. ], ['id' => $item['id']]);
  138. }
  139. if (!$res) throw new Exception('修改分红池当前金额数据失败');
  140. // 生成该等级发送记录
  141. $send = [
  142. 'mall_id' => $mall_id,
  143. 'level' => $item['level'],
  144. 'total_bonus_money' => $reward_currency == 'commission' ? $item['current_money'] : $item['current_score'],
  145. 'bonus_num' => $bonus_num,
  146. 'bonus_money' => $bonus,
  147. 'cycle_type' => $cycle_type,
  148. 'date' => $date,
  149. 'reward_currency' => $reward_currency
  150. ];
  151. $resp = DoubleCopyPoolSend::create($send);
  152. if ($resp === false) throw new \Exception(DoubleCopyPoolSend::getStaticError());
  153. // 生成用户明细
  154. foreach ($user_arr as $user) {
  155. // 修改用户分红池收入
  156. if($reward_currency == 'commission'){
  157. $res = DoubleCopyPoolUser::updateAll([
  158. 'pool_income' => new Expression('`pool_income`+'.$bonus),
  159. 'updated_at' => $time
  160. ], ['id' => $user['id']]);
  161. }else{
  162. $res = DoubleCopyPoolUser::updateAll([
  163. 'pool_income_score' => new Expression('`pool_income_score`+'.$bonus),
  164. 'updated_at' => $time
  165. ], ['id' => $user['id']]);
  166. }
  167. if (!$res) throw new Exception('修改用户分红池收入数据失败');
  168. $insert_wallet[] = [
  169. 'mall_id' => $mall_id,
  170. 'user_id' => $user['user_id'],
  171. 'is_frozen' => false,
  172. 'wallet_type' => $reward_currency,
  173. 'money' => $bonus,
  174. 'desc' => '分红池发放',
  175. 'source_table' => 'addons_double_copy_pool_send',
  176. 'source_table_id' => $resp['id'],
  177. 'from_type' => DoubleCopyEnum::ADDONS_NAME,
  178. 'capital_type' => UserWalletEnum::BOUNS,
  179. ];
  180. $rows[] = [
  181. 'send_id' => $resp['id'],
  182. 'mall_id' => $mall_id,
  183. 'user_id' => $user['user_id'],
  184. 'level' => $item['level'],
  185. 'total_bonus_money' => $reward_currency == 'commission' ? $item['current_money'] : $item['current_score'],
  186. 'bonus_num' => $bonus_num,
  187. 'bonus_money' => $bonus,
  188. 'created_at' => $time,
  189. 'updated_at' => $time,
  190. 'reward_currency' => $reward_currency
  191. ];
  192. }
  193. }
  194. // 插入个人分红记录
  195. if (!empty($rows)) {
  196. $field = ['send_id','mall_id','user_id','level','total_bonus_money','bonus_num','bonus_money','created_at','updated_at','reward_currency'];
  197. $res = Yii::$app->db->createCommand()->batchInsert(DoubleCopyPoolLog::tableName(), $field, $rows)->execute();
  198. if ($res == false) throw new Exception("批量插入奖励出错");
  199. }
  200. $trans->commit();
  201. if (!empty($insert_wallet)) {
  202. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  203. if (empty($res)) throw new \Exception('插入钱包队列:' . UserWalletService::getStaticError());
  204. }
  205. return true;
  206. } catch (\Exception $e) {
  207. $trans->rollBack();
  208. $exception = FormatHelper::exception($e, "{$mall_id} 二二复制分红池发放");
  209. Yii::error($exception);
  210. return false;
  211. }
  212. }
  213. }