OrderService.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. <?php
  2. namespace app\common\service;
  3. use think\Cache;
  4. use think\Db;
  5. use think\Log;
  6. use app\common\model\Orders;
  7. use app\common\traits\ServiceTrait;
  8. use think\Exception;
  9. class OrderService
  10. {
  11. use ServiceTrait;
  12. /** @var Orders */
  13. public static $Model = Orders::class;
  14. const LOCK_ORDER_PREFIX = 'lock_order_cache:'; //重复创建订单锁
  15. //订单状态
  16. const ORDER_STATUS_NO = 0; //关闭
  17. const ORDER_STATUS_WAIT_PAY = 10; //待付款
  18. const ORDER_STATUS_WAIT_SHIP = 20; //已支付(待发货)
  19. const ORDER_STATUS_SHIPPED = 30; //已发货(待收货)
  20. const ORDER_STATUS_FAILED = 31; //交易失败
  21. const ORDER_STATUS_TIMEOUT = 33; //订单超时
  22. const ORDER_STATUS_FINISHED = 40; //已完成
  23. const ORDER_STATUS_CANCEL = 50; //已取消
  24. const ORDER_STATUS_REFUNDED = 60; //已退款
  25. const ORDER_STATUS_MAP = [
  26. self::ORDER_STATUS_NO => '订单关闭',
  27. self::ORDER_STATUS_WAIT_PAY => '待支付',
  28. self::ORDER_STATUS_WAIT_SHIP => '待发货',
  29. self::ORDER_STATUS_SHIPPED => '已发货',
  30. self::ORDER_STATUS_FAILED => '交易失败',
  31. self::ORDER_STATUS_TIMEOUT => '订单超时',
  32. self::ORDER_STATUS_CANCEL => '用户取消订单',
  33. self::ORDER_STATUS_FINISHED => '交易完成',
  34. self::ORDER_STATUS_REFUNDED => '已退款',
  35. ];
  36. // 订单操作按钮
  37. const BUTTON_PAY = 1; // 付款
  38. const BUTTON_CANCEL = 2; // 取消订单
  39. const BUTTON_CONFIRM = 3; // 确认收货
  40. const BUTTON_APPLY_REFUND = 4; // 申请售后
  41. const BUTTON_VIEW_REFUND = 5; // 查看退款
  42. const BUTTON_COMMENT = 6; // 评价
  43. const BUTTON_DELETE = 7; // 删除订单
  44. const BUTTON_DELIVERY = 8; // 查看物流
  45. const BUTTON_REBUY = 9; // 再次购买
  46. const BUTTON_INVITE_GROUPON = 11; //邀请好友拼团
  47. const BUTTON_MAP = [
  48. self::BUTTON_PAY => '付款', // 付款
  49. self::BUTTON_CANCEL => '取消订单', // 取消订单
  50. self::BUTTON_CONFIRM => '确认收货', // 确认收货
  51. self::BUTTON_APPLY_REFUND => '申请售后', // 申请售后
  52. self::BUTTON_VIEW_REFUND => '查看退款', // 查看退款
  53. self::BUTTON_COMMENT => '评价', // 评价
  54. self::BUTTON_DELETE => '删除订单', // 删除订单
  55. self::BUTTON_DELIVERY => '查看物流', // 查看物流
  56. self::BUTTON_REBUY => '再次购买', // 再次购买
  57. self::BUTTON_INVITE_GROUPON => '邀请好友拼团', //邀请好友拼团
  58. ];
  59. const ORDER_TYPE_SOFTWARE = 0;//软件产品;
  60. const ORDER_TYPE_FIRST_PAYMENT = 1;//首付款款订单;
  61. const ORDER_TYPE_FINAL_PAYMENT = 2; //尾款订单;
  62. const ORDER_TYPE_MAP = [
  63. self::ORDER_TYPE_SOFTWARE => '软件产品',
  64. self::ORDER_TYPE_FIRST_PAYMENT => '需求首付款',
  65. self::ORDER_TYPE_FINAL_PAYMENT => '需求尾款',
  66. ];
  67. /**
  68. * 生成订单
  69. * @param $requestData
  70. * @return array
  71. * @throws \Exception
  72. */
  73. public static function createOrder($requestData)
  74. {
  75. try {
  76. $user = $requestData['userInfo'] ?? [];
  77. $userId = $user['id'] ?? 0;
  78. $openid = $user['openid'] ?? '';
  79. Log::info('创建订单数据-request:' . json_encode($requestData, JSON_UNESCAPED_UNICODE));
  80. if (empty($requestData['goodsRequestList'])) {
  81. throw new \Exception('订单数据错误');
  82. }
  83. //如果30秒内有重复数据,直接返回缓存订单,不再创建
  84. $lockOrderKey = self::getLockOrderKey($userId, $requestData);
  85. if ($lockOrderRes = Cache::get($lockOrderKey)) {
  86. return json_decode($lockOrderRes, true);
  87. }
  88. $goodsRequestList = $requestData['goodsRequestList'];
  89. $count = count($goodsRequestList);
  90. if ($count == 0) {
  91. Log::error('订单创建失败:商品数量不能为0');
  92. throw new \Exception('订单创建失败:商品数量不能为0');
  93. }
  94. $total_amount = 0;
  95. $total_quantity = 0;
  96. $goodsDataList = [];
  97. foreach ($goodsRequestList as $item) {
  98. $quantity = max(1, $item['quantity']);
  99. $total_quantity += $quantity;
  100. $total_amount += $quantity * $item['price'];
  101. $goodsDataList[] = [
  102. 'spu_id' => $item['spuId'],
  103. 'sku_id' => $item['sku_id'] ?? '',
  104. 'goods_name' => $item['goodsName'],
  105. 'goods_picture_url' => $item['primaryImage'],
  106. 'origin_price' => $item['price'],
  107. 'actual_price' => $item['price'],
  108. 'buy_quantity' => $quantity,
  109. 'item_total_amount' => $item['price'] * $quantity,
  110. 'item_discount_amount' => 0,
  111. 'item_payment_amount' => $item['price'] * $quantity,
  112. 'goods_payment_price' => $item['price'],
  113. ];
  114. }
  115. $orderData = [
  116. 'user_id' => $userId,
  117. 'store_id' => 1,
  118. 'order_no' => generate_order_sn(),
  119. 'order_status' => OrderService::ORDER_STATUS_WAIT_PAY,
  120. 'order_type' => 0,
  121. 'total_amount' => $total_amount,
  122. 'payment_amount' => $total_amount,
  123. 'goods_amount' => $total_quantity,
  124. 'discount_amount' => 0,
  125. 'remark' => $requestData['storeInfoList'][0]['remark'] ?? '',
  126. ];
  127. $existed = OrderService::getOne(['order_no' => $orderData['order_no']]);
  128. if (!$existed) {
  129. //创建订单及订单商品
  130. $orderRes = self::$Model::create($orderData);
  131. Log::info('创建订单数据:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  132. if (!$orderRes) {
  133. Log::error('创建订单创建失败:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  134. throw new \Exception('订单创建失败');
  135. }
  136. $goodsRes = $orderRes->orderGoods()->saveAll($goodsDataList);
  137. if (!$goodsRes) {
  138. Log::error('创建订单产品失败:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  139. throw new \Exception('订单创建数据失败');
  140. }
  141. }
  142. $orderData += [
  143. 'channel' => 'wechat',
  144. 'tradeNo' => $orderData['order_no'],
  145. 'interactId' => 0,
  146. 'transactionId' => 0,
  147. 'payInfo' => self::pay($orderData['order_no'], $total_amount, $openid), //统一下单接口
  148. ];
  149. //存入缓存
  150. Cache::set($lockOrderKey, json_encode($orderData), 30);
  151. return $orderData;
  152. } catch (Exception $e) {
  153. throw new \Exception('订单数据保存失败:' . $e->getMessage());
  154. }
  155. }
  156. /**
  157. * 生成需求订单
  158. * @param $requestData
  159. * @throws \Exception
  160. */
  161. public static function createDemandOrder($requestData)
  162. {
  163. try {
  164. $demandId = $requestData['demandId'] ?? 0;
  165. $formData = $requestData['formData'] ?? [];
  166. $totalCost = $formData['totalCost'] ?? 0;
  167. Log::info('创建需求订单数据-request:' . json_encode($requestData, JSON_UNESCAPED_UNICODE));
  168. $demand = DemandService::getOne(['id' => $demandId]);
  169. if (!$demand) {
  170. throw new \Exception('该需求不存在');
  171. }
  172. $winBid = DemandBiddingService::getOne(['demand_id' => $demandId, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN]);
  173. $orderInfo = self::where(['parent_order_no' => $demand->parent_order_no])->find();
  174. $ratio = 0.5; //分期比率50%
  175. if (!$orderInfo) {
  176. $installments = 2;//分期数
  177. for ($i = 1; $i <= $installments; $i++) {
  178. $total_amount = $i == 1 ? $totalCost * $ratio : $totalCost * (1 - $ratio);
  179. $goodsDataList = [[
  180. 'spu_id' => 0,
  181. 'sku_id' => 0,
  182. 'goods_name' => '需求签约-' . ($i == 1 ? '首付款' : '尾款') . $demand->parent_order_no,
  183. 'goods_picture_url' => 'https://soft-market.oss-cn-shenzhen.aliyuncs.com/images/contract.png',
  184. 'origin_price' => $total_amount,
  185. 'actual_price' => $total_amount,
  186. 'buy_quantity' => 1,
  187. 'item_total_amount' => $total_amount,
  188. 'item_discount_amount' => 0,
  189. 'item_payment_amount' => $total_amount,
  190. 'goods_payment_price' => $total_amount,
  191. ]];
  192. $orderData = [
  193. 'user_id' => $demand->user_id,
  194. 'store_id' => 1,
  195. 'parent_order_no' => $demand->parent_order_no,
  196. 'order_no' => generate_order_sn(),
  197. 'order_status' => OrderService::ORDER_STATUS_WAIT_PAY,
  198. 'order_type' => $i,
  199. 'total_amount' => $total_amount,
  200. 'payment_amount' => $total_amount,
  201. 'goods_amount' => $total_amount,
  202. 'discount_amount' => 0,
  203. 'remark' => '',
  204. ];
  205. $existed = OrderService::getOne(['order_no' => $orderData['order_no']]);
  206. if (!$existed) {
  207. //创建订单及订单商品
  208. $orderRes = self::$Model::create($orderData);
  209. Log::info('创建需求订单数据:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  210. if (!$orderRes) {
  211. Log::error('创建需求订单创建失败:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  212. throw new \Exception('需求订单创建失败');
  213. }
  214. $goodsRes = $orderRes->orderGoods()->saveAll($goodsDataList);
  215. if (!$goodsRes) {
  216. Log::error('创建需求订单产品失败:' . json_encode($orderData, JSON_UNESCAPED_UNICODE));
  217. throw new \Exception('需求订单创建数据失败');
  218. }
  219. }
  220. }
  221. }
  222. //查找签约记录,没有则创建
  223. $contractInfo = ContractService::getOne(['demand_id' => $demand, 'bidding_id' => $winBid->id ?? 0]);
  224. if (!$contractInfo) {
  225. //创建合同数据
  226. $firstContract = ContractService::getFirstContract($demandId);
  227. $depositAmount = $firstContract ? $firstContract->deposit_amount : $formData['totalCost'] * $ratio;
  228. ContractService::createData($demandId, $winBid->id ?? 0, $depositAmount, $formData);
  229. }
  230. return $contractInfo;
  231. } catch (Exception $e) {
  232. throw new \Exception('需求订单数据保存失败:' . $e->getMessage());
  233. }
  234. }
  235. public static function getDemandOrder($parentOrderNo, $contractType)
  236. {
  237. $res = self::getOne(['parent_order_no' => $parentOrderNo, 'order_type' => $contractType], ['orderGoods', 'orderPayment']);
  238. return $res;
  239. }
  240. public static function orderPay($requestData)
  241. {
  242. try {
  243. $user = $requestData['userInfo'] ?? [];
  244. $userId = $user['id'] ?? 0;
  245. $openid = $user['openid'] ?? '';
  246. $orderNo = $requestData['orderNo'] ?? '';
  247. if (!$orderNo) {
  248. throw new \Exception('订单号不存在');
  249. }
  250. $fields = 'user_id,store_id,order_no,order_status,order_type,total_amount,payment_amount,goods_amount,discount_amount,remark';
  251. $orderInfo = OrderService::where(['order_no' => $orderNo, 'user_id' => $userId])->field($fields)->find();
  252. if (!$orderInfo) {
  253. throw new \Exception('该订单不存在');
  254. }
  255. $orderData = $orderInfo->toArray();
  256. $orderData += [
  257. 'channel' => 'wechat',
  258. 'tradeNo' => $orderData['order_no'],
  259. 'interactId' => 1,
  260. 'transactionId' => 0,
  261. 'payInfo' => self::pay($orderInfo->order_no, $orderInfo->total_amount, $openid), //统一下单接口
  262. ];
  263. return $orderData;
  264. } catch (Exception $e) {
  265. throw new \Exception('订单支付异常:' . $e->getMessage());
  266. }
  267. }
  268. /**
  269. * 订单操作
  270. * @param $request
  271. * @return mixed
  272. * @throws \Exception
  273. */
  274. public static function orderOperate($requestData, $userId)
  275. {
  276. $goodsInfo = $requestData['goodsInfo'] ?? [];
  277. $type = $requestData['type'] ?? '';
  278. switch ($type) {
  279. case self::BUTTON_CONFIRM:
  280. $res = self::confirmOrder($goodsInfo['id'] ?? 0, $userId);
  281. break;
  282. case self::BUTTON_CANCEL:
  283. $res = self::cancelOrder($goodsInfo['id'] ?? 0, $userId);
  284. break;
  285. default:
  286. throw new \Exception('非法操作');
  287. }
  288. return $res;
  289. }
  290. /**
  291. * 取消订单
  292. * @param $order_id
  293. * @param $userId
  294. * @return mixed
  295. * @throws \Exception
  296. */
  297. public static function cancelOrder($orderId, $userId = 0)
  298. {
  299. try {
  300. $where = ['id' => $orderId, 'user_id' => $userId];
  301. $order = self::getOne($where);
  302. if (!$order) {
  303. throw new \Exception('该订单不存在');
  304. }
  305. Db::startTrans();
  306. if (!in_array($order->order_status, [OrderService::ORDER_STATUS_WAIT_PAY, OrderService::ORDER_STATUS_WAIT_SHIP])) {
  307. throw new \Exception('该订单为' . OrderService::ORDER_STATUS_MAP[$order->order_status] . ',不能取消');
  308. }
  309. //修改订单状态
  310. $upRes = self::where($where)->update(['order_status' => OrderService::ORDER_STATUS_CANCEL]);
  311. if (!$upRes) {
  312. throw new \Exception('更新订单状态失败');
  313. }
  314. //退款原路返回
  315. // OrderRefund::dispatch(['order_sn' => $order->order_sn, 'actual_amount' => $order->actual_amount]);
  316. //给用户发送出票失败结果通知
  317. // SendMsg::dispatch(['order_id' => $order->id, 'user_id' => $order->user_id, 'template_id' => SubscribeMessageService::MSG_TEMP_ORDER_FAILED, 'desc' => SubscribeMessageService::ORDER_MSG_MAP['failed'], 'desc2' => SubscribeMessageService::ORDER_MSG_MAP['refund']]);
  318. Db::commit();
  319. $info = OrderService::getOne(['id' => $orderId]);
  320. return $info;
  321. } catch (\Exception $e) {
  322. Db::rollback();
  323. throw $e;
  324. }
  325. }
  326. /**
  327. * 确认收货
  328. * @param $orderId
  329. * @param $userId
  330. * @return mixed
  331. * @throws \Exception
  332. */
  333. public static function confirmOrder($orderId, $userId = 0)
  334. {
  335. try {
  336. $where = ['id' => $orderId, 'user_id' => $userId];
  337. $order = self::getOne($where);
  338. if (!$order) {
  339. throw new \Exception('该订单不存在');
  340. }
  341. Db::startTrans();
  342. if (!in_array($order->order_status, [OrderService::ORDER_STATUS_SHIPPED])) {
  343. throw new \Exception('该订单为' . OrderService::ORDER_STATUS_MAP[$order->order_status] . ',不能确认收货');
  344. }
  345. //修改订单状态
  346. $upRes = self::where($where)->update(['order_status' => OrderService::ORDER_STATUS_FINISHED]);
  347. if (!$upRes) {
  348. throw new \Exception('更新订单状态失败');
  349. }
  350. Db::commit();
  351. $info = OrderService::getOne(['id' => $orderId]);
  352. return $info;
  353. } catch (\Exception $e) {
  354. Db::rollback();
  355. throw $e;
  356. }
  357. }
  358. /**
  359. * 微信支付回调
  360. * @param
  361. * @return string
  362. * @throws \Exception
  363. */
  364. public static function payNotify()
  365. {
  366. $xmlData = file_get_contents('php://input');
  367. $data = ToolService::FromXml($xmlData);
  368. Log::info('微信回调信息_request_xml:' . json_encode(['data' => $data, 'xml' => $xmlData]));
  369. $order_no = $data['out_trade_no'] ?? '';
  370. //更新订单状态
  371. $orderInfo = OrderService::getOne(['order_no' => $order_no]);
  372. self::checkPaySuccess($data, $orderInfo);
  373. $res = [
  374. 'return_code' => 'SUCCESS',
  375. 'return_msg' => 'OK'
  376. ];
  377. $xml = ToolService::ToXml($res);
  378. Log::info('微信回调信息信息_result:' . json_encode(['res' => $res, 'xml' => $xml]));
  379. //如果为待支付,才可更新为已支付。防止重复更新状态,导致重复发货。
  380. if ($orderInfo->order_status == self::ORDER_STATUS_WAIT_PAY) {
  381. $paymentData = [
  382. 'order_no' => $order_no,
  383. 'pay_status' => $data['result_code'],
  384. 'amount' => $data['total_fee'] / 100,
  385. 'currency' => $data['fee_type'],
  386. 'pay_type' => '1', // 1微信 2支付宝
  387. 'pay_way' => $data['trade_type'],
  388. 'trace_no' => $data['transaction_id'],
  389. 'pay_time' => time(),
  390. 'pay_success_time' => strtotime($data['time_end']),
  391. ];
  392. Db::transaction(function () use ($order_no, $paymentData, $orderInfo) {
  393. self::where('order_no', $order_no)->update(['order_status' => self::ORDER_STATUS_WAIT_SHIP]);
  394. OrderPaymentService::create($paymentData);
  395. if ($orderInfo->order_type == 1) {
  396. DemandService::customerContractFinishedDeal($orderInfo->parent_order_no);
  397. } elseif ($orderInfo->order_type == 2) {
  398. DemandService::customerWorkAcceptFinishedDeal($orderInfo->parent_order_no);
  399. }
  400. });
  401. }
  402. return $xml;
  403. }
  404. /**
  405. * @param $data
  406. * @param $info
  407. * @return void
  408. * @throws \Exception
  409. */
  410. public static function checkPaySuccess($data, $info)
  411. {
  412. if ($info) {
  413. $checkSign = ToolService::CheckSign($data, $data['sign']);
  414. $checkMoney = sprintf("%.1f", $data['total_fee'] / 100) == sprintf("%.1f", $info->payment_amount); //分
  415. $checkResult = $data['result_code'] == 'SUCCESS';
  416. if (!$checkSign) {
  417. throw new \Exception('签名错误');
  418. }
  419. if (!$checkMoney) {
  420. throw new \Exception('金额错误:' . sprintf("%.2f", $data['total_fee'] / 100) . '----' . sprintf("%.2f", $info->payment_amount));
  421. }
  422. if (!$checkResult) {
  423. throw new \Exception('支付失败');
  424. }
  425. } else {
  426. throw new \Exception('获取订单数据失败');
  427. }
  428. }
  429. /**
  430. * 获取缓存
  431. * @param $userId
  432. * @param $data array
  433. * @return mixed
  434. */
  435. public static function getLockOrderKey($userId, $data)
  436. {
  437. $key = self::LOCK_ORDER_PREFIX . md5($userId . json_encode($data));
  438. return $key;
  439. }
  440. /**
  441. * @param $order_sn
  442. * @param $total_fee
  443. * @param $openid
  444. * @param string $body
  445. * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
  446. * @throws \Exception
  447. */
  448. public static function pay($order_sn, $total_fee, $openid, string $body = '软件产品服务')
  449. {
  450. if (!($body && $order_sn && $total_fee && $openid)) {
  451. throw new \Exception('支付参数错误2');
  452. }
  453. $EasyWeChatService = new EasyWeChatService();
  454. $payRes = $EasyWeChatService->unify($body, $order_sn, $total_fee, $openid);
  455. if (!($payRes && $payRes['return_code'] == 'SUCCESS' && $payRes['return_msg'] == 'OK')) {
  456. throw new \Exception('统一下单接口调用失败');
  457. }
  458. $payData = $EasyWeChatService->sdkConfig($payRes['prepay_id']);
  459. return $payData;
  460. }
  461. /**
  462. * 获取订单操作按钮
  463. * @param $orderStatus
  464. * @return array
  465. */
  466. public static function getOrderButtons($orderStatus): array
  467. {
  468. $buttons = [];
  469. if ($orderStatus == self::ORDER_STATUS_WAIT_PAY) {
  470. $buttons[] = ['name' => self::BUTTON_MAP[OrderService::BUTTON_CANCEL], 'primary' => false, 'type' => OrderService::BUTTON_CANCEL];
  471. $buttons[] = ['name' => self::BUTTON_MAP[OrderService::BUTTON_PAY], 'primary' => true, 'type' => OrderService::BUTTON_PAY];
  472. }
  473. if ($orderStatus == self::ORDER_STATUS_SHIPPED) {
  474. $buttons[] = ['name' => self::BUTTON_MAP[OrderService::BUTTON_CONFIRM], 'primary' => true, 'type' => OrderService::BUTTON_CONFIRM];
  475. }
  476. return $buttons;
  477. }
  478. /**
  479. * 获取订单统计
  480. * @param $userId
  481. * @return array[]
  482. */
  483. public static function getOrderCount($userId): array
  484. {
  485. $orderCountList = [
  486. ['orderNum' => 0, 'tabType' => OrderService::ORDER_STATUS_WAIT_PAY],
  487. ['orderNum' => 0, 'tabType' => OrderService::ORDER_STATUS_WAIT_SHIP],
  488. ['orderNum' => 0, 'tabType' => OrderService::ORDER_STATUS_SHIPPED],
  489. ['orderNum' => 0, 'tabType' => OrderService::ORDER_STATUS_FINISHED],
  490. ['orderNum' => 0, 'tabType' => OrderService::ORDER_STATUS_REFUNDED],
  491. ];
  492. $countList = self::where(['user_id' => $userId, 'order_type' => self::ORDER_TYPE_SOFTWARE])->field('order_status, COUNT(*) as total')
  493. ->group('order_status')
  494. ->select();
  495. foreach ($orderCountList as &$value) {
  496. if ($value['tabType'] == OrderService::ORDER_STATUS_FINISHED) {
  497. continue;
  498. }
  499. foreach ($countList as $item) {
  500. if ($item->order_status == $value['tabType']) {
  501. $value['orderNum'] = $item->total;
  502. }
  503. }
  504. }
  505. return $orderCountList;
  506. }
  507. /**
  508. * 订单发货
  509. * @param $id
  510. * @return void
  511. * @throws \Exception
  512. */
  513. public static function orderShip($id)
  514. {
  515. Db::transaction(function () use ($id) {
  516. $order = OrderService::getOne(['id' => $id], ['orderGoods']);
  517. if ($order->order_status != OrderService::ORDER_STATUS_WAIT_SHIP) {
  518. exception('订单状态异常,不能发货');
  519. }
  520. //查询激活码
  521. $code = SoftCodeService::getAvailableCode();
  522. //生成发货单
  523. OrderShipService::createData($order->order_no, $order->orderGoods[0]->spu_id, $code);
  524. $order->order_status = OrderService::ORDER_STATUS_SHIPPED;
  525. //修改发货状态
  526. $saveRes = $order->save();
  527. if (!$saveRes) {
  528. exception('更新发货状态失败');
  529. }
  530. //发送订单发货通知
  531. $msgData = [
  532. 'values' => [
  533. $order->order_no,
  534. mb_substr($order->orderGoods[0]->goods_name, 0, 20),
  535. '已发货',
  536. SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_ORDER_SHIPPED]['remark'],
  537. ]
  538. ];
  539. (new EasyWeChatService())->sendMsg($order->user_id, SubscribeMessageService::MSG_TEMP_ORDER_SHIPPED, $msgData);
  540. });
  541. }
  542. }