RewardLogic.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <?php
  2. namespace addons\Recommen\common\logic;
  3. use addons\Coupon\common\enums\AddonsCouponEnum;
  4. use addons\Coupon\common\models\AddonsCouponUserRelate;
  5. use addons\Recommen\common\enums\RecommenEnum;
  6. use addons\Recommen\common\models\Recommen;
  7. use addons\Recommen\common\models\RecommenLog;
  8. use addons\Recommen\common\models\RecommenReward;
  9. use common\enums\AddonsEnum;
  10. use common\enums\OrderStatusEnum;
  11. use common\enums\StatusEnum;
  12. use common\enums\UserWalletEnum;
  13. use common\helpers\FormatHelper;
  14. use common\models\mall\MallAddons;
  15. use common\models\order\Order;
  16. use common\models\statistics\UserStatisticsTotal;
  17. use common\models\user\User;
  18. use services\common\UserWalletService;
  19. use Yii;
  20. use yii\helpers\Json;
  21. class RewardLogic
  22. {
  23. /**
  24. * @param array $params
  25. * @param int $type
  26. * @return bool
  27. */
  28. public static function execute(array $params, int $type)
  29. {
  30. Yii::$app->db->close();
  31. $trans = Yii::$app->db->beginTransaction();
  32. try {
  33. $user = User::find()->select('id,mall_id,parent_id')->where(['id' => $params['user_id']])->one();
  34. if (empty($user)) throw new \Exception('用户查询失败');
  35. $mall_id = $user['mall_id'];
  36. $user_id = $user['id'];
  37. $parent_id = $user['parent_id'];
  38. // 没有推荐人的情况下不做处理
  39. if (empty($parent_id)) {
  40. return true;
  41. }
  42. //查询现在正在进行的活动
  43. $time = time();
  44. $where[] = ['<', 'start_time', $time];
  45. $where[] = ['>', 'end_time', $time];
  46. $where[] = ['=', 'status', StatusEnum::ENABLED];
  47. $where[] = ['=', 'mall_id', $mall_id];
  48. $where[] = ['=', 'settle_type', $type];
  49. $order = 'id desc';
  50. $params = array('where' => $where, 'order'=>$order);
  51. $list = Recommen::lists($params);
  52. $parent_child_user_ids = User::find()
  53. ->where(['parent_id' => $parent_id])
  54. ->andWhere(['status' => StatusEnum::ENABLED])
  55. ->select('id')->column();
  56. $parent_child_pay_amounts = [];
  57. foreach ($parent_child_user_ids as $child_user_id) {
  58. $amount = Order::find()->where(['user_id' => $child_user_id])
  59. ->andWhere(['order_status' => OrderStatusEnum::ACCOMPLISH])
  60. ->sum('pay_money');
  61. $parent_child_pay_amounts[$child_user_id] = bcmul(empty($amount) ? 0 : $amount, 100);
  62. }
  63. if($list){
  64. foreach($list as $k=>$v){ //遍历活动
  65. $add['mall_id'] = $mall_id;
  66. $add['user_id'] = $user_id;
  67. $add['parent_id'] = $parent_id;
  68. $add['active_id'] = $v['id'];
  69. $addrecommen = RecommenLog::setData($add, $type, $v['settle_type'] == $type);
  70. // 如果存在了那肯定不能再领取了 || 如果类型不一致,那么也不能获得奖励 - 如果一个人连续下两单,那么就会被拒绝奖励
  71. if (!$addrecommen) continue;
  72. $is_be_status = true;
  73. if (is_array($addrecommen) && !empty($addrecommen[0]) && $addrecommen[0] instanceof RecommenLog) {
  74. $addrecommen = $addrecommen[0];
  75. $is_be_status = false;
  76. }
  77. //达到添加则赠送奖励
  78. $recommen_reward = Json::decode($v['recommen_reward']);
  79. // $recommen_reward = array_reverse($recommen_reward);
  80. //阶梯奖励
  81. $arrive_nums = array_column($recommen_reward,'arrive_num');
  82. $consumption_amounts = array_column($recommen_reward,'consumption_amount');
  83. // var_dump('$consumption_amounts ->', $arrive_nums, $consumption_amounts );
  84. if($arrive_nums){
  85. // 已经领取奖励次数
  86. $reward_list = RecommenReward::find()->where(['mall_id' => $mall_id])
  87. ->andWhere(['user_id' => $parent_id, 'be_reward' => 2])->andWhere(['active_id' => $v['id']])
  88. ->andWhere(['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]])->select('id, index, active_id')->indexBy('index')->asArray()->all();
  89. $reward_total = count($reward_list);
  90. //推荐者奖励
  91. $index = null;
  92. foreach($arrive_nums as $key => $value){
  93. //如果阶梯奖励已领取奖励,则跳过此条规则
  94. if (!empty($reward_list[$key]) && $v['type'] == 2 ) {
  95. echo "{$v['id']} 1 \n";
  96. continue;
  97. }
  98. // 判断数量是否已经达标? 推荐数量/单次推荐多少人可以领奖
  99. $can_reward_num = floor(count($parent_child_user_ids) / $value);
  100. // $v['type'] == 1 每推荐1人 每人消费满 N 元进行奖励 - 条件奖励
  101. // $v['type'] == 2 推荐N人 每人消费满 N 元进行奖励 - 找到最大的一个值 - 满足第一个 -> 满足第二个 -> 满足第三个 - 阶梯奖励
  102. //检查是否符合当前规则推荐人数
  103. if ($can_reward_num < 1) {
  104. echo "{$v['id']} 1 \n";
  105. continue;
  106. }
  107. if ($v['type'] == 1 && $can_reward_num <= $reward_total) {
  108. echo "{$v['id']} 1 \n";
  109. continue;
  110. }
  111. $consumption_amount = $consumption_amounts[$key] ?? 0; // 默认是0元,也就是说默认没有消费门槛
  112. // 判断消费是否满足
  113. if ($consumption_amount > 0 && $v['settle_type'] == RecommenEnum::RECOMMEND_TYPE_ORDER_FINISH) {
  114. $tmp_parent_child_pay_amounts = array_values(array_filter($parent_child_pay_amounts, function ($val) use ($consumption_amount) {
  115. return $val >= bcmul($consumption_amount, 100);
  116. }));
  117. // 如果支付人数达不到要求,那么就不做奖励
  118. $order_cnt = count($tmp_parent_child_pay_amounts);
  119. if (empty($order_cnt) || $order_cnt%$value != 0) {
  120. continue;
  121. }
  122. // 每推荐1人 每人消费满 N 元进行奖励 - 条件奖励
  123. if (floor($order_cnt / $value) <= $reward_total && $v['type'] == 1) {
  124. continue;
  125. }
  126. // 推荐N人 每人消费满 N 元进行奖励 - 找到最大的一个值 - 满足第一个 -> 满足第二个 -> 满足第三个 - 阶梯奖励
  127. if ($v['type'] == 2) {
  128. $index_cnt = RecommenReward::find()->where(['user_id' => $parent_id, 'be_reward' => 2])
  129. ->andWhere(['active_id' => $v['id']])->andWhere(['index' => $key])->count();
  130. if ($index_cnt > 0 && floor($order_cnt / $value) <= $index_cnt) {
  131. continue;
  132. }
  133. }
  134. }
  135. $index = $key;
  136. }
  137. if ($index !== null) self::reward($v, $mall_id, $add, $recommen_reward, $parent_id, $index, $v['type']);
  138. }
  139. //被推荐者奖励
  140. $be_recommen_reward = json_decode($v['be_recommen_reward'],true);
  141. if($v['be_status'] == 2 && $is_be_status){
  142. $reward_data = [];
  143. $reward_data['active_id'] = $v['id'];
  144. $reward_data['mall_id'] = $mall_id;
  145. $reward_data['user_id'] = $user_id;
  146. $reward_data['is_frozen'] = false;
  147. $reward_data['be_reward'] = 1;
  148. $balance = 0;
  149. $sorce = 0;
  150. $reward_list = RecommenReward::find()->where(['mall_id' => $mall_id])
  151. ->andWhere(['user_id' => $user_id, 'be_reward' => 1])->andWhere(['active_id' => $v['id']])
  152. ->andWhere(['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]])->select('id, index, active_id')->one();
  153. if (!empty($reward_list)) continue;
  154. //var_dump($v['id'],$be_recommen_reward);die;
  155. if($be_recommen_reward){//推荐者奖励
  156. foreach($be_recommen_reward as $kp => $vp){ //奖励的上一层
  157. foreach($vp['data'] as $k_reward => $v_reward){
  158. $reward_data['num'] = $v_reward['data'];
  159. switch ($v_reward['type']) {
  160. case RecommenEnum::REWARD_BALANCE:// 奖励余额
  161. $balance += $v_reward['data'];
  162. $res_reward = self::rewardBalance($reward_data);
  163. break;
  164. case RecommenEnum::REWARD_SCORE:// 奖励积分
  165. $sorce += $v_reward['data'];
  166. $res_reward = self::rewardScore($reward_data);
  167. break;
  168. case RecommenEnum::REWARD_COUPON:// 奖励优惠券
  169. $coupon_data['data'] = $v_reward['data'];
  170. //var_dump($v_reward['data'],$v['id'],999);
  171. $coupon_data['mall_id'] = $mall_id;
  172. $coupon_data['user_id'] = $user_id;
  173. $res_data = self::rewardCoupon($coupon_data);
  174. if($res_data){
  175. $reward_data['reward'][]= $res_data;
  176. }
  177. break;
  178. }
  179. }
  180. }
  181. if($balance>0) $reward_data['reward'][] = "奖励余额".$balance."元";
  182. if($sorce>0) $reward_data['reward'][] = "奖励积分".$sorce;
  183. //发放奖励
  184. $reward = RecommenReward::setData($reward_data);
  185. }
  186. }
  187. }
  188. }
  189. $trans->commit();
  190. } catch (\Exception $e) {
  191. $trans->rollBack();
  192. $exception = FormatHelper::exception($e, "用户注册异步事件");
  193. echo $exception;
  194. Yii::error($exception);
  195. return false;
  196. }
  197. return true;
  198. }
  199. protected static function reward($v, $mall_id, $add, $recommen_reward, $parent_id, $index, $type)
  200. {
  201. $reward_data = [];
  202. $reward_data['active_id'] = $v['id'];
  203. $reward_data['mall_id'] = $mall_id;
  204. $reward_data['user_id'] = $add['parent_id'];
  205. $reward_data['be_reward'] = 2;
  206. $reward_data['index'] = $index;
  207. if($recommen_reward){//推荐者奖励
  208. $reward_data['reward'] = [];
  209. $balance = 0;
  210. $sorce = 0;
  211. foreach($recommen_reward as $kp => $vp){ //奖励的上一层
  212. if ($type == 2 && $index != $kp) continue;
  213. foreach($vp['data'] as $k_reward => $v_reward){
  214. $reward_data['num'] = $v_reward['data'];
  215. switch ($v_reward['type']) {
  216. case RecommenEnum::REWARD_BALANCE:// 奖励余额
  217. $balance += $v_reward['data'];
  218. self::rewardBalance($reward_data);
  219. break;
  220. case RecommenEnum::REWARD_SCORE:// 奖励积分
  221. $sorce += $v_reward['data'];
  222. self::rewardScore($reward_data);
  223. break;
  224. case RecommenEnum::REWARD_COUPON:// 奖励优惠券
  225. $coupon_data['data'] = $v_reward['data'];
  226. //var_dump($v_reward['data'],$v['id'],88);
  227. $coupon_data['mall_id'] = $mall_id;
  228. $coupon_data['user_id'] = $parent_id;
  229. $res_data = self::rewardCoupon($coupon_data);
  230. if($res_data){
  231. $reward_data['reward'][]= $res_data;
  232. }
  233. break;
  234. }
  235. }
  236. }
  237. if($balance>0) $reward_data['reward'][] = "奖励余额".$balance."元";
  238. if($sorce>0) $reward_data['reward'][] = "奖励积分".$sorce;
  239. //发放奖励
  240. $reward = RecommenReward::setData($reward_data);
  241. }
  242. }
  243. /**
  244. * 奖励余额
  245. * @Author: ltm
  246. * @DateTime: 2022/5/17 19:03
  247. * @Copyright: copyright (c) 2021 广东七件事集团
  248. * @param $data
  249. * @throws \Exception
  250. */
  251. protected static function rewardBalance($data){
  252. //转到用户账号
  253. $insert_wallet [] = ['mall_id' => $data['mall_id'], 'user_id' => $data['user_id'],
  254. 'is_frozen' => false,
  255. 'wallet_type' => UserWalletService::WALLET_TYPE_BALANCE,
  256. 'money' => $data['num'],
  257. 'desc' => "推荐有礼奖励",
  258. 'source_table' => RecommenReward::tableName(),
  259. 'source_table_id' => $data['user_id'],
  260. 'from_type' => UserWalletEnum::REWARD,
  261. 'capital_type' => UserWalletEnum::RECOMMEND,
  262. ];
  263. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  264. }
  265. /**
  266. * 奖励积分
  267. * @Author: ltm
  268. * @DateTime: 2022/5/17 19:03
  269. * @Copyright: copyright (c) 2021 广东七件事集团
  270. * @param $data
  271. * @throws \Exception
  272. */
  273. protected static function rewardScore($data){
  274. //转到用户账号
  275. $insert_wallet [] = ['mall_id' => $data['mall_id'], 'user_id' => $data['user_id'],
  276. 'is_frozen' => false,
  277. 'wallet_type' => UserWalletService::WALLET_TYPE_SCORE,
  278. 'money' => $data['num'],
  279. 'desc' => "推荐有礼奖励",
  280. 'source_table' => RecommenReward::tableName(),
  281. 'source_table_id' => $data['user_id'],
  282. 'from_type' => UserWalletEnum::REWARD,
  283. 'capital_type' => UserWalletEnum::RECOMMEND,
  284. ];
  285. //var_dump($insert_wallet);die;
  286. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  287. }
  288. /**
  289. * 奖励积分
  290. * @Author: ltm
  291. * @DateTime: 2022/5/17 19:03
  292. * @Copyright: copyright (c) 2021 广东七件事集团
  293. * @param $data
  294. * @return string
  295. */
  296. protected static function rewardCoupon($data){
  297. $is_install = MallAddons::isInstall($data['mall_id'], AddonsEnum::ADDONS_NAME_COUPON);
  298. $reward_text = '';
  299. if($is_install){
  300. // 赠送优惠券
  301. if($data['data']){
  302. $give_coupon_arr = [];
  303. foreach ($data['data'] as $coupon) {
  304. $give_coupon_arr[$coupon['relevant_id']] = $coupon['num'];
  305. }
  306. $coupon_arr = AddonsCouponUserRelate::giveCoupon($data['mall_id'], $data['user_id'], $give_coupon_arr, AddonsCouponEnum::SEND_FROM15);
  307. if ($coupon_arr) {
  308. $coupon_text = [];
  309. foreach ($coupon_arr as $info) {
  310. $coupon_text[] = $info['name'].$info['num'].'张';
  311. }
  312. $reward_text.= "优惠券:[" . implode(',', $coupon_text) .']';
  313. }
  314. }
  315. }
  316. return $reward_text;
  317. }
  318. }