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.

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