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.

820 lines
30 KiB

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