BargainOrder.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. <?php
  2. namespace addons\Bargain\common\models;
  3. use addons\Bargain\common\enums\BargainEnum;
  4. use common\enums\GoodsTypeEnum;
  5. use common\enums\OrderStatusEnum;
  6. use common\enums\PaymentTradeOrderEnum;
  7. use common\enums\RabbitMqEnum;
  8. use common\enums\RedisKeyEnum;
  9. use common\enums\StatusEnum;
  10. use common\enums\UserWalletEnum;
  11. use common\helpers\FormatHelper;
  12. use common\helpers\LockHelper;
  13. use common\helpers\StringHelper;
  14. use common\models\base\BaseActiveRecord;
  15. use common\models\goods\Goods;
  16. use common\models\goods\GoodsAttr;
  17. use common\models\order\Order;
  18. use common\models\order\OrderDetail;
  19. use common\models\user\User;
  20. use common\models\user\UserLevel;
  21. use services\common\UserWalletService;
  22. use Yii;
  23. use yii\helpers\Json;
  24. /**
  25. * This is the model class for table "qimall_addons_bargain_order".
  26. *
  27. * @property int $id
  28. * @property int $mall_id
  29. * @property int $user_id
  30. * @property int $order_id 主订订单id
  31. * @property string $order_no 订单编号
  32. * @property int $bargain_active_id 砍价活动id
  33. * @property string $goods_name
  34. * @property string $cover_pic
  35. * @property string $token
  36. * @property float $price 售价
  37. * @property float $min_price 最低价
  38. * @property int $time 砍价时间
  39. * @property int $order_status 状态 0--进行中 1--成功 2--失败
  40. * @property int $is_pay 是否支付:0否;1:是
  41. * @property string $bargain_goods_data 砍价设置
  42. * @property string|null $mobile 收货人的手机号码
  43. * @property string|null $receiver_name 收货人姓名
  44. * @property int|null $province 收货人所在省
  45. * @property int|null $city 收货人所在城市
  46. * @property int|null $area 收货人所在街道
  47. * @property string|null $zip 收货人邮编
  48. * @property string|null $address 详细地址
  49. * @property string|null $region_name 地区名称(省市区[乡/镇])
  50. * @property float $bargain_price 砍后商品价格
  51. * @property float $reduce_price 减少价格
  52. * @property int $num 购买数量
  53. * @property int $payment_type 支付方式:1.在线支付 2.货到付款 3.余额支付
  54. * @property int $pay_time 支付时间
  55. * @property int $shipping_type 订单配送方式【1物流配送 2买家自提 3货到付款 4本地配送】
  56. * @property float $shipping_money 运费
  57. * @property float $total_pay_price 实际支付总费用(含运费)
  58. * @property string $remark 用户订单备注
  59. * @property int $status 状态[-1:删除;0:禁用;1启用]
  60. * @property int $created_at
  61. * @property int $updated_at
  62. */
  63. class BargainOrder extends BaseActiveRecord
  64. {
  65. /**
  66. * {@inheritdoc}
  67. */
  68. public static function tableName(): string
  69. {
  70. return '{{%addons_bargain_order}}';
  71. }
  72. /**
  73. * {@inheritdoc}
  74. */
  75. public function rules(): array
  76. {
  77. return [
  78. [['mall_id', 'user_id', 'order_id', 'bargain_active_id', 'time', 'order_status', 'is_pay', 'province', 'city', 'area', 'num', 'payment_type', 'pay_time', 'shipping_type', 'status', 'created_at', 'updated_at'], 'integer'],
  79. [['price', 'min_price', 'bargain_price','reduce_price', 'shipping_money', 'total_pay_price'], 'number'],
  80. [['bargain_goods_data'], 'required'],
  81. [['bargain_goods_data'], 'string'],
  82. [['order_no', 'receiver_name'], 'string', 'max' => 50],
  83. [['cover_pic','goods_name','token', 'remark'], 'string', 'max' => 255],
  84. [['mobile'], 'string', 'max' => 11],
  85. [['zip'], 'string', 'max' => 20],
  86. [['address', 'region_name'], 'string', 'max' => 200],
  87. ];
  88. }
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function attributeLabels(): array
  93. {
  94. return [
  95. 'id' => 'ID',
  96. 'mall_id' => 'Mall ID',
  97. 'user_id' => 'User ID',
  98. 'order_id' => '主订订单id',
  99. 'order_no' => '订单编号',
  100. 'bargain_active_id' => '砍价活动id',
  101. 'cover_pic' => 'cover_pic',
  102. 'goods_name' => 'goods_name',
  103. 'token' => 'Token',
  104. 'price' => '售价',
  105. 'min_price' => '最低价',
  106. 'time' => '砍价时间',
  107. 'order_status' => '状态 0--进行中 1--成功 2--失败',
  108. 'is_pay' => '是否支付:0否;1:是',
  109. 'bargain_goods_data' => '砍价设置',
  110. 'mobile' => '收货人的手机号码',
  111. 'receiver_name' => '收货人姓名',
  112. 'province' => '收货人所在省',
  113. 'city' => '收货人所在城市',
  114. 'area' => '收货人所在街道',
  115. 'zip' => '收货人邮编',
  116. 'address' => '详细地址',
  117. 'region_name' => '地区名称(省市区[乡/镇])',
  118. 'bargain_price' => '砍后商品价格',
  119. 'reduce_price' => '减少价格',
  120. 'num' => '购买数量',
  121. 'payment_type' => '支付方式:1.在线支付 2.货到付款 3.余额支付',
  122. 'pay_time' => '支付时间',
  123. 'shipping_type' => '订单配送方式【1物流配送 2买家自提 3货到付款 4本地配送】',
  124. 'shipping_money' => '运费',
  125. 'total_pay_price' => '实际支付总费用(含运费)',
  126. 'remark' => '用户订单备注',
  127. 'status' => '状态[-1:删除;0:禁用;1启用]',
  128. 'created_at' => 'Created At',
  129. 'updated_at' => 'Updated At',
  130. ];
  131. }
  132. public function getUser(): \yii\db\ActiveQuery
  133. {
  134. return $this->hasOne(User::class, ['id' => 'user_id']);
  135. }
  136. public function getActive(): \yii\db\ActiveQuery
  137. {
  138. return $this->hasOne(BargainActive::class, ['id' => 'bargain_active_id']);
  139. }
  140. public function getUserJoinOrder(): \yii\db\ActiveQuery
  141. {
  142. return $this->hasMany(BargainUserOrder::class, ['bargain_order_id' => 'id'])->where(['status' => StatusEnum::ENABLED]);
  143. }
  144. /**
  145. * @desc:发布砍价
  146. * @Author: hua
  147. * @Date: 2022/1/3
  148. * @Time: 15:16
  149. * @Copyright: copyright (c) 2021 广东七件事集团
  150. * @param $params
  151. * @return BargainOrder|false
  152. */
  153. public static function release($params)
  154. {
  155. $stock_locks = [];
  156. $t = Yii::$app->db->beginTransaction();
  157. try {
  158. $lock_key = RedisKeyEnum::LOCK_BARGAIN_ACTIVE . $params['active_id'];
  159. $identification = uniqid();
  160. $stock_locks[$lock_key] = $identification;
  161. if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new \Exception('当前访问人数过多');
  162. $active = BargainActive::findOne(['mall_id' => $params['mall_id'], 'id' => $params['active_id'], 'active_status' => BargainEnum::ACTIVE_HANDING]);
  163. if (!$active) throw new \Exception('砍价商品不存在');
  164. if ($active->begin_time >= time()) throw new \Exception('砍价活动尚未开始');
  165. if ($active->end_time <= time()) throw new \Exception('砍价活动已结束');
  166. if ($active->stock <= 0) throw new \Exception('砍价活动商品库存不足');
  167. $bargain_order = BargainOrder::findOne(['mall_id' => $params['mall_id'], 'bargain_active_id' => $active['id'], 'user_id' => $params['user_id'], 'order_status' => BargainEnum::ORDER_HANDING,'status'=>StatusEnum::ENABLED]);
  168. if (!empty($bargain_order)) throw new \Exception('已存在进行中的砍价');
  169. //检查用户等级能否参与
  170. self::checkUserLevel($params, $active);
  171. //检查用户参与次数
  172. self::checkUserJoinTime($params, $active);
  173. $token = \Yii::$app->security->generateRandomString();
  174. $mode_data = json_decode($active->mode_data, JSON_UNESCAPED_UNICODE);
  175. $goods = $active->goods;
  176. $bargain_order = new BargainOrder();
  177. $bargain_order->loadDefaultValues();
  178. $bargain_order->mall_id = $params['mall_id'];
  179. $bargain_order->user_id = $params['user_id'];
  180. $bargain_order->bargain_active_id = $active->id;
  181. $bargain_order->token = $token;
  182. $bargain_order->price = $active->goods->price;
  183. $bargain_order->min_price = $active->min_price;
  184. $bargain_order->time = $active->time;
  185. $bargain_order->goods_name = $goods->goods_name;
  186. $bargain_order->cover_pic = $goods->cover_pic;
  187. $bargain_order->bargain_goods_data = json_encode(array_merge([
  188. 'min_price' => $active->min_price,
  189. 'begin_time' => $active->begin_time,
  190. 'end_time' => $active->end_time,
  191. 'time' => $active->time,
  192. 'type' => $active->type,
  193. 'stock' => $active->stock,
  194. 'id' => $active->id,
  195. 'price' => $active->goods->price
  196. ], $mode_data), JSON_UNESCAPED_UNICODE);
  197. if (!$bargain_order->save()) throw new \Exception($bargain_order->getErrorMessage());
  198. if ($active->type != 1) {
  199. //选择允许中途下单,在下单后才减少库存
  200. $active->stock -= 1;
  201. }
  202. $active->initiator += 1;
  203. $active->underway += 1;
  204. if (!$active->save()) throw new \Exception(BargainActive::getStaticError());
  205. $t->commit();
  206. LockHelper::batchUlock($stock_locks);
  207. return $bargain_order;
  208. } catch (\Exception $e) {
  209. LockHelper::batchUlock($stock_locks);
  210. $t->rollback();
  211. self::$static_error = $e->getMessage();
  212. return false;
  213. }
  214. }
  215. public static function checkUserLevel($params, $active)
  216. {
  217. $join_limit_user_level = empty($active->join_limit_user_level) ? [] : $active->join_limit_user_level;
  218. if (empty($join_limit_user_level)) {
  219. return true;
  220. }
  221. $user = User::find()
  222. ->where(['id' => $params['user_id'], 'status' => StatusEnum::ENABLED])
  223. ->select('id,level')
  224. ->asArray()
  225. ->one();
  226. if (empty($user)) {
  227. throw new \Exception('用户信息不存在');
  228. }
  229. $mall_level_info = UserLevel::find()
  230. ->where([
  231. 'mall_id' => $params['mall_id'],
  232. 'status' => StatusEnum::ENABLED
  233. ])
  234. ->andWhere(['in', 'id', $join_limit_user_level])
  235. ->select('id,level')
  236. ->asArray()
  237. ->all();
  238. $join_level = $mall_level_info ? array_column($mall_level_info, 'level') : [];
  239. if (in_array(0, $join_limit_user_level)) {
  240. $join_level[] = 0;
  241. }
  242. if (!in_array($user['level'], $join_level)) {
  243. throw new \Exception('很抱歉!您暂时无法发起这个活动~');
  244. }
  245. }
  246. public static function checkUserJoinTime($params, $active)
  247. {
  248. $active_release_count = self::find()
  249. ->where([
  250. 'mall_id' => $params['mall_id'],
  251. 'user_id' => $params['user_id'],
  252. 'bargain_active_id' => $active->id,
  253. 'status' => StatusEnum::ENABLED
  254. ])
  255. ->count();
  256. if ($active->join_time && $active->join_time <= $active_release_count) {
  257. throw new \Exception('您的发起次数不足,去发起其它活动吧~');
  258. }
  259. }
  260. /**
  261. * @desc:生成订单
  262. * @Author: hua
  263. * @Date: 2022/1/4
  264. * @Time: 17:07
  265. * @Copyright: copyright (c) 2021 广东七件事集团
  266. * @param $form
  267. * @return array|false
  268. */
  269. public static function createOrder($form)
  270. {
  271. $trans = Yii::$app->db->beginTransaction();
  272. try {
  273. $group_order_goods = $form['group_order_goods'];
  274. $data = is_array($form->data) ? $form->data : Json::decode($form->data, true);
  275. $order_trade_info = [];
  276. //只有一个订单
  277. foreach ($group_order_goods as $mch_order) {
  278. $mch_order_info = $mch_order['mch_order_info'];
  279. $bargain_order = BargainOrder::findOne(['mall_id' => $form->mall_id, 'user_id' => $form->user_id, 'bargain_active_id' => $data['active_id'], 'order_status' => BargainEnum::ORDER_HANDING]);
  280. if (empty($bargain_order)) throw new \Exception('砍价订单不存在');
  281. $bargain_order->load($mch_order_info, '');
  282. $bargain_order->order_status = OrderStatusEnum::NOT_PAY;
  283. $bargain_order->remark = $data['remark'];
  284. $bargain_order->total_pay_price = $mch_order_info['pay_money'];
  285. $bargain_order->order_no = StringHelper::generateOrderNo('br');
  286. $res = $bargain_order->save();
  287. if ($res == false) throw new \Exception(BargainOrder::getStaticError());
  288. $order_trade_info[] = [
  289. 'order_no' => $bargain_order->order_no,
  290. 'amount' => $bargain_order->total_pay_price,
  291. 'title' => mb_strlen($mch_order_info['goods_name']) > 32 ? mb_substr($mch_order_info['goods_name'], 0, 32) : $mch_order_info['goods_name'],
  292. 'notify_class' => BargainEnum::NOTIFY_CLASS,
  293. 'order_type' => PaymentTradeOrderEnum::BARGAIN_ORDER,
  294. ];
  295. }
  296. //中途下单的 创建订单才扣活动库存
  297. $bargain_active = BargainActive::findOne(['id' => $data['active_id'], 'mall_id' => $form->mall_id]);
  298. if ($bargain_active && $bargain_active['type'] == 1) {
  299. $goods = Goods::getOne([
  300. ['mall_id' => $form->mall_id],
  301. ['id' => $bargain_active['goods_id']],
  302. ['status' => StatusEnum::ENABLED]
  303. ], true, [], null, 'goods_name');
  304. if ($bargain_active['stock'] <= 0) throw new \Exception($goods['goods_name'] . '商品已售罄,暂时无法购买哦~');
  305. $bargain_active->stock -= 1;
  306. if (!$bargain_active->save()) throw new \Exception(BargainActive::getStaticError());
  307. }
  308. $trans->commit();
  309. //生成支付流水
  310. $res = \Yii::$app->services->pay->createTrade($form['mall_id'], $form['user_id'], $order_trade_info);
  311. if ($res == false) throw new \Exception('生成支付流水失败');
  312. $arr['transaction'] = $res;
  313. $arr['pay_success_page'] = Yii::$app->services->setting->mall->get($form['mall_id'], 'order.pay_after_link');// 支付成功后跳转的地址
  314. return $arr;
  315. } catch (\Exception $e) {
  316. if (isset($trans)) $trans->rollback();
  317. self::$static_error = $e->getMessage();
  318. return false;
  319. }
  320. }
  321. /**
  322. * @desc:支付回调
  323. * @Author: hua
  324. * @Date: 2022/1/5
  325. * @Time: 14:23
  326. * @Copyright: copyright (c) 2021 广东七件事集团
  327. * @param $params
  328. * @param $payment_type
  329. * @param $out_trade_no
  330. * @return BargainOrder|false
  331. */
  332. public static function pay($params, $payment_type, $out_trade_no = '')
  333. {
  334. $trans = Yii::$app->db->beginTransaction();
  335. try {
  336. $model = self::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED]]);
  337. if (empty($model)) throw new \Exception('订单不存在或已删除');
  338. if ($model->is_pay != OrderStatusEnum::NOT_PAY) throw new \Exception('订单已经被处理,无法进行支付');
  339. if ($model->is_pay == StatusEnum::ENABLED) throw new \Exception('订单已支付,请不要重复支付');
  340. $model->is_pay = OrderStatusEnum::PAY;
  341. $model->order_status = BargainEnum::ORDER_SUCCESS;
  342. $model->payment_type = $payment_type;
  343. $model->pay_time = time();
  344. $res = $model->save();
  345. if ($res === false) throw new \Exception('修改订单失败:' . $model->getErrorMessage());
  346. $trans->commit();
  347. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, ['id' => $params['id'], 'out_trade_no' => $out_trade_no], self::class, 'handleSyncAddMainOrder');
  348. return $model;
  349. } catch (\Exception $e) {
  350. if (isset($trans)) $trans->rollback();
  351. self::$static_error = $e->getMessage();
  352. return false;
  353. }
  354. }
  355. /**
  356. * @desc:添加主订单,异步调用
  357. * @Author: hua
  358. * @Date: 2022/1/5
  359. * @Time: 14:48
  360. * @Copyright: copyright (c) 2021 广东七件事集团
  361. * @param $data
  362. */
  363. public static function handleSyncAddMainOrder($data)
  364. {
  365. $out_trade_no = $data['out_trade_no'];
  366. $bargain_order = BargainOrder::findOne($data['id']);
  367. $active = BargainActive::findOne(['mall_id' => $bargain_order->mall_id, 'id' => $bargain_order->bargain_active_id]);
  368. $t = Yii::$app->db->beginTransaction();
  369. try {
  370. $goods = Goods::findOne(['id' => $active->goods_id]);
  371. $goods_attr = GoodsAttr::findOne(['id' => $active->attr_id]);
  372. $marketing_type = BargainEnum::ADDONS_NAME;
  373. //成功砍价,往主订单写入数据
  374. $order_id = self::createMallOrder($bargain_order, $marketing_type, $goods, $goods_attr, $out_trade_no);
  375. $bargain_order->order_id = $order_id;
  376. $bargain_order->order_status = BargainEnum::ORDER_SUCCESS;
  377. $res = $bargain_order->save();
  378. if ($res == false) throw new \Exception('砍价成功回写主订id失败');
  379. $active->success += 1;
  380. $res = $active->save();
  381. if ($res == false) throw new \Exception('更新砍价活动失败');
  382. $t->commit();
  383. $mode_data = json_decode($active->mode_data, true);
  384. if (!empty($mode_data['commission_type'])){
  385. $list = \Yii::$app->services->setting->addons->get($bargain_order->mall_id, BargainEnum::ADDONS_NAME, 'basic');
  386. if(empty($list['grant_type'])||$list['grant_type']==1) self::giveReward(BargainOrder::tableName(), $data['id'], $active);
  387. }
  388. // 触发订单支付事件,事务提交完成后触发
  389. $user = User::findOne(['id' => $bargain_order->user_id]);
  390. $event = new \common\events\order\OrderPaidEvent($bargain_order->mall_id);
  391. $order['id'] = $order_id;
  392. $order['operator_id'] = $user['id']??0;
  393. $order['operator_name'] = $user['nickname'] ?? '';
  394. Yii::$app->services->events->dispatch($event, $order, $event->listeners);
  395. } catch (\Exception $e) {
  396. $t->rollBack();
  397. $exception = FormatHelper::exception($e, "订单支付触发砍价事件");
  398. echo $exception;
  399. Yii::error($exception);
  400. }
  401. }
  402. /**
  403. * @desc:生成主订单
  404. * @Author: hua
  405. * @Date: 2022/1/5
  406. * @Time: 14:49
  407. * @Copyright: copyright (c) 2021 广东七件事集团
  408. * @param $bargain_order
  409. * @param $marketing_type
  410. * @param $goods
  411. * @param $goods_attr
  412. * @param $out_trade_no
  413. * @return int
  414. * @throws \Exception
  415. */
  416. public static function createMallOrder($bargain_order, $marketing_type, $goods, $goods_attr, $out_trade_no = ''): int
  417. {
  418. $order = new Order();
  419. $order->loadDefaultValues();
  420. $order->load($bargain_order->toArray(), '');
  421. $order->mch_id = $goods->mch_id;
  422. $order->order_status = OrderStatusEnum::PAY;
  423. $order->marketing_id = $bargain_order->bargain_active_id;
  424. $order->marketing_type = $marketing_type;
  425. $order->goods_price = $bargain_order->bargain_price;
  426. $order->pay_money = $bargain_order->total_pay_price;
  427. $order->shipping_money = $bargain_order->shipping_money;
  428. $order->shipping_type = $bargain_order->shipping_type;
  429. $order->original_goods_price = $goods_attr->original_price;
  430. $order->pay_status = 1;
  431. $order->out_trade_no = $out_trade_no ?? '';
  432. $res = $order->save();
  433. if ($res == false) throw new \Exception('砍价成功生成主订单失败');
  434. self::createOrderDetail($bargain_order, $order->id, $goods, $goods_attr, $marketing_type);
  435. return $order->id;
  436. }
  437. /**
  438. * @desc:生成主订单详情
  439. * @Author: hua
  440. * @Date: 2022/1/5
  441. * @Time: 14:49
  442. * @Copyright: copyright (c) 2021 广东七件事集团
  443. * @param $bargain_order
  444. * @param $order_id
  445. * @param $goods
  446. * @param $goods_attr
  447. * @param $marketing_type
  448. * @throws \Exception
  449. */
  450. public static function createOrderDetail($bargain_order, $order_id, $goods, $goods_attr, $marketing_type)
  451. {
  452. // 订单详情
  453. $order_detail = new OrderDetail();
  454. $order_detail->loadDefaultValues();
  455. $order_detail->user_id = $bargain_order->user_id;
  456. $order_detail->mall_id = $bargain_order->mall_id;
  457. $order_detail->mch_id = $goods->mch_id;
  458. $order_detail->order_id = $order_id;
  459. $order_detail->goods_id = $goods->id;
  460. $order_detail->goods_attr_id = $goods_attr->id;
  461. $order_detail->goods_name = $goods->goods_name;
  462. $order_detail->goods_attr_name = $goods_attr->name;
  463. $order_detail->price = $bargain_order->price;
  464. $order_detail->cost_price = $goods_attr->cost_price;
  465. $order_detail->original_goods_price = floatval($goods_attr->original_price)?$goods_attr->original_price*$bargain_order->num:$bargain_order->price*$bargain_order->num;
  466. $order_detail->goods_price = $bargain_order->bargain_price;
  467. $order_detail->num = $bargain_order->num;
  468. $order_detail->pic_url = $goods->cover_pic;
  469. $order_detail->marketing_id = $bargain_order->bargain_active_id;
  470. $order_detail->marketing_type = $marketing_type;
  471. $order_detail->order_status = OrderStatusEnum::PAY;
  472. $order_detail->remark = $bargain_order->remark;
  473. //$order_detail->is_virtual = $goods->goods_type;
  474. $order_detail->is_virtual = $goods->goods_type == GoodsTypeEnum::GoodsTypeVirtual ? 1 : 0;
  475. $res = $order_detail->save();
  476. if ($res == false) throw new \Exception('砍价成功生成订单详情失败');
  477. }
  478. /**
  479. * @desc:赠送佣金
  480. * @Author: hua
  481. * @Date: 2022/1/5
  482. * @Time: 17:16
  483. * @Copyright: copyright (c) 2021 广东七件事集团
  484. * @param $source_table
  485. * @param $bargain_order_id
  486. * @param $active
  487. * @throws \Exception
  488. */
  489. public static function giveReward($source_table, $bargain_order_id, $active)
  490. {
  491. $insert_wallet = [];
  492. $list = BargainUserOrder::lists(['where' => [['bargain_order_id' => $bargain_order_id], ['status' => StatusEnum::ENABLED]]]);
  493. foreach ($list as $item) {
  494. if ($item['price']) {
  495. $item['price'] = bcmul($item['price'],1,2);
  496. $user_id = $item['user_id'];
  497. $desc = '用户(' . $user_id . '),获得砍价订单(' . $bargain_order_id . ')奖励,奖励类型:佣金,数量:' . $item['price'];
  498. $insert_wallet [] = ['mall_id' => $active->mall_id, 'user_id' => $user_id,
  499. 'is_frozen' => false, 'wallet_type' => 'commission', 'money' => $item['price'],
  500. 'desc' => $desc,
  501. 'source_table' => $source_table,
  502. 'source_table_id' => $bargain_order_id,
  503. 'from_type' => UserWalletEnum::FROM_BARGAIN,
  504. 'capital_type' => UserWalletEnum::GIVE,
  505. ];
  506. }
  507. }
  508. if (!empty($insert_wallet)) {
  509. UserWalletService::batchHandleByQueue($insert_wallet);
  510. }
  511. }
  512. /**
  513. * @desc:砍价时间到,结束
  514. * @Author: hua
  515. * @Date: 2022/1/5
  516. * @Time: 17:21
  517. * @Copyright: copyright (c) 2021 广东七件事集团
  518. * @param $params
  519. * @param false $force
  520. * @return BargainOrder|false
  521. * @throws \yii\db\Exception
  522. */
  523. public static function close($params, $force = false)
  524. {
  525. $trans = Yii::$app->db->beginTransaction();
  526. $stock_locks = [];
  527. try {
  528. $cond = ['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED]];
  529. isset($params['user_id']) && $cond['user_id'] = $params['user_id'];
  530. $model = self::findOne($cond);
  531. if (empty($model)) throw new \Exception('订单不存在或已删除');
  532. $active = BargainActive::findOne(['id' => $model['bargain_active_id']]);
  533. // 订单结束时间取活动结束时间 或者砍价最大时间
  534. $end_time = min($model->created_at + $active->time * 3600, $active->end_time);
  535. if($end_time > time()){
  536. throw new \Exception('还没到过期时间');
  537. }
  538. // 判断订单是否已经被关闭
  539. if ($model->order_status == BargainEnum::ORDER_FAILURE) throw new \Exception('订单已经关闭');
  540. // 判断是否是未支付的订单
  541. if ($force == false && $model->is_pay != 0) throw new \Exception('订单已经被处理');
  542. $model->order_status = BargainEnum::ORDER_FAILURE;
  543. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  544. self::rollBackStock($model, $stock_locks);//回退库存
  545. $trans->commit();
  546. LockHelper::batchUlock($stock_locks);
  547. return $model;
  548. } catch (\Exception $e) {
  549. $trans->rollback();
  550. LockHelper::batchUlock($stock_locks);
  551. self::$static_error = $e->getMessage();
  552. return false;
  553. }
  554. }
  555. /**
  556. * @desc:回退库存
  557. * @Author: hua
  558. * @Date: 2022/1/5
  559. * @Time: 17:28
  560. * @Copyright: copyright (c) 2021 广东七件事集团
  561. * @param $model
  562. * @param $stock_locks
  563. * @throws \Exception
  564. */
  565. public static function rollBackStock($model, &$stock_locks)
  566. {
  567. $lock_key = RedisKeyEnum::LOCK_BARGAIN_ACTIVE . $model->bargain_active_id;
  568. $identification = uniqid();
  569. if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new \Exception('当前访问人数过多');
  570. $stock_locks[$lock_key] = $identification;
  571. //操作商品库存-回退
  572. $res = BargainActive::handleStock($model->mall_id, $model->bargain_active_id, $model->num);
  573. if (!$res) throw new \Exception(Goods::getStaticError());
  574. }
  575. /**
  576. * @desc:分享详情
  577. * @Author: hua
  578. * @Date: 2022/1/5
  579. * @Time: 16:39
  580. * @Copyright: copyright (c) 2021 广东七件事集团
  581. * @param $bargain_order_id
  582. * @param $mall_id
  583. * @return array
  584. */
  585. public static function getShareDetail($bargain_order_id, $mall_id): array
  586. {
  587. $order = self::getOne([['id' => $bargain_order_id, 'mall_id' => $mall_id]], true, ['active' => function ($query) {
  588. $query->with(['goods']);
  589. }]);
  590. $data['item_id'] = $order['id'];
  591. $data['price'] = $order['price'];
  592. $data['min_price'] = $order['active']['min_price'];
  593. $data['share_title'] = $order['active']['goods']['goods_name'];
  594. $data['share_img'] = $order['active']['goods']['cover_pic'];
  595. $data['active_id'] = $order['bargain_active_id'];
  596. return $data;
  597. }
  598. public static function check($params): bool
  599. {
  600. $order_no_arr = $params['order_no_arr'];
  601. $payment_order_list = $params['payment_order_list'];
  602. $counts = BargainOrder::find()->where(['order_no' => $order_no_arr, 'is_pay' => 0])->count();
  603. if ($counts != count($payment_order_list)) {
  604. self::$static_error = '砍价订单不一致';
  605. return false;
  606. }
  607. return true;
  608. }
  609. }