You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

791 lines
29 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. <?php
  2. namespace App\Service;
  3. use App\Commons\Log;
  4. use App\Constants\LogLabel;
  5. use App\Model\Coupon;
  6. use App\Model\CouponUserRec;
  7. use App\Model\CouponUserUse;
  8. use App\Model\Goods;
  9. use App\Model\Order;
  10. use App\Model\OrderGoods;
  11. use App\Model\OrderMain;
  12. use App\Model\OrderSalesStatistic;
  13. use App\Model\SpecCombination;
  14. use App\Model\Store;
  15. use Exception;
  16. use Hyperf\DbConnection\Db;
  17. use Hyperf\Snowflake\IdGeneratorInterface;
  18. use Hyperf\Utils\ApplicationContext;
  19. use Hyperf\Di\Annotation\Inject;
  20. class OrderService implements OrderServiceInterface
  21. {
  22. /**
  23. * @Inject
  24. * @var Log
  25. */
  26. protected $log;
  27. /**
  28. * @Inject
  29. * @var CouponServiceInterface
  30. */
  31. protected $couponService;
  32. /**
  33. * @Inject
  34. * @var PurchaseLimitServiceInterface
  35. */
  36. protected $purchaseLimitService;
  37. /**
  38. * @inheritDoc
  39. */
  40. public function addOnlineOrder($data)
  41. {
  42. bcscale(6);
  43. $dataMain = $data;
  44. Db::beginTransaction();
  45. try {
  46. // TODO 这个字段后续可能不用了,之前由达达订单号从前端传上来
  47. $dataMain['order_num'] = 'o'.date('YmdHis').mt_rand(1000,9999);
  48. // 计算当前订单可用红包优惠金额
  49. $couponMoney = 0;
  50. $receiveCouponIds = [];
  51. if (isset($data['receive_coupon_ids'])&&$data['receive_coupon_ids']) {
  52. $receiveCouponIds = explode(',', str_replace(',',',',$data['receive_coupon_ids']));
  53. $couponMoney = $this->getCouponAmount($receiveCouponIds, $data['money'], $data['user_id'], $data['market_id']);
  54. }
  55. $dataMain['yhq_money2'] = $couponMoney;
  56. // 获取分布式全局ID
  57. $generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class);
  58. $dataMain['global_order_id'] = $generator->generate();
  59. // 店铺IDs
  60. $dataMain['store_ids'] = '';
  61. $storeList = json_decode(html_entity_decode($data['store_list']), true);
  62. if (!is_array($storeList)||empty($storeList)) {
  63. Db::rollBack();
  64. return '订单中商品不存在或已失效';
  65. }
  66. // 获取商户IDs
  67. foreach ($storeList as &$item) {
  68. $dataMain['store_ids'] .= empty($dataMain['store_ids']) ? $item['store_id'] : ','.$item['store_id'];
  69. }
  70. // 主订单插入数据
  71. $currentTime = time();
  72. $dataMain['time'] = date('Y-m-d H:i:s', $currentTime);
  73. $dataMain['time_add'] = $currentTime;
  74. $dataMain['pay_time'] = '';
  75. $dataMain['state'] = OrderMain::ORDER_STATE_UNPAY;
  76. $dataMain['code'] = $dataMain['global_order_id'];
  77. $dataMain['jj_note'] = '';
  78. // 主订单模型保存
  79. $orderMain = OrderMain::create($dataMain);
  80. $orderMainId = $orderMain->id;
  81. // 统计订单中所有店铺当日订单数,做店铺订单序号
  82. $countsArr = Order::query()
  83. ->selectRaw('store_id, COUNT(*) AS count')
  84. ->whereIn('store_id', explode(',', $dataMain['store_ids']))
  85. ->where(['type' => OrderMain::ORDER_TYPE_ONLINE])
  86. ->whereBetween('time', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')])
  87. ->groupBy('store_id')
  88. ->get()
  89. ->toArray();
  90. $storeOrderCounts = [];
  91. foreach ($countsArr as $key => &$row) {
  92. $storeOrderCounts[$row['store_id']] = $row['count'];
  93. }
  94. // 循环处理订单总额、子订单总额、商品、商户订单等信息
  95. $orderAmountTotal = 0; # 总订单金额
  96. $orderGoods = [];
  97. foreach ($storeList as $key => &$item) {
  98. // 子订单数据处理
  99. $dataChild = [
  100. 'uniacid' => $data['uniacid'],
  101. 'order_num' => 's'.date('YmdHis', time()) . rand(1111, 9999),
  102. 'user_id' => $orderMain->user_id,
  103. 'store_id' => $item['store_id'],
  104. 'order_main_id' => $orderMainId,
  105. 'state' => OrderMain::ORDER_STATE_UNPAY,
  106. 'tel' => $orderMain->tel,
  107. 'name' => $orderMain->name,
  108. 'address' => $orderMain->address,
  109. 'area' => $orderMain->area,
  110. 'time' => date("Y-m-d H:i:s"),
  111. 'note' => $item['note'] ?? '',
  112. 'delivery_time' => $orderMain->delivery_time,
  113. 'type' => $orderMain->type,
  114. 'lat' => $orderMain->lat,
  115. 'lng' => $orderMain->lng,
  116. 'pay_type' => $orderMain->pay_type,
  117. 'order_type' => $orderMain->order_type,
  118. 'money' => floatval($item['subtotal']),
  119. 'box_money' => floatval($item['box_money']),
  120. 'mj_money' => floatval($item['mj_money']),
  121. 'yhq_money' => floatval($item['yhq_money']),
  122. 'yhq_money2' => floatval($item['yhq_money2']),
  123. 'zk_money' => floatval($item['zk_money']),
  124. 'coupon_id' => $item['coupon_id'],
  125. 'coupon_id2' => $item['coupon_id2'],
  126. 'xyh_money' => floatval($item['xyh_money']),
  127. 'oid' => (isset($storeOrderCounts[$item['store_id']]) ? $item['store_id'] : 0) + 1,
  128. 'time_add' => date("Y-m-d H:i:s"),
  129. 'jj_note' => '',
  130. 'form_id' => '',
  131. 'form_id2' => '',
  132. 'code' => '',
  133. ];
  134. $orderChildId = Order::query()->insertGetId($dataChild);
  135. // 子订单内商品处理
  136. $goodsAmountTotal = 0;
  137. if (!is_array($item['good_list'])||empty($item['good_list'])) {
  138. Db::rollBack();
  139. return '订单商品异常';
  140. }
  141. foreach ($item['good_list'] as &$goods) {
  142. $goodsAmount = bcadd(floatval($goods['money']), floatval($goods['box_money']));
  143. $goodsAmount = bcmul($goodsAmount, $goods['num']);
  144. $goodsAmountTotal = bcadd($goodsAmountTotal, $goodsAmount);
  145. $orderGoods[$goods['id']] = $goods;
  146. $orderGoods[$goods['id']]['uniacid'] = $data['uniacid'];
  147. $orderGoods[$goods['id']]['order_id'] = $orderChildId;
  148. $orderGoods[$goods['id']]['user_id'] = $dataMain['user_id'];
  149. $orderGoods[$goods['id']]['store_id'] = $item['store_id'];
  150. }
  151. // 子订单优惠总额
  152. $discountAmountTotal = bcadd($dataChild['mj_money'], $dataChild['yhq_money']);
  153. $discountAmountTotal = bcadd($discountAmountTotal, $dataChild['yhq_money2']);
  154. $discountAmountTotal = bcadd($discountAmountTotal, $dataChild['zk_money']);
  155. $discountAmountTotal = bcadd($discountAmountTotal, $dataChild['xyh_money']);
  156. $goodsAmountTotal = bcsub($goodsAmountTotal, $discountAmountTotal, 2);
  157. $orderAmountTotal = bcadd($orderAmountTotal, $goodsAmountTotal, 2);
  158. // 校验子订单金额
  159. if ($goodsAmountTotal != $dataChild['money']) {
  160. Db::rollBack();
  161. return '店铺订单总金额错误';
  162. }
  163. }
  164. // 校验库存
  165. foreach ($orderGoods as $Key => &$goodsItem) {
  166. $goodsItem['combination_id'] = intval($goodsItem['combination_id']);
  167. // 存在规格,则去规格处查库存
  168. $goods = [];
  169. if ($goodsItem['combination_id'] > 0) {
  170. $combination = SpecCombination::query()
  171. ->select(['good_id AS id', 'number AS inventory'])
  172. ->where(['id' => $goodsItem['combination_id']])
  173. ->first()
  174. ->toArray();
  175. $goods = Goods::query()
  176. ->select(['id', 'name', 'is_max'])
  177. ->where(['id' => $combination['id']])
  178. ->first()
  179. ->toArray();
  180. $goods['inventory'] = $combination['inventory'];
  181. } else {
  182. $goods = Goods::query()
  183. ->select(['id', 'name', 'is_max', 'inventory'])
  184. ->where(['id' => $goodsItem['good_id']])
  185. ->first()
  186. ->toArray();
  187. }
  188. if (!$goods) {
  189. Db::rollBack();
  190. return '缺少商品';
  191. }
  192. if($goodsItem['num'] > $goods['inventory'] && $goods['is_max'] != Goods::INVENTORY_NOLIMIT){
  193. Db::rollBack();
  194. return '商品 '.$goods->name.' 库存不足!';
  195. }
  196. }
  197. // 校验总订单金额
  198. $deliveryAmount = 0; # 配送费用
  199. if($dataMain['order_type'] == OrderMain::ORDER_TYPE_ONLINE){
  200. $deliveryAmount = $dataMain['dada_fee'];
  201. }
  202. $orderAmountTotal = bcadd($orderAmountTotal, $deliveryAmount);
  203. # 总订单优惠总额
  204. $discountAmountTotal = bcadd($dataMain['mj_money'], $dataMain['yhq_money']);
  205. $discountAmountTotal = bcadd($discountAmountTotal, $dataMain['yhq_money2']);
  206. $discountAmountTotal = bcadd($discountAmountTotal, $dataMain['zk_money']);
  207. $discountAmountTotal = bcadd($discountAmountTotal, $dataMain['xyh_money']);
  208. $orderAmountTotal = bcsub($orderAmountTotal, $discountAmountTotal, 2);
  209. if ($orderAmountTotal != bcsub(bcadd($dataMain['money'], $deliveryAmount), $discountAmountTotal, 2)) {
  210. Db::rollBack();
  211. return '订单总金额错误';
  212. }
  213. // 添加订单商品
  214. $tempGoods = $orderGoods;
  215. $orderGoods = [];
  216. foreach ($tempGoods as $key => &$value) {
  217. $goodsTemp['good_id'] = $value['good_id'];
  218. $goodsTemp['img'] = $value['logo'];
  219. $goodsTemp['number'] = $value['num'];
  220. $goodsTemp['order_id'] = $value['order_id'];
  221. $goodsTemp['name'] = $value['name'];
  222. $goodsTemp['money'] = $value['money'];
  223. $goodsTemp['dishes_id'] = $value['dishes_id'];
  224. $goodsTemp['spec'] = $value['spec'];
  225. $goodsTemp['is_qg'] = $value['is_qg'];
  226. $goodsTemp['good_unit'] = $value['good_unit'];
  227. $goodsTemp['uniacid'] = $value['uniacid'];
  228. $goodsTemp['combination_id'] = $value['combination_id'];
  229. $orderGoods[] = $goodsTemp;
  230. }
  231. $addOrderGoods = OrderGoods::query()->insert($orderGoods);
  232. if (!$addOrderGoods) {
  233. Db::rollBack();
  234. return '订单商品异常';
  235. }
  236. //判断是否有购买特价商品
  237. $this->purchaseLimitService->ssdbPurchaseRecord($orderGoods,$data['user_id'],$dataMain['global_order_id']);
  238. // 修改总订单金额,金额是计算来的
  239. // TODO 这部分其实可以结合处理优化一下,循环前后关联处理太多
  240. $updateOrderMain = OrderMain::query()->where(['id' => $orderMainId])->update(['money' => $orderAmountTotal, 'total_money' => $dataMain['money']]);
  241. if (!$updateOrderMain) {
  242. Db::rollBack();
  243. return '订单总金额记录失败';
  244. }
  245. // 处理红包的使用
  246. $canUseCoupons = CouponUserRec::select(['id', 'user_id', 'number', 'number_remain', 'system_coupon_user_id'])
  247. ->whereIn('id', $receiveCouponIds)
  248. ->get()->toArray();
  249. if (is_array($canUseCoupons)&&!empty($canUseCoupons)) {
  250. # 使用记录、更新当前优惠券
  251. foreach ($canUseCoupons as $key => &$coupon) {
  252. $couponUse = [
  253. 'user_id' => $coupon['user_id'],
  254. 'user_receive_id' => $coupon['id'],
  255. 'system_coupon_id' => $coupon['system_coupon_user_id'],
  256. 'order_main_id' => $orderMainId,
  257. 'use_time' => $currentTime,
  258. 'return_time' => 0,
  259. 'number' => 1,
  260. 'status' => 1,
  261. 'update_time' => 0,
  262. ];
  263. var_dump('$couponUse',$couponUse);
  264. $insertRes = CouponUserUse::query()->insert($couponUse);
  265. if ($insertRes) {
  266. $numberRemain = $coupon['number_remain'] - 1;
  267. if ($numberRemain == 0) {
  268. $status = 2;
  269. } elseif ($numberRemain > 0 && $numberRemain < $coupon['number']) {
  270. $status = 1;
  271. } elseif ($numberRemain == $coupon['number']) {
  272. $status = 0;
  273. }
  274. $upRes = CouponUserRec::query()->where(['id' => $coupon['id']])->update(['number_remain' => $numberRemain, 'status' => $status]);
  275. if (!$upRes) {
  276. Db::rollBack();
  277. return '优惠券使用失败';
  278. }
  279. // 缓存使用记录
  280. $usedRes = $this->couponService->cacheTodayCouponUsed($coupon['user_id'], $coupon['system_coupon_user_id'], $coupon['id']);
  281. if (!$usedRes) {
  282. Db::rollBack();
  283. return '优惠券使用失败';
  284. }
  285. } else {
  286. Db::rollBack();
  287. return '优惠券使用失败';
  288. }
  289. }
  290. }
  291. Db::commit();
  292. return $orderMainId;
  293. } catch (Exception $e) {
  294. $this->log->event(
  295. LogLabel::ORDER_LOG,
  296. ['message' => $e->getMessage()]
  297. );
  298. Db::rollBack();
  299. return $e->getMessage();
  300. }
  301. }
  302. /**
  303. * @inheritDoc
  304. */
  305. public function addOfflineOrder($data)
  306. {
  307. Db::beginTransaction();
  308. try {
  309. // 主订单数据
  310. $dataMain = [];
  311. // 获取分布式全局ID
  312. $generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class);
  313. $globalRrderId = $generator->generate();
  314. // 主订单插入数据
  315. $currentTime = time();
  316. $dataMain = [
  317. 'delivery_no' => '',
  318. 'dada_fee' => 0,
  319. 'market_id' => 0,
  320. 'box_money' => 0,
  321. 'ps_money' => 0,
  322. 'mj_money' => 0,
  323. 'xyh_money' => 0,
  324. 'yhq_money' => 0,
  325. 'yhq_money2' => 0,
  326. 'zk_money' => 0,
  327. 'tel' => '',
  328. 'name' => '',
  329. 'address' => '',
  330. 'area' => '',
  331. 'lat' => '',
  332. 'lng' => '',
  333. 'note' => '',
  334. 'form_id' => '',
  335. 'form_id2' => '',
  336. 'delivery_time' => '',
  337. 'order_type' => 0,
  338. 'coupon_id' => 0,
  339. 'coupon_id2' => 0,
  340. 'store_list' => '',
  341. 'receive_coupon_ids' => '',
  342. 'type' => OrderMain::ORDER_TYPE_OFFLINE,
  343. 'time' => date('Y-m-d H:i:s', $currentTime),
  344. 'time_add' => $currentTime,
  345. 'pay_time' => '',
  346. 'pay_type' => OrderMain::ORDER_PAY_WX,
  347. 'state' => OrderMain::ORDER_STATE_UNPAY,
  348. 'dm_state' => OrderMain::ORDER_STATE_UNPAY,
  349. 'code' => $globalRrderId,
  350. 'jj_note' => '',
  351. 'uniacid' => 2,
  352. 'order_num' => 'dm'.date('YmdHis') . mt_rand(1000, 9999),
  353. 'money' => $data['money'],
  354. 'user_id' => $data['user_id'],
  355. 'store_ids' => $data['store_id'],
  356. 'global_order_id' => $globalRrderId,
  357. ];
  358. // 主订单模型保存
  359. $orderMain = OrderMain::create($dataMain);
  360. $orderMainId = $orderMain->id;
  361. // 子订单模型保存
  362. $dataChild = [
  363. 'uniacid' => 1,
  364. 'order_num' => 's'.date('YmdHis') . mt_rand(1000, 9999),
  365. 'user_id' => $orderMain->user_id,
  366. 'store_id' => $data['store_id'],
  367. 'order_main_id' => $orderMainId,
  368. 'state' => OrderMain::ORDER_STATE_UNPAY,
  369. 'dm_state' => OrderMain::ORDER_STATE_UNPAY,
  370. 'tel' => $orderMain->tel,
  371. 'name' => $orderMain->name,
  372. 'address' => $orderMain->address,
  373. 'area' => $orderMain->area,
  374. 'time' => date("Y-m-d H:i:s"),
  375. 'note' => '',
  376. 'delivery_time' => $orderMain->delivery_time,
  377. 'type' => $orderMain->type,
  378. 'lat' => $orderMain->lat,
  379. 'lng' => $orderMain->lng,
  380. 'pay_type' => $orderMain->pay_type,
  381. 'order_type' => $orderMain->order_type,
  382. 'money' => $data['money'],
  383. 'box_money' => 0,
  384. 'mj_money' => 0,
  385. 'yhq_money' => 0,
  386. 'yhq_money2' => 0,
  387. 'zk_money' => 0,
  388. 'coupon_id' => 0,
  389. 'coupon_id2' => 0,
  390. 'xyh_money' => 0,
  391. 'time_add' => date("Y-m-d H:i:s"),
  392. 'jj_note' => '',
  393. 'form_id' => '',
  394. 'form_id2' => '',
  395. 'code' => '',
  396. ];
  397. $orderChildId = Order::query()->insertGetId($dataChild);
  398. Db::commit();
  399. return $orderMainId;
  400. } catch (Exception $e) {
  401. $this->log->event(
  402. LogLabel::ORDER_LOG,
  403. ['message' => $e->getMessage()]
  404. );
  405. Db::rollBack();
  406. return '购买失败';
  407. }
  408. }
  409. /**
  410. * 计算和校验当前订单可用红包及金额
  411. * @param $couponIds
  412. * @param $orderAmount
  413. * @param $userId
  414. * @param $marketId
  415. * @return int|string
  416. * @throws Exception
  417. */
  418. protected function getCouponAmount($couponIds, $orderAmount, $userId, $marketId)
  419. {
  420. // 用户当前订单可用优惠券
  421. $couponsCanUse = $this->couponService->getOrderCanUseCoupons(
  422. $orderAmount,
  423. $marketId,
  424. $userId,
  425. [
  426. 'receive.id',
  427. 'receive.user_id',
  428. 'receive.number',
  429. 'receive.number_remain',
  430. 'receive.system_coupon_user_id',
  431. 'coupon.discounts',
  432. 'coupon.discount_type',
  433. ]
  434. );
  435. $couponCanUseIds = array_column($couponsCanUse, 'id');
  436. $couponCanUseIds = array_intersect($couponCanUseIds, $couponIds);
  437. $couponCannotUseIds = array_diff($couponIds, $couponCanUseIds);
  438. if (empty($couponCanUseIds)||!empty($couponCannotUseIds)) {
  439. throw new Exception('您的订单中有优惠券已经失效');
  440. }
  441. // 计算红包折扣金额
  442. $couponMoney = 0;
  443. foreach ($couponsCanUse as $key => $coupon) {
  444. if (!in_array($coupon->id, $couponIds)) {
  445. continue;
  446. }
  447. if ($coupon->discount_type == Coupon::DISCOUNT_TYPE_CASH) {
  448. $couponMoney = bcadd($couponMoney, $coupon->discounts, 2);
  449. } elseif ($coupon->discount_type == Coupon::DISCOUNT_TYPE_RATE) {
  450. $discountRate = bcdiv($coupon->discounts,10);
  451. $discountRate = bcsub(1,$discountRate);
  452. $discountMoney = bcmul($orderAmount, $discountRate);
  453. $couponMoney = bcadd($couponMoney, $discountMoney, 2);
  454. }
  455. }
  456. return $couponMoney;
  457. }
  458. /**
  459. * @inheritDoc
  460. */
  461. public function existsByGlobalOrderId($global_order_id)
  462. {
  463. return OrderMain::query()->where(['order_num' => $global_order_id])->value('id');
  464. }
  465. /**
  466. * @inheritDoc
  467. */
  468. public function onlineCompleted($global_order_id)
  469. {
  470. Db::beginTransaction();
  471. try {
  472. // 主订单状态更新
  473. $orderMain = OrderMain::query()
  474. ->where(['global_order_id' => $global_order_id, 'state' => OrderMain::ORDER_STATE_DELIVERY])
  475. ->first();
  476. if (empty($orderMain)) {
  477. Db::rollBack();
  478. return false;
  479. }
  480. $orderMain->state = OrderMain::ORDER_STATE_COMPLETE;
  481. $orderMain->save();
  482. // 子订单状态更新
  483. $upChild = Order::query()
  484. ->where(['order_main_id' => $orderMain->id])
  485. ->update(['state' => OrderMain::ORDER_STATE_COMPLETE]);
  486. Db::commit();
  487. return true;
  488. } catch (Exception $e) {
  489. $this->log->event(LogLabel::ONLINE_COMPLETE_LOG, ['exception' => $e->getMessage()]);
  490. Db::rollBack();
  491. return false;
  492. }
  493. }
  494. /**
  495. * @inheritDoc
  496. */
  497. public function onlinePaid($global_order_id)
  498. {
  499. Db::beginTransaction();
  500. try {
  501. // 查询订单
  502. $orderMain = OrderMain::query()
  503. ->where([
  504. 'global_order_id' => $global_order_id,
  505. 'type' => OrderMain::ORDER_TYPE_ONLINE
  506. ])
  507. ->first();
  508. // 修改订单、子订单状态
  509. $currentTime = time();
  510. $orderMain->state = OrderMain::ORDER_STATE_UNTAKE;
  511. $orderMain->time_pay = $currentTime;
  512. $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
  513. $orderMain->save();
  514. $upOrder = Order::query()
  515. ->where(['order_main_id' => $orderMain->id])
  516. ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]);
  517. // 更新商户销量
  518. $upStoreScore = Store::query()
  519. ->whereIn('id', explode(',', $orderMain->store_ids))
  520. ->update(['score' => Db::raw('score+1')]);
  521. // 更新商品库存和销量
  522. $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
  523. ->where(['order_main_id' => $orderMain->id])
  524. ->get()
  525. ->toArray();
  526. $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id'])
  527. ->whereIn('order_id', array_values(array_column($orders, 'id')))
  528. ->get()
  529. ->toArray();
  530. foreach ($orderGoods as $key => &$goodsItem) {
  531. $goods = Goods::find($goodsItem['id']);
  532. // 库存处理,有规格
  533. if ($goodsItem['combination_id']) {
  534. $combination = SpecCombination::find($goodsItem['combination_id']);
  535. $combination->number = $combination->number - $goodsItem['number'];
  536. $combination->save();
  537. } else {
  538. $goods->inventory = $goods->inventory - $goodsItem['number'];
  539. }
  540. $goods->sales = $goods->sales - $goodsItem['number'];
  541. $goods->save();
  542. }
  543. // 月销流水
  544. $statistics = [];
  545. foreach ($orders as $key => &$order) {
  546. $statistics[] = [
  547. 'money' => $order['money'],
  548. 'user_id' => $order['user_id'],
  549. 'store_id' => $order['store_id'],
  550. 'market_id' => $orderMain->market_id,
  551. 'order_id' => $order['id'],
  552. 'createtime' => strtotime($order['pay_time']),
  553. ];
  554. }
  555. if (is_array($statistics) && !empty($statistics)) {
  556. $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics);
  557. }
  558. Db::commit();
  559. return true;
  560. } catch (Exception $e) {
  561. $this->log->event(LogLabel::ONLINE_PAID_LOG, ['exception' => $e->getMessage()]);
  562. Db::rollBack();
  563. return false;
  564. }
  565. }
  566. /**
  567. * @inheritDoc
  568. */
  569. public function offlinePaid($global_order_id)
  570. {
  571. Db::beginTransaction();
  572. try {
  573. // 主订单状态更新
  574. $orderMain = OrderMain::query()
  575. ->where(['global_order_id' => $global_order_id, 'type' => OrderMain::ORDER_TYPE_OFFLINE])
  576. ->first();
  577. if (empty($orderMain)) {
  578. $this->log->event(
  579. LogLabel::PAY_NOTIFY_WXMINI,
  580. ['order_not_found' => $global_order_id]
  581. );
  582. Db::rollBack();
  583. return false;
  584. }
  585. $currentTime = time();
  586. $orderMain->state = OrderMain::ORDER_STATE_UNTAKE;
  587. $orderMain->dm_state = OrderMain::ORDER_STATE_UNTAKE;
  588. $orderMain->time_pay = $currentTime;
  589. $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
  590. $orderMain->save();
  591. // 子订单状态更新
  592. $upOrder = Order::query()
  593. ->where(['order_main_id' => $orderMain->id])
  594. ->update([
  595. 'state' => OrderMain::ORDER_STATE_UNTAKE,
  596. 'dm_state' => OrderMain::ORDER_STATE_UNTAKE,
  597. 'pay_time' => date('Y-m-d H:i:s', $currentTime)
  598. ]);
  599. Db::commit();
  600. return true;
  601. } catch (Exception $e) {
  602. $this->log->event(LogLabel::OFFLINE_PAID_LOG, ['exception' => $e->getMessage()]);
  603. Db::rollBack();
  604. return false;
  605. }
  606. }
  607. /**
  608. * @inheritDoc
  609. */
  610. public function onlineCancel($order_id){
  611. OrderMain::where('id',$order_id)
  612. ->update(['state' => OrderMain::ORDER_STATE_CANCEL]);
  613. //撤销redis 用券记录
  614. $res = $this->couponService->refundOrderCoupons($order_id);
  615. //撤销特价商品购买记录
  616. $res = $this->purchaseLimitService->delSsdbPurchaseRecord($order_id);
  617. return $res;
  618. }
  619. /**
  620. * @inheritDoc
  621. */
  622. public function onlineRefund($global_order_id){
  623. Db::beginTransaction();
  624. try {
  625. $time = time();
  626. // 主订单状态更新
  627. $orderMain = OrderMain::query()
  628. ->where(['global_order_id' => $global_order_id, 'state' => OrderMain::ORDER_STATE_DELIVERY])
  629. ->first();
  630. if (empty($orderMain)) {
  631. Db::rollBack();
  632. return false;
  633. }
  634. $orderMain->state = OrderMain::ORDER_STATE_REFUNDED;
  635. $upOrderMain = $orderMain->save();
  636. // 子订单状态更新
  637. $upChild = Order::query()
  638. ->where(['order_main_id' => $orderMain->id])
  639. ->update(['state' => OrderMain::ORDER_STATE_REFUNDED]);
  640. /* 退还优惠券 */
  641. // 先查询是否正常使用优惠券
  642. // 修改状态,退还领取记录库存,删除ssdb缓存
  643. $couponUses = CouponUserUse::query()
  644. ->select('id','system_coupon_id','user_id','number','user_receive_id')
  645. ->where('order_main_id',$orderMain->id)
  646. ->where('status',CouponUserUse::COUPON_USE_STATE_USED)
  647. ->select();
  648. if(!empty($couponUse)){
  649. foreach($couponUses as $use){
  650. $use->status = CouponUserUse::COUPON_USE_STATE_USED;
  651. $use->return_time = $time;
  652. $use->update_time = $time;
  653. $use->save();
  654. $couponReceive = CouponUserRec::query()
  655. ->where('id',$use->user_receive_id)
  656. ->whereRaw('number >= number_remain+'.$use->number)
  657. ->update([
  658. 'number_remain' => Db::raw('number_remain+'.$use->number),
  659. 'status' => Db::raw('IF(number=number_remain,' . CouponUserRec::STATE_UNUSED . ',' . CouponUserRec::STATE_SOME . ')'),
  660. 'update_time' => $time
  661. ]);
  662. $clearUseRedis = $this->couponService->clearTodayCouponUsed($use->user_id,$use->system_coupon_id);
  663. }
  664. }
  665. // 退还订单金额到用户微信余额
  666. Db::commit();
  667. return true;
  668. } catch (Exception $e) {
  669. $this->log->event(LogLabel::ORDER_LOG, ['msg'=> '订单退款','exception' => $e->getMessage()]);
  670. Db::rollBack();
  671. return false;
  672. }
  673. }
  674. }