WeightService.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. namespace addons\Happiness\common\service;
  3. use addons\Happiness\common\enums\HappinessEnum;
  4. use addons\Happiness\common\enums\HappinessRewardEnum;
  5. use addons\Happiness\common\models\HappinessBoss;
  6. use addons\Happiness\common\models\HappinessWeightPoolJob;
  7. use addons\Happiness\common\models\HappinessWeightPoolLog;
  8. use addons\Happiness\common\models\HappinessWeightPoolOrderLog;
  9. use common\enums\StatusEnum;
  10. use services\common\UserWalletService;
  11. /**
  12. * 加权分红服务
  13. */
  14. class WeightService
  15. {
  16. public function record($order, $order_status)
  17. {
  18. try {
  19. $mall_id = $order['mall_id'];
  20. $config = \Yii::$app->services->setting->addons->get($mall_id, HappinessEnum::ADDONS_NAME, 'basic');
  21. if ($order_status == $config['settlement_method']) {
  22. $this->recordOrderLog($order, $config,$order_status); //分红池订单
  23. }
  24. } catch (\Exception $e) {
  25. \Yii::error(__METHOD__ . ', err:' . $e->getMessage());
  26. }
  27. }
  28. //发放奖励
  29. public function send($mall_id, $config, $start_at, $end_at, $job_id)
  30. {
  31. try {
  32. $last=HappinessWeightPoolOrderLog::find()->where(['mall_id'=>$mall_id,'status'=>StatusEnum::ENABLED,'settlement_status' => StatusEnum::DISABLED])->orderBy('id desc')->one();
  33. if(!$last)
  34. {
  35. return true;
  36. }
  37. //分红的金额
  38. $pool_prize_amount = HappinessWeightPoolOrderLog::find()->where([
  39. 'and',
  40. ['mall_id' => $mall_id],
  41. ['status' => StatusEnum::ENABLED],
  42. ['settlement_status' => StatusEnum::DISABLED],
  43. ['<=', 'id', $last->id]
  44. ])->sum('amount') ?? 0;
  45. if ($pool_prize_amount <= 0) return true;
  46. $level_list=!empty($config['boss_list'])? json_decode($config['boss_list'],true):[];//身份收益设置
  47. $pool_level=[];
  48. if(!empty($level_list))
  49. {
  50. foreach ($level_list as $level => $level_info)
  51. {
  52. if($level_info['weight_scale']>0 && $level_info['weight_num']>0)
  53. {
  54. $pool_level[]=[
  55. 'weight_scale'=>$level_info['weight_scale'],
  56. 'weight_num'=>$level_info['weight_num'],
  57. 'level'=>$level_info['level']
  58. ];
  59. }
  60. }
  61. }
  62. if (empty($pool_level)) return true;
  63. //获取分红人数
  64. foreach ($pool_level as &$level_info)
  65. {
  66. $level_info['member']=HappinessBoss::find()->where(['level'=>$level_info['level'],
  67. 'mall_id'=>$mall_id])->orderBy('id asc')->asArray()->limit($level_info['weight_num'])->all();
  68. $level_info['count']=count($level_info['member']);
  69. $level_info['pool']=bcmul(bcdiv($level_info['weight_scale'],100,4), $pool_prize_amount, 2);
  70. $level_info['amount']=bcdiv($level_info['pool'],
  71. $level_info['weight_num'], 2);
  72. }
  73. $rows = [];
  74. $period_num = 0;
  75. $period_amount = 0;
  76. foreach ($pool_level as $pool_level_info) {
  77. $amount = $pool_level_info['amount'];
  78. if($amount<=0 || $pool_level_info['count']<=0)
  79. {
  80. continue;
  81. }
  82. foreach ($pool_level_info['member'] as $member_info)
  83. {
  84. $rows[] = [
  85. 'mall_id' => $mall_id,
  86. 'user_id' => $member_info['user_id'],
  87. 'num' => $pool_level_info['count'], //分红人数
  88. 'total_amount' => $pool_level_info['pool'], //分红池总金额
  89. 'amount' => $amount, //可获得分红
  90. 'start_at' => $start_at,
  91. 'end_at' => $end_at,
  92. 'remark'=>'合伙人加权分红',
  93. 'created_at' => time(),
  94. 'updated_at' => time(),
  95. 'billing_cycle' => $config['compute_period'],
  96. 'job_id' => $job_id,
  97. 'scale' => $pool_level_info['weight_scale'],
  98. ];
  99. $period_num += 1; //实际分红人数
  100. $period_amount += $amount; //分红总金额累加
  101. }
  102. }
  103. if (empty($rows)) throw new \Exception('奖金池佣金记录为空');
  104. $job = HappinessWeightPoolJob::findOne($job_id);
  105. $t = \Yii::$app->db->beginTransaction();
  106. try {
  107. $insert_wallet = [];
  108. $columns = ['mall_id', 'user_id', 'num', 'total_amount', 'amount', 'start_at', 'end_at','remark','created_at', 'updated_at', 'billing_cycle', 'job_id', 'scale'];
  109. $res = \Yii::$app->db->createCommand()->batchInsert(HappinessWeightPoolLog::tableName(), $columns, $rows)->execute();
  110. if (!$res) throw new \Exception('批量生成奖金池佣金记录失败');
  111. HappinessWeightPoolOrderLog::updateAll(
  112. ['settlement_status' => StatusEnum::ENABLED, 'updated_at' => time()],
  113. ['and', ['mall_id' => $mall_id, 'settlement_status' => StatusEnum::DISABLED], ['<=', 'id', $last->id]]
  114. );
  115. $k = 1;
  116. $page_log = 1000;
  117. while ($log_list = HappinessWeightPoolLog::find()->where(['mall_id' => $mall_id, 'start_at' =>
  118. $start_at, 'end_at' => $end_at])
  119. ->offset(($k - 1) * $page_log)->limit($page_log)->asArray()->all()
  120. ) {
  121. foreach ($log_list as $log) {
  122. $insert_wallet[] = [
  123. 'mall_id' => $log['mall_id'],
  124. 'user_id' => $log['user_id'],
  125. 'is_frozen' => false,
  126. 'wallet_type' => 'commission',
  127. 'money' => $log['amount'],
  128. 'desc' => '加权分红',
  129. 'source_table' => HappinessWeightPoolLog::tableName(),
  130. 'source_table_id' => $log['id'],
  131. 'from_type' => HappinessEnum::ADDONS_NAME,
  132. 'capital_type' => HappinessRewardEnum::COMMISSION_TYPE_POOL
  133. ];
  134. }
  135. $k++;
  136. }
  137. $job->num = $period_num; //分红人数
  138. $job->total_amount = $period_amount; //实际分红总金额
  139. $job->period_total_amount = $pool_prize_amount; //分红池金额
  140. $job->save();
  141. //加一条减少记录
  142. if (HappinessWeightPoolOrderLog::setData([
  143. 'mall_id' => $mall_id,
  144. 'user_id' => 0,
  145. 'date' => date('Ymdhis'),
  146. 'amount' => -$pool_prize_amount,
  147. 'order_id' =>0,
  148. 'order_no' => '',
  149. 'price' => 0,
  150. 'pay_price' => 0,
  151. 'before_amount' => $pool_prize_amount,
  152. 'after_amount' => 0,
  153. 'settlement_status' =>1,
  154. 'desc' => '奖金池释放'
  155. ]) === false) {
  156. throw new \Exception(HappinessWeightPoolOrderLog::getStaticError());
  157. }
  158. $t->commit();
  159. } catch (\Exception $ex) {
  160. $t->rollback();
  161. throw $ex;
  162. }
  163. if ($insert_wallet) {
  164. UserWalletService::batchHandleByQueue($insert_wallet);
  165. }
  166. return true;
  167. } catch (\Exception $e) {
  168. \Yii::error(__METHOD__ . ', err:' . $e->getMessage());
  169. return true;
  170. }
  171. }
  172. /**
  173. * @Description: 记录进入奖金池的订单
  174. * @param array $order
  175. * @param array $config
  176. * @return bool
  177. */
  178. private function recordOrderLog($order, $config,$order_status): bool
  179. {
  180. try {
  181. $user_id = $order['user_id'];
  182. $mall_id = $order['mall_id'];
  183. $is_open = $config['is_enable'];
  184. if (!$is_open || $order['pay_money']<=0) {
  185. return true;
  186. }
  187. //如果是订单支付且结算方式是支付完成
  188. if ($order_status == 0 && $config['settlement_method'] == 1) {
  189. return false;
  190. }
  191. //判断是否已经写入这个订单
  192. $hasOrder=HappinessWeightPoolOrderLog::find()->where(['order_no'=>$order['order_no'],'mall_id'=>$mall_id,
  193. 'user_id'=>$user_id])
  194. ->one();
  195. if($hasOrder)
  196. {
  197. return false;
  198. }
  199. $amount = $order['pay_money'] ;
  200. $before_amount = HappinessWeightPoolOrderLog::find()->where(['mall_id' => $mall_id, 'settlement_status' => 0])->sum('amount');
  201. $before_amount= $before_amount??0;
  202. if ($amount > 0) {
  203. if (HappinessWeightPoolOrderLog::setData([
  204. 'mall_id' => $mall_id,
  205. 'user_id' => $user_id,
  206. 'date' => date('Ymdhis'),
  207. 'amount' => $amount,
  208. 'order_id' => $order['id'],
  209. 'order_no' => $order['order_no'],
  210. 'price' => $order['goods_price'],
  211. 'pay_price' => $order['goods_price'],
  212. 'before_amount' => $before_amount,
  213. 'after_amount' => bcadd($before_amount, $amount, 2),
  214. 'desc' => '来自订单' . $order['order_no'] . '的分红金额'
  215. ]) === false) {
  216. throw new \Exception(HappinessWeightPoolOrderLog::getStaticError());
  217. }
  218. }
  219. return true;
  220. } catch (\Exception $e) {
  221. \Yii::error(__METHOD__ . ',err:' . $e->getMessage());
  222. return false;
  223. }
  224. }
  225. }