RedpackLogic.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <?php
  2. /**
  3. * 红包拓客
  4. */
  5. namespace addons\Redpack\common\logic;
  6. use addons\BlueScore\common\enums\BlueScoreEnum;
  7. use addons\BlueScore\common\models\BlueScore;
  8. use addons\Redpack\common\enums\RedpackEnum;
  9. use addons\Redpack\common\helper\RedpackHelper;
  10. use addons\Redpack\common\models\Redpack;
  11. use addons\Redpack\common\models\RedpackGoodsSetting;
  12. use addons\Redpack\common\models\RedpackUserCountDay;
  13. use addons\Redpack\common\models\RedpackUserGrab;
  14. use addons\Redpack\common\models\RedpackWallet;
  15. use common\enums\AddonsEnum;
  16. use common\enums\StatusEnum;
  17. use common\models\mall\MallAddons;
  18. use common\models\order\OrderDetail;
  19. use common\models\order\OrderMarketing;
  20. use common\models\user\User;
  21. use common\traits\ErrorTrait;
  22. use yii\db\Exception;
  23. use Yii;
  24. use yii\helpers\Json;
  25. class RedpackLogic
  26. {
  27. use ErrorTrait;
  28. /**
  29. * 判断活动限制
  30. * @Author: lun
  31. * @DateTime: 2022/3/21 0021 17:24
  32. * @Copyright: copyright (c) 2021 广东七件事集团
  33. */
  34. public static function checkUserLimit($redpack, $user_level)
  35. {
  36. if (empty($redpack['limit_user_level'])) throw new \Exception('您暂无参与活动权限');
  37. $limit_user_level = Json::decode($redpack['limit_user_level'], true);
  38. if (!in_array($user_level, $limit_user_level)) throw new \Exception('您暂无参与活动权限');
  39. }
  40. /**
  41. * @param User $user
  42. * @param Redpack $redpack
  43. * @return false|float|mixed|string
  44. */
  45. public static function gradRedpackByUserLimit(User $user, Redpack $redpack, string $pack_name)
  46. {
  47. $trans = Yii::$app->db->beginTransaction();
  48. try {
  49. $date = date('ymd', time());
  50. $award = $redpack->award;// 活动奖金池剩余金额
  51. // 今日抢红包统计
  52. $today_grad = RedpackUserCountDay::find()->where(['rid' => $redpack->id,'user_id' => $user->id,
  53. 'date' => $date, 'status' => StatusEnum::ENABLED])->asArray()->one();
  54. $num = $redpack->limit_user_level_num[$user->level] ?? 0;
  55. if ($num <= 0) throw new \Exception("暂无红包可领");
  56. $today_grad_num = $today_grad['grab_num_total'] ?? 0;
  57. if ($num - $today_grad_num <= 0) throw new \Exception("今日红包个数已领完");
  58. // 解析红包规则内容
  59. $rule_values = Json::decode($redpack->rule_values);
  60. // 首次抢红包金额配置
  61. $money_start = bcmul($rule_values['second_money_start'] ?? 0, 100);
  62. $money_end = bcmul($rule_values['second_money_end'] ?? 0, 100);
  63. if (empty($today_grad)) {
  64. $money_start = bcmul($rule_values['first_money_start'], 100);
  65. $money_end = bcmul($rule_values['first_money_end'], 100);
  66. }
  67. $money = bcmul(rand($money_start, $money_end), 0.01, 2);
  68. // 扣减奖金池
  69. if ($redpack->redpack_type != RedpackEnum::FREEZE_TO_ACTIVE) {
  70. // 判断可得金额是否大于奖金池剩余金额
  71. if ($money >= $award) $money = $award;
  72. $redpack->award = $redpack->award - $money;
  73. }
  74. // 判断用户曾经是否抢过红包
  75. $has_grab = RedpackUserGrab::find()->where(['mall_id' => $redpack->mall_id,'rid' => $redpack->id,
  76. 'user_id' => $user->id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  77. empty($has_grab) && $redpack->grab_user_num = $redpack->grab_user_num + 1;
  78. // 红包表数据统计汇总
  79. $redpack->grab_money = $redpack->grab_money + $money;
  80. // 增加用户红包金额
  81. $p_desc = "";
  82. switch ($redpack->redpack_type) {
  83. case RedpackEnum::FREEZE_TO_ACTIVE :
  84. $is_frozen = false;
  85. $desc = "抢冻结到激活$pack_name";
  86. // 将冻结红包的金额先减扣掉
  87. $wallet = RedpackWallet::setData([
  88. 'mall_id' => $redpack->mall_id,
  89. 'user_id' => $user->id,
  90. 'is_frozen' => true,
  91. 'is_deduct' => true,
  92. 'money' => -$money,
  93. 'source_table' => Redpack::briefTableName(),
  94. 'source_table_id' => $redpack->id,
  95. 'from_type' => RedpackEnum::FROM_RECEIVE,
  96. 'desc' => $desc,
  97. ]);
  98. if (!$wallet) throw new Exception(RedpackWallet::getStaticError());
  99. $money = $wallet['money'];
  100. if ($money <= 0) throw new \Exception("暂无可激活的冻结$pack_name");
  101. break;
  102. case RedpackEnum::INCREMENT_FREEZE :
  103. $is_frozen = true;
  104. $desc = '抢冻结' . $pack_name;
  105. $p_desc = '冻结' . $pack_name;
  106. break;
  107. case RedpackEnum::INCREMENT_ACTIVE :
  108. $is_frozen = false;
  109. $desc = '抢激活' . $pack_name;
  110. $p_desc = '激活' . $pack_name;
  111. break;
  112. }
  113. // 增加用户的红包余额
  114. $res = RedpackWallet::setData([
  115. 'mall_id' => $redpack->mall_id,
  116. 'user_id' => $user->id,
  117. 'is_frozen' => $is_frozen,
  118. 'money' => $money,
  119. 'source_table' => Redpack::briefTableName(),
  120. 'source_table_id' => $redpack->id,
  121. 'from_type' => RedpackEnum::FROM_RECEIVE,
  122. 'desc' => $desc,
  123. ]);
  124. if (!$res) throw new Exception(RedpackWallet::getStaticError());
  125. // 增加抢红包次数
  126. $count_day = [
  127. 'mall_id' => $redpack->mall_id,
  128. 'rid' => $redpack->id,
  129. 'user_id' => $user->id,
  130. 'grab_num' => empty($today_grad['grab_num_total']) ? $num - 1 : $num - $today_grad['grab_num_total'] - 1,
  131. 'grab_num_total' => empty($today_grad['grab_num_total']) ? 1 : $today_grad['grab_num_total'] + 1,
  132. ];
  133. !empty($today_grad['id']) && $count_day['id'] = $today_grad['id'];
  134. $res = RedpackUserCountDay::setData($count_day);
  135. if (!$res) throw new Exception(RedpackUserCountDay::getStaticError());
  136. // 增加抢红包数据
  137. $res = RedpackUserGrab::setData([
  138. 'mall_id' => $redpack->mall_id,
  139. 'rid' => $redpack->id,
  140. 'user_id' => $user->id,
  141. 'grab_money' => $money,
  142. ]);
  143. if (!$res) throw new Exception(RedpackUserGrab::getStaticError());
  144. // 判断上级是否需要增加,当前用户是否有上级
  145. if ($redpack->reward_parent_rate > 0 && !empty($user->parent_id) &&
  146. $redpack->award > 0 && $redpack->redpack_type > 1 && $redpack->is_limit_user_level_num) {
  147. // 增加用户的红包余额
  148. $parent_money = bcmul($money, bcmul($redpack->reward_parent_rate, 0.01, 10), 2);
  149. if ($parent_money > $redpack->award) $parent_money = $redpack->award;
  150. $redpack->award -= $parent_money; // 奖池需要减去上级奖励金额
  151. if ($parent_money >= 0.01) {
  152. $res = RedpackWallet::setData([
  153. 'mall_id' => $redpack->mall_id,
  154. 'user_id' => $user->parent_id,
  155. 'is_frozen' => $is_frozen,
  156. 'money' => $parent_money,
  157. 'source_table' => Redpack::briefTableName(),
  158. 'source_table_id' => $redpack->id,
  159. 'from_type' => RedpackEnum::FROM_SUBORDINATE,
  160. 'desc' => "{$p_desc}: 会员ID [$user->id] 的直推$pack_name",
  161. ]);
  162. if (!$res) throw new Exception(RedpackWallet::getStaticError());
  163. // 增加抢红包数据
  164. $res = RedpackUserGrab::setData([
  165. 'mall_id' => $redpack->mall_id,
  166. 'rid' => $redpack->id,
  167. 'user_id' => $user->parent_id,
  168. 'grab_money' => $parent_money,
  169. ]);
  170. if (!$res) throw new Exception(RedpackUserGrab::getStaticError());
  171. }
  172. }
  173. // 更新红包活动
  174. if (!$redpack->save()) throw new Exception($redpack->getErrorMessage());
  175. $trans->commit();
  176. return $money;
  177. } catch (\Exception $e) {
  178. self::setStaticError($e->getMessage());
  179. $trans->rollBack();
  180. return false;
  181. }
  182. }
  183. /**
  184. * 红包金额变动
  185. * @Author: lun
  186. * @DateTime: 2022/3/22 0022 9:56
  187. * @Copyright: copyright (c) 2021 广东七件事集团
  188. * @param int $user_id
  189. */
  190. public static function gradRedpack($user_id, Redpack $redpack, string $pack_name)
  191. {
  192. $trans = Yii::$app->db->beginTransaction();
  193. try {
  194. $time_type = $redpack['time_type'];// 活动类型[1=每日红包,2=时间段红包]
  195. $date = date('ymd', time());
  196. // 活动-每日抢红包,每天都有一次无需邀请人抢红包机会
  197. // 活动-时间段抢红包,在这个时间段内,最多只有一次无需邀请人可抢红包机会
  198. // 获取用户是否首次抢红包
  199. if ($time_type == 1) {
  200. $is_first_grad = RedpackUserCountDay::find()->where(['rid' => $redpack->id,'user_id' => $user_id, 'date' => $date, 'status' => StatusEnum::ENABLED])->asArray()->one();
  201. } else {
  202. $is_first_grad = RedpackUserCountDay::find()->where(['rid' => $redpack->id,'user_id' => $user_id, 'status' => StatusEnum::ENABLED, 'inviter_num' => 0])->asArray()->one();
  203. }
  204. $award = $redpack->award;// 活动奖金池剩余金额
  205. // 今日抢红包统计
  206. $today_grad = RedpackUserCountDay::find()->where(['rid' => $redpack->id,'user_id' => $user_id, 'date' => $date, 'status' => StatusEnum::ENABLED])->asArray()->one();
  207. // 解析红包规则内容
  208. $rule_values = Json::decode($redpack->rule_values, true);
  209. if (empty($is_first_grad)) {
  210. // 首次抢红包金额配置
  211. $money = rand($rule_values['first_money_start'] * 100, $rule_values['first_money_end'] * 100);
  212. } else {
  213. // 非首次抢到红包,检查最后一次抢红包次数是否是第一次抢,不是则找到今日最后一次抢的统计内容
  214. // 判断今日抢红包次数是否已经超出
  215. if ($today_grad['grab_num_total'] >= $rule_values['times']) throw new \Exception('今日抢红包次数已用完');
  216. // 判断可抢次数是否还足够
  217. $user_grad_num = empty($today_grad['inviter_num']) ? 0 : floor($today_grad['inviter_num'] / $rule_values['everyday_invitation']);// 用户已抢红包次数
  218. if ($user_grad_num - $today_grad['grab_num_total'] + 1 <= 0) throw new \Exception('今日抢红包次数不足');
  219. $money = rand($rule_values['everyday_invitation_start'] * 100, $rule_values['everyday_invitation_end'] * 100);
  220. }
  221. // 将奖励金额单位改为元
  222. $money = $money / 100;
  223. // 扣减奖金池
  224. if ($redpack->redpack_type != RedpackEnum::FREEZE_TO_ACTIVE) {
  225. // 判断可得金额是否大于奖金池剩余金额
  226. if ($money >= $award) $money = $award;
  227. $redpack->award = $redpack->award - $money;
  228. }
  229. // 判断用户曾经是否抢过红包
  230. $has_grab = RedpackUserGrab::find()->where(['mall_id' => $redpack->mall_id,'rid' => $redpack->id,'user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  231. empty($has_grab) && $redpack->grab_user_num = $redpack->grab_user_num + 1;
  232. // 红包表数据统计汇总
  233. $redpack->grab_money = $redpack->grab_money + $money;
  234. if (!$redpack->save()) throw new Exception($redpack->getErrorMessage());
  235. // 增加用户红包金额
  236. switch ($redpack->redpack_type) {
  237. case RedpackEnum::FREEZE_TO_ACTIVE :
  238. $is_frozen = false;
  239. $desc = '抢冻结到激活' . $pack_name;
  240. // 将冻结红包的金额先减扣掉
  241. $wallet = RedpackWallet::setData([
  242. 'mall_id' => $redpack->mall_id,
  243. 'user_id' => $user_id,
  244. 'is_frozen' => true,
  245. 'is_deduct' => true,
  246. 'money' => -$money,
  247. 'source_table' => Redpack::briefTableName(),
  248. 'source_table_id' => $redpack->id,
  249. 'from_type' => RedpackEnum::FROM_RECEIVE,
  250. 'desc' => $desc,
  251. ]);
  252. if ($wallet == false) throw new Exception(RedpackWallet::getStaticError());
  253. $money = $wallet['money'];
  254. if ($money <= 0) throw new \Exception("暂无可激活的冻结$pack_name");
  255. break;
  256. case RedpackEnum::INCREMENT_FREEZE :
  257. $is_frozen = true;
  258. $desc = '抢冻结' . $pack_name;
  259. break;
  260. case RedpackEnum::INCREMENT_ACTIVE :
  261. $is_frozen = false;
  262. $desc = '抢激活' . $pack_name;
  263. break;
  264. }
  265. // 增加用户的红包余额
  266. $res = RedpackWallet::setData([
  267. 'mall_id' => $redpack->mall_id,
  268. 'user_id' => $user_id,
  269. 'is_frozen' => $is_frozen,
  270. 'money' => $money,
  271. 'source_table' => Redpack::briefTableName(),
  272. 'source_table_id' => $redpack->id,
  273. 'from_type' => RedpackEnum::FROM_RECEIVE,
  274. 'desc' => $desc,
  275. ]);
  276. if ($res == false) throw new Exception(RedpackWallet::getStaticError());
  277. // 增加抢红包次数
  278. $count_day = [
  279. 'mall_id' => $redpack->mall_id,
  280. 'rid' => $redpack->id,
  281. 'user_id' => $user_id,
  282. 'grab_num' => empty($today_grad['grab_num_total']) ? $rule_values['times'] - 1 : $rule_values['times'] - $today_grad['grab_num_total'] - 1,
  283. 'grab_num_total' => empty($today_grad['grab_num_total']) ? 1 : $today_grad['grab_num_total'] + 1,
  284. ];
  285. !empty($today_grad['id']) && $count_day['id'] = $today_grad['id'];
  286. $res = RedpackUserCountDay::setData($count_day);
  287. if ($res == false) throw new Exception(RedpackUserCountDay::getStaticError());
  288. // 增加抢红包数据
  289. $res = RedpackUserGrab::setData([
  290. 'mall_id' => $redpack->mall_id,
  291. 'rid' => $redpack->id,
  292. 'user_id' => $user_id,
  293. 'grab_money' => $money,
  294. ]);
  295. if ($res == false) throw new Exception(RedpackUserGrab::getStaticError());
  296. $trans->commit();
  297. return $money;
  298. } catch (\Exception $e) {
  299. self::setStaticError($e->getMessage());
  300. $trans->rollBack();
  301. return false;
  302. }
  303. }
  304. /**
  305. * 赠送红包
  306. * @Author: lun
  307. * @DateTime: 2022/3/26 0026 14:51
  308. * @Copyright: copyright (c) 2021 广东七件事集团
  309. * @param $order_id
  310. * @param $order_status 1=支付完成,2=订单完成
  311. * @return bool
  312. */
  313. public static function giveRedpack($order_id, $order_status = 2)
  314. {
  315. try {
  316. $order = \common\models\order\Order::findOne(['id'=>$order_id]);
  317. if(!empty($order['store_id'])) return true;
  318. // 查询订单
  319. $select = "mall_id,goods_id,user_id,goods_price,adjust_money,num";
  320. $order_details = OrderDetail::find()->select($select)->where(['order_id' => $order_id])->indexBy("goods_id")->asArray()->all();
  321. if (empty($order_details)) throw new \Exception("订单id={$order_id}的订单详情数据为空");
  322. $goods_ids = array_keys($order_details);// 商品ids
  323. foreach ($order_details as $goods_id => $detail) {
  324. $user_id = $detail['user_id'];
  325. $mall_id = $detail['mall_id'];
  326. break;
  327. }
  328. // 获取配置【1=支付完成,2=订单完成】
  329. $give_type = Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_REDPACK, 'basic.give_type');
  330. if ($give_type != $order_status) return true;
  331. // 获取设置了红包的商品
  332. $list = RedpackGoodsSetting::find()->where(['goods_id' => $goods_ids, 'is_enable' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED])->asArray()->all();true;
  333. if (empty($list)) return true;
  334. foreach ($list as $item) {
  335. // 计算可赠送的红包金额
  336. $pay_money = $order_details[$item['goods_id']]['goods_price'] + $order_details[$item['goods_id']]['adjust_money'];
  337. $money = $item['is_percent'] == 0 ? bcmul($item['give'], $order_details[$item['goods_id']]['num'], 2) : bcmul(($item['give'] / 100), $pay_money, 2);
  338. if ($money <= 0) continue;
  339. // 插入红包金额表
  340. $wallet = RedpackWallet::setData([
  341. 'mall_id' => $item['mall_id'],
  342. 'user_id' => $user_id,
  343. 'is_frozen' => $item['redpack_wallet_type'] == RedpackEnum::WALLET_REDPACK_FROZEN ? true : false,
  344. 'money' => $money,
  345. 'source_table' => 'order',
  346. 'source_table_id' => $order_id,
  347. 'from_type' => RedpackEnum::FROM_GOODS,
  348. 'desc' => '购物赠送',
  349. ]);
  350. if ($wallet == false) throw new Exception(RedpackWallet::getStaticError());
  351. }
  352. return true;
  353. } catch (\Exception $e) {
  354. self::setStaticError($e->getMessage());
  355. return false;
  356. }
  357. }
  358. /**
  359. * 红包返回
  360. * @Author: lun
  361. * @DateTime: 2022/9/21 0021 9:54
  362. * @Copyright: copyright (c) 2021 广东七件事集团
  363. * @param $order_detail_id
  364. * @param array $params
  365. * @return bool
  366. */
  367. public static function backRedpack($order_detail_id, $params = [])
  368. {
  369. $trans = Yii::$app->db->beginTransaction();
  370. try {
  371. $deduct = OrderMarketing::find()->select('deduct_currency')->where(['order_detail_id' => $order_detail_id, 'status' => StatusEnum::ENABLED])->scalar();
  372. if (empty($deduct)) {
  373. $trans->commit();
  374. return true;
  375. }
  376. $deduct_arr = Json::decode($deduct, true);
  377. foreach ($deduct_arr as $key => $item) {
  378. // 判断里面是否存在激活红包跟冻结红包
  379. if (in_array($key, [RedpackEnum::WALLET_REDPACK, RedpackEnum::WALLET_REDPACK_FROZEN]) && $item['money'] > 0) {
  380. $wallet = RedpackWallet::setData([
  381. 'mall_id' => $params['mall_id'],
  382. 'user_id' => $params['user_id'],
  383. 'is_frozen' => $key == RedpackEnum::WALLET_REDPACK_FROZEN ? true : false,
  384. 'money' => $item['money'],
  385. 'source_table' => $params['source_table'],
  386. 'source_table_id' => $params['source_table_id'],
  387. 'from_type' => $params['from_type'],
  388. 'desc' => $params['desc'] ?? '',
  389. 'no_icr_total' => true,// 不增加红包累计总额
  390. ]);
  391. if ($wallet == false) throw new Exception(RedpackWallet::getStaticError());
  392. }
  393. }
  394. $trans->commit();
  395. return true;
  396. } catch (\Exception $e) {
  397. $trans->rollBack();
  398. self::setStaticError($e->getMessage());
  399. return false;
  400. }
  401. }
  402. /**
  403. * 订单加速冻结红包转激活红包
  404. * @Author:
  405. * @DateTime:
  406. * @Copyright: copyright (c) 2021 广东七件事集团
  407. * @param $order_id
  408. * @param int $orderStatus
  409. * @return bool
  410. */
  411. public static function accelerateFrozenToActive($order_id, int $orderStatus = \common\enums\OrderStatusEnum::PAY)
  412. {
  413. try {
  414. $order = \common\models\order\Order::findOne(['id' => $order_id]);
  415. if (!empty($order['store_id'])) return true;
  416. // 查询订单
  417. $select = "mall_id,goods_id,user_id,goods_price,adjust_money,num";
  418. $order_details = OrderDetail::find()->select($select)->where(['order_id' => $order_id])->indexBy("goods_id")->asArray()->all();
  419. if (empty($order_details)) throw new \Exception("订单id={$order_id}的订单详情数据为空");
  420. $goods_ids = array_keys($order_details);// 商品ids
  421. foreach ($order_details as $goods_id => $detail) {
  422. $user_id = $detail['user_id'];
  423. $mall_id = $detail['mall_id'];
  424. break;
  425. }
  426. //获取红包配置
  427. $config = Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_REDPACK, 'basic');
  428. $config = RedpackHelper::initConfig($config);
  429. //获取蓝色积分配置
  430. $blue_score_config = Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_BLUE_SCORE, 'basic');
  431. if (empty($config['is_accelerated_activation'])) return true;
  432. //判断订单状态
  433. // 因为订单队列执行慢,可能会出现客户支付成功后就操作订单完成。这个时候肯支付队列、订单完成队列的订单状态都是一致的。所以需要修改为由队列传递状态
  434. if ($config['accelerate_settlement_type'] == 1 && $order->order_status != $orderStatus) {
  435. return true;
  436. }
  437. if ($config['accelerate_settlement_type'] == 2 && $order->order_status != $orderStatus) {
  438. return true;
  439. }
  440. $accelerated_user_level_ids = json_decode($config['accelerated_user_level_ids'], true);
  441. $accelerated_goods_ids = json_decode($config['accelerated_goods_ids'], true);
  442. $accelerated_goods_list = json_decode($config['accelerated_goods_list'], true);
  443. $accelerated_goods_list = array_column($accelerated_goods_list, null, 'id');
  444. //获取用户上级
  445. $user = \common\models\user\User::findOne(['id' => $user_id]);
  446. $user_parent = \common\models\user\User::findOne(['id' => $user->parent_id]);
  447. //没有上级信息
  448. if (empty($user_parent)) return true;
  449. $user_level_res = \common\models\user\UserLevel::getUserLevelOne([['mall_id' => $mall_id], ['level' => $user_parent->level]], [], 1);
  450. //上级等级不在加速等级
  451. if (!in_array($user_level_res['id'], $accelerated_user_level_ids)) return true;
  452. $goods_intersect = array_intersect($goods_ids, $accelerated_goods_ids);
  453. //没有商品可以进行加速
  454. if (empty($goods_intersect)) return true;
  455. $money = 0;
  456. //计算加速冻结红包数额
  457. foreach ($accelerated_goods_list as $item) {
  458. if (in_array($item['id'], $goods_intersect)) {
  459. $money += $item['accelerate_number'];
  460. }
  461. }
  462. if ($money == 0) return true;
  463. $user_redpack_wallet = RedpackWallet::findOne(['user_id' => $user_parent->id, 'status' => StatusEnum::ENABLED]);
  464. //没有冻结红包
  465. if (empty($user_redpack_wallet) || $user_redpack_wallet['frozen_redpack'] == 0 ) return true;
  466. if ($user_redpack_wallet['frozen_redpack'] < $money) {
  467. //冻结红包数额少于加速数额,则将冻结红包全部转换
  468. $money = $user_redpack_wallet['frozen_redpack'];
  469. }
  470. $trans = Yii::$app->db->beginTransaction();
  471. //扣除冻结红包
  472. $res = RedpackWallet::setData([
  473. 'mall_id' => $mall_id,
  474. 'user_id' => $user_parent->id,
  475. 'is_frozen' => true,
  476. 'is_deduct' => true,
  477. 'money' => -$money,
  478. 'from_type' => RedpackEnum::FROM_ORDER_ACCELERATED_FROZEN_ROLL_OUT,
  479. 'desc' => '订单加速冻结红包转出',
  480. ]);
  481. if ($res === false) throw new Exception('执行失败');
  482. //是否安装and开启了蓝色积分转换
  483. $has_blue_score = MallAddons::isInstall($mall_id,AddonsEnum::ADDONS_BLUE_SCORE);
  484. if ($has_blue_score && !empty($blue_score_config) && $blue_score_config['is_enable'] == StatusEnum::ENABLED) {
  485. if (!empty($blue_score_config['transfer_rate']) || $blue_score_config['transfer_rate'] > 0) {
  486. //计算激活红包转换的蓝色积分
  487. $integral = round($money * $blue_score_config['transfer_rate'] / 100, 2);
  488. //计算剩余的激活红包
  489. $money = round($money * (1 - ($blue_score_config['transfer_rate'] / 100)), 2);;
  490. //转换蓝色积分
  491. $res = BlueScore::setData([
  492. 'mall_id' => $mall_id,
  493. 'user_id' => $user_parent->id,
  494. 'integral' => $integral,
  495. 'from_type' => BlueScoreEnum::FROM_ORDER_ACCELERATED_ACTIVE_TO_BLUE_SCORE,
  496. 'desc' => '用户(' . $user_id . '),获得订单(' . $order_id .')加速冻结红包转蓝色积分奖励,蓝色积分+' . $integral,
  497. 'source_table' => \common\models\order\Order::tableName(),
  498. 'source_table_id' => $order_id,
  499. ]);
  500. if ($res === false) throw new Exception('执行失败');
  501. }
  502. }
  503. //转激活红包
  504. $res = RedpackWallet::setData([
  505. 'mall_id' => $mall_id,
  506. 'user_id' => $user_parent->id,
  507. 'is_frozen' => false,
  508. 'is_deduct' => true,
  509. 'money' => $money,
  510. 'from_type' => RedpackEnum::FROM_ORDER_ACCELERATED_FROZEN_TO_ACTIVE,
  511. 'desc' => '订单加速冻结红包转激活红包',
  512. ]);
  513. if ($res === false) throw new Exception('执行失败');
  514. $trans->commit();
  515. return true;
  516. } catch (\Exception $e) {
  517. $trans->rollBack();
  518. self::setStaticError($e->getMessage());
  519. return false;
  520. }
  521. }
  522. }