StoreOrderDeliveryServices.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\order;
  12. use app\services\BaseServices;
  13. use app\dao\order\StoreOrderDao;
  14. use app\services\store\finance\StoreFinanceFlowServices;
  15. use app\services\serve\ServeServices;
  16. use think\exception\ValidateException;
  17. use crmeb\services\FormBuilder as Form;
  18. use app\services\other\ExpressServices;
  19. use crmeb\traits\OptionTrait;
  20. /**
  21. * 订单发货
  22. * Class StoreOrderDeliveryServices
  23. * @package app\services\order
  24. * @mixin StoreOrderDao
  25. */
  26. class StoreOrderDeliveryServices extends BaseServices
  27. {
  28. use OptionTrait;
  29. /**
  30. * 构造方法
  31. * StoreOrderDeliveryServices constructor.
  32. * @param StoreOrderDao $dao
  33. */
  34. public function __construct(StoreOrderDao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * 订单整体发货
  40. * @param int $id
  41. * @param array $data
  42. * @param int $staff_id
  43. * @return array
  44. * @throws \think\db\exception\DataNotFoundException
  45. * @throws \think\db\exception\DbException
  46. * @throws \think\db\exception\ModelNotFoundException
  47. */
  48. public function delivery(int $id, array $data, int $staff_id = 0)
  49. {
  50. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  51. if (!$orderInfo) {
  52. throw new ValidateException('订单未能查到,不能发货!');
  53. }
  54. if ($orderInfo['paid'] != 1) {
  55. throw new ValidateException('订单未支付');
  56. }
  57. if ($orderInfo->is_del) {
  58. throw new ValidateException('订单已删除,不能发货!');
  59. }
  60. if ($orderInfo->status == 1) {
  61. throw new ValidateException('订单已发货请勿重复操作!');
  62. }
  63. if ($orderInfo->shipping_type == 2) {
  64. throw new ValidateException('核销订单不能发货!');
  65. }
  66. if (isset($orderInfo['pinkStatus']) && $orderInfo['pinkStatus'] != 2) {
  67. throw new ValidateException('拼团未完成暂不能发货!');
  68. }
  69. $store_id = $this->getItem('store_id', 0);
  70. $supplier_id = $this->getItem('supplier_id', 0);
  71. //拆分完整主订单查询未发货子订单
  72. if ($orderInfo['pid'] == -1) {
  73. $orderInfo = $this->dao->get(['pid' => $id, 'status' => 0, 'supplier_id' => $supplier_id, 'store_id' => $store_id, 'refund_type' => [0, 3]], ['*'], ['pink']);
  74. if (!$orderInfo) {
  75. throw new ValidateException('订单未能查到,请在详情发货列表确认后发货');
  76. }
  77. $id = (int)$orderInfo['id'];
  78. }
  79. /** @var StoreOrderRefundServices $storeOrderRefundServices */
  80. $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
  81. if ($storeOrderRefundServices->count(['store_order_id' => $id, 'refund_type' => [1, 2, 4, 5, 6], 'is_cancel' => 0, 'is_del' => 0])) {
  82. throw new ValidateException('订单有售后申请请先处理');
  83. }
  84. //预售订单 验证预售活动是否结束
  85. if ($orderInfo['type'] == 6) {
  86. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  87. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  88. $cartInfo = $storeOrderCartInfoServices->getOrderCartInfo($id);
  89. $time = time();
  90. foreach ($cartInfo as $cart) {
  91. if (isset($cart['cart_info']['productInfo']['presale_end_time']) && $cart['cart_info']['productInfo']['presale_end_time'] > $time) {
  92. throw new ValidateException('预售活动暂未结束,请稍后发货');
  93. }
  94. }
  95. }
  96. $dump = $this->doDelivery($id, $orderInfo, $data);
  97. if ($staff_id) {
  98. $this->dao->update($id, ['staff_id' => $staff_id]);
  99. //流水关联店员
  100. /** @var StoreFinanceFlowServices $storeFinanceFlow */
  101. $storeFinanceFlow = app()->make(StoreFinanceFlowServices::class);
  102. $storeFinanceFlow->setStaff($orderInfo['order_id'], $staff_id);
  103. }
  104. return compact('orderInfo', 'dump');
  105. }
  106. /**
  107. * 订单拆单发货
  108. * @param int $id
  109. * @param array $data
  110. * @param int $staff_id
  111. * @return bool
  112. * @throws \think\db\exception\DataNotFoundException
  113. * @throws \think\db\exception\DbException
  114. * @throws \think\db\exception\ModelNotFoundException
  115. */
  116. public function splitDelivery(int $id, array $data, int $staff_id = 0)
  117. {
  118. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  119. if (!$orderInfo) {
  120. throw new ValidateException('订单未能查到,不能发货!');
  121. }
  122. if ($orderInfo['paid'] != 1) {
  123. throw new ValidateException('订单未支付');
  124. }
  125. if ($orderInfo->is_del) {
  126. throw new ValidateException('订单已删除,不能发货!');
  127. }
  128. if ($orderInfo->shipping_type == 2) {
  129. throw new ValidateException('核销订单不能发货!');
  130. }
  131. if (isset($orderInfo['pinkStatus']) && $orderInfo['pinkStatus'] != 2) {
  132. throw new ValidateException('拼团未完成暂不能发货!');
  133. }
  134. $store_id = $this->getItem('store_id', 0);
  135. $supplier_id = $this->getItem('supplier_id', 0);
  136. //拆分完整主订单查询未发货子订单
  137. if ($orderInfo['pid'] == -1) {
  138. $orderInfo = $this->dao->get(['pid' => $id, 'status' => 0, 'supplier_id' => $supplier_id, 'store_id' => $store_id, 'refund_type' => [0, 3]], ['*'], ['pink']);
  139. if (!$orderInfo) {
  140. throw new ValidateException('订单未能查到,不能发货!');
  141. }
  142. $id = (int)$orderInfo['id'];
  143. }
  144. /** @var StoreOrderRefundServices $storeOrderRefundServices */
  145. $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
  146. if ($storeOrderRefundServices->count(['store_order_id' => $id, 'refund_type' => [1, 2, 4, 5, 6], 'is_cancel' => 0, 'is_del' => 0])) {
  147. throw new ValidateException('订单有售后申请请先处理');
  148. }
  149. //预售订单 验证预售活动是否结束
  150. if ($orderInfo['type'] == 6) {
  151. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  152. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  153. $cartInfo = $storeOrderCartInfoServices->getOrderCartInfo($id);
  154. $time = time();
  155. foreach ($cartInfo as $cart) {
  156. if (isset($cart['cart_info']['productInfo']['presale_end_time']) && $cart['cart_info']['productInfo']['presale_end_time'] > $time) {
  157. throw new ValidateException('预售活动暂未结束,请稍后发货');
  158. }
  159. }
  160. }
  161. $cart_ids = $data['cart_ids'];
  162. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  163. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  164. //检测选择商品是否还可拆分
  165. $storeOrderCartInfoServices->checkCartIdsIsSplit($id, $cart_ids);
  166. unset($data['cart_ids']);
  167. return $this->transaction(function () use ($id, $cart_ids, $orderInfo, $data, $storeOrderCartInfoServices, $staff_id) {
  168. /** @var StoreOrderSplitServices $storeOrderSplitServices */
  169. $storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
  170. //拆单
  171. $splitResult = $storeOrderSplitServices->equalSplit($id, $cart_ids, $orderInfo, 0, false, $data['erp_id'] ?? 0);
  172. if ($splitResult) {//拆分发货
  173. [$orderInfo, $otherOrder] = $splitResult;
  174. //拆分订单执行发货
  175. $this->doDelivery((int)$orderInfo->id, $orderInfo, $data);
  176. //检测原订单商品是否 全部拆分发货完成 改原订单状态
  177. $status_data = ['oid' => $id, 'change_time' => time()];
  178. if (!$storeOrderCartInfoServices->getSplitCartList($id)) {//发货完成
  179. $status_data['change_type'] = 'delivery_split';
  180. $status_data['change_message'] = '已拆分发货';
  181. } else {
  182. $status_data['change_type'] = 'delivery_part_split';
  183. $status_data['change_message'] = '已拆分部分发货';
  184. }
  185. /** @var StoreOrderStatusServices $services */
  186. $services = app()->make(StoreOrderStatusServices::class);
  187. //记录原订单状态
  188. $services->save($status_data);
  189. if ($staff_id) {
  190. $this->dao->update($orderInfo['id'], ['staff_id' => $staff_id]);
  191. //流水关联店员
  192. /** @var StoreFinanceFlowServices $storeFinanceFlow */
  193. $storeFinanceFlow = app()->make(StoreFinanceFlowServices::class);
  194. $storeFinanceFlow->setStaff($orderInfo['order_id'], $staff_id);
  195. }
  196. } else {//整体发货
  197. $this->delivery($id, $data, $staff_id);
  198. }
  199. return $splitResult;
  200. });
  201. // return true;
  202. }
  203. /**
  204. * 具体执行发货
  205. * @param int $id
  206. * @param $orderInfo
  207. * @param array $data
  208. * @return bool
  209. */
  210. public function doDelivery(int $id, $orderInfo, array $data)
  211. {
  212. $type = (int)$data['type'];
  213. unset($data['type']);
  214. //获取购物车内的商品标题
  215. /** @var StoreOrderCartInfoServices $orderInfoServices */
  216. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  217. $storeName = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo['id']);
  218. //修改返回数据
  219. $res = [];
  220. switch ($type) {
  221. case 1://快递发货
  222. $res = $this->orderDeliverGoods($id, $data, $orderInfo, $storeName);
  223. break;
  224. case 2://配送
  225. $this->orderDelivery($id, $data, $orderInfo);
  226. break;
  227. case 3://虚拟发货
  228. $this->orderVirtualDelivery($id, $data);
  229. break;
  230. case 4://门店收银订单自动发货
  231. $this->dao->update($orderInfo['id'], ['delivery_type' => 'cashier']);
  232. /** @var StoreOrderStatusServices $statusService */
  233. $statusService = app()->make(StoreOrderStatusServices::class);
  234. $statusService->save([
  235. 'oid' => $orderInfo['id'],
  236. 'change_type' => 'delivery_cashier',
  237. 'change_message' => '门店收银台自提',
  238. 'change_time' => time()
  239. ]);
  240. break;
  241. default:
  242. throw new ValidateException('暂时不支持其他发货类型');
  243. }
  244. //跟新完成后重新赋值订单信息
  245. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  246. event('order.delivery', [$orderInfo, $storeName, $data, $type]);
  247. return $res;
  248. }
  249. /**
  250. * 订单快递发货
  251. * @param int $id
  252. * @param array $data
  253. */
  254. public function orderDeliverGoods(int $id, array $data, $orderInfo, $storeTitle)
  255. {
  256. if (!$data['delivery_name']) {
  257. throw new ValidateException('请选择快递公司');
  258. }
  259. //修改
  260. $dump = [];
  261. $data['delivery_type'] = 'express';
  262. if ($data['express_record_type'] == 2) {//电子面单
  263. if (!sys_config('config_export_open', 0)) {
  264. throw new ValidateException('系统通知:电子面单已关闭,请选择其他发货方式!');
  265. }
  266. if (!$data['delivery_code']) {
  267. throw new ValidateException('快递公司编缺失');
  268. }
  269. if (!$data['express_temp_id']) {
  270. throw new ValidateException('请选择电子面单模板');
  271. }
  272. if (!$data['to_name']) {
  273. throw new ValidateException('请填写寄件人姓名');
  274. }
  275. if (!$data['to_tel']) {
  276. throw new ValidateException('请填写寄件人电话');
  277. }
  278. if (!$data['to_addr']) {
  279. throw new ValidateException('请填写寄件人地址');
  280. }
  281. $expData['com'] = $data['delivery_code'];
  282. $expData['to_name'] = $orderInfo['real_name'];
  283. $expData['to_tel'] = $orderInfo['user_phone'];
  284. $expData['to_addr'] = $orderInfo['user_address'];
  285. $expData['from_name'] = $data['to_name'];
  286. $expData['from_tel'] = $data['to_tel'];
  287. $expData['from_addr'] = $data['to_addr'];
  288. $expData['siid'] = sys_config('config_export_siid');
  289. $expData['temp_id'] = $data['express_temp_id'];
  290. $expData['count'] = $orderInfo['total_num'];
  291. $expData['weight'] = $this->getOrderSumWeight($id);
  292. /** @var StoreOrderCartInfoServices $orderInfoServices */
  293. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  294. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo['id'], true);
  295. $expData['order_id'] = $orderInfo['order_id'];
  296. /** @var ServeServices $expressService */
  297. $expressService = app()->make(ServeServices::class);
  298. $dump = $expressService->express()->dump($expData);
  299. $data['express_dump'] = json_encode([
  300. 'com' => $expData['com'],
  301. 'from_name' => $expData['from_name'],
  302. 'from_tel' => $expData['from_tel'],
  303. 'from_addr' => $expData['from_addr'],
  304. 'temp_id' => $expData['temp_id'],
  305. 'cargo' => $expData['cargo'],
  306. ]);
  307. $data['delivery_id'] = $dump['kuaidinum'];
  308. //修改快递面单图片写入数据库
  309. if (!empty($dump['label'])) {
  310. $data['kuaidi_label'] = $dump['label'];
  311. }
  312. } else {
  313. if (!$data['delivery_id']) {
  314. throw new ValidateException('请输入快递单号');
  315. }
  316. }
  317. $data['status'] = 1;
  318. unset($data['delivery_remark']);
  319. /** @var StoreOrderStatusServices $services */
  320. $services = app()->make(StoreOrderStatusServices::class);
  321. $this->transaction(function () use ($id, $data, $services) {
  322. $res = $this->dao->update($id, $data);
  323. $res = $res && $services->save([
  324. 'oid' => $id,
  325. 'change_time' => time(),
  326. 'change_type' => 'delivery_goods',
  327. 'change_message' => '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  328. ]);
  329. if (!$res) {
  330. throw new ValidateException('发货失败:数据保存不成功');
  331. }
  332. });
  333. return $dump;
  334. }
  335. /**
  336. * 订单配送
  337. * @param int $id
  338. * @param array $data
  339. * @return bool
  340. */
  341. public function orderDelivery(int $id, array $data, $orderInfo = [])
  342. {
  343. $data['delivery_name'] = $data['sh_delivery_name'];
  344. $data['delivery_id'] = $data['sh_delivery_id'];
  345. $data['delivery_uid'] = $data['sh_delivery_uid'];
  346. $delivery_type = $data['delivery_type'] ?? 1;
  347. $delivery_type = $delivery_type ? $delivery_type : 1;
  348. $station_type = $data['station_type'] ?? 1;
  349. unset($data['delivery_type'], $data['station_type']);
  350. switch ($delivery_type) {
  351. case 1://自己配送
  352. if (!$data['delivery_name']) {
  353. throw new ValidateException('请输入送货人姓名');
  354. }
  355. if (!$data['delivery_id']) {
  356. throw new ValidateException('请输入送货人电话号码');
  357. }
  358. if (!$data['delivery_uid']) {
  359. throw new ValidateException('请输入送货人信息');
  360. }
  361. if (!check_phone($data['delivery_id'])) {
  362. throw new ValidateException('请输入正确的送货人电话号码');
  363. }
  364. //获取核销码
  365. /** @var StoreOrderCreateServices $storeOrderCreateService */
  366. $storeOrderCreateService = app()->make(StoreOrderCreateServices::class);
  367. $data['verify_code'] = $storeOrderCreateService->getStoreCode();
  368. $data['delivery_type'] = 'send';
  369. break;
  370. case 2://第三方配送
  371. if (!isset($data['cargo_weight']) || !$data['cargo_weight']) {
  372. throw new ValidateException('请填写配送商品重量');
  373. }
  374. $data['delivery_type'] = 'city_delivery';
  375. /** @var StoreDeliveryOrderServices $storeDeliverOrderServices */
  376. $storeDeliverOrderServices = app()->make(StoreDeliveryOrderServices::class);
  377. $storeDeliverOrderServices->create($id, $data, $station_type, $orderInfo);
  378. break;
  379. }
  380. $data['status'] = 1;
  381. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['sh_delivery_uid'], $data['delivery_remark']);
  382. /** @var StoreOrderStatusServices $services */
  383. $services = app()->make(StoreOrderStatusServices::class);
  384. $this->transaction(function () use ($id, $data, $services, $delivery_type, $station_type) {
  385. //修改订单发货信息
  386. $this->dao->update($id, $data);
  387. if ($delivery_type == 1) {
  388. $message = '已配送 发货人:' . $data['delivery_name'] . ' 发货人电话:' . $data['delivery_id'];
  389. } else {
  390. $message = '已'. ($station_type == 1 ? '达达' : 'UU跑腿') .'同城配送';
  391. }
  392. //记录订单状态
  393. $services->save([
  394. 'oid' => $id,
  395. 'change_type' => $delivery_type == 1 ? 'delivery' : 'city_delivery',
  396. 'change_time' => time(),
  397. 'change_message' => $message
  398. ]);
  399. });
  400. return true;
  401. }
  402. /**
  403. * 虚拟发货
  404. * @param int $id
  405. * @param array $data
  406. */
  407. public function orderVirtualDelivery(int $id, array $data)
  408. {
  409. $data['delivery_type'] = 'fictitious';
  410. $data['status'] = 1;
  411. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['delivery_name'], $data['delivery_id'], $data['delivery_remark']);
  412. //保存信息
  413. /** @var StoreOrderStatusServices $services */
  414. $services = app()->make(StoreOrderStatusServices::class);
  415. return $this->transaction(function () use ($id, $data, $services) {
  416. $res1 = $this->dao->update($id, $data);
  417. $res2 = $services->save([
  418. 'oid' => $id,
  419. 'change_type' => 'delivery_fictitious',
  420. 'change_message' => '已虚拟发货',
  421. 'change_time' => time()
  422. ]);
  423. return $res1 && $res2;
  424. });
  425. }
  426. /**
  427. * 获取修改配送信息表单结构
  428. * @param int $id
  429. * @return array
  430. * @throws \FormBuilder\Exception\FormBuilderException
  431. */
  432. public function distributionForm(int $id)
  433. {
  434. if (!$orderInfo = $this->dao->get($id))
  435. throw new ValidateException('订单不存在');
  436. $f[] = Form::input('order_id', '订单号', $orderInfo->getData('order_id'))->disabled(1);
  437. switch ($orderInfo['delivery_type']) {
  438. case 'send':
  439. $f[] = Form::input('delivery_name', '送货人姓名', $orderInfo->getData('delivery_name'))->required('请输入送货人姓名');
  440. $f[] = Form::input('delivery_id', '送货人电话', $orderInfo->getData('delivery_id'))->required('请输入送货人电话');
  441. break;
  442. case 'express':
  443. /** @var ExpressServices $expressServices */
  444. $expressServices = app()->make(ExpressServices::class);
  445. $f[] = Form::select('delivery_name', '快递公司', (string)$orderInfo->getData('delivery_name'))->setOptions(array_map(function ($item) {
  446. $item['value'] = $item['label'];
  447. return $item;
  448. }, $expressServices->expressSelectForm(['is_show' => 1])))->filterable(true)->required('请选择快递公司');
  449. $f[] = Form::input('delivery_id', '快递单号', $orderInfo->getData('delivery_id'))->required('请填写快递单号');
  450. break;
  451. }
  452. return create_form('配送信息', $f, $this->url('/order/distribution/' . $id), 'PUT');
  453. }
  454. /**
  455. * 修改配送信息
  456. * @param int $id 订单id
  457. * @return mixed
  458. */
  459. public function updateDistribution(int $id, array $data)
  460. {
  461. $order = $this->dao->get($id);
  462. if (!$order) {
  463. throw new ValidateException('数据不存在!');
  464. }
  465. switch ($order['delivery_type']) {
  466. case 'send':
  467. if (!$data['delivery_name']) {
  468. throw new ValidateException('请输入送货人姓名');
  469. }
  470. if (!$data['delivery_id']) {
  471. throw new ValidateException('请输入送货人电话号码');
  472. }
  473. if (!check_phone($data['delivery_id'])) {
  474. throw new ValidateException('请输入正确的送货人电话号码');
  475. }
  476. break;
  477. case 'express':
  478. if (!$data['delivery_name']) {
  479. throw new ValidateException('请选择快递公司');
  480. }
  481. if (!$data['delivery_id']) {
  482. throw new ValidateException('请输入快递单号');
  483. }
  484. break;
  485. default:
  486. throw new ValidateException('未发货,请先发货再修改配送信息');
  487. break;
  488. }
  489. /** @var StoreOrderStatusServices $statusService */
  490. $statusService = app()->make(StoreOrderStatusServices::class);
  491. $statusService->save([
  492. 'oid' => $id,
  493. 'change_type' => 'distribution',
  494. 'change_message' => '修改发货信息为' . $data['delivery_name'] . '号' . $data['delivery_id'],
  495. 'change_time' => time()
  496. ]);
  497. return $this->dao->update($id, $data);
  498. }
  499. /**
  500. * 订单发货后打印电子面单
  501. * @param $orderId
  502. * @return bool|mixed
  503. */
  504. public function orderDump($orderId)
  505. {
  506. if (!$orderId) throw new ValidateException('订单号缺失');
  507. /** @var StoreOrderServices $orderService */
  508. $orderService = app()->make(StoreOrderServices::class);
  509. $orderInfo = $orderService->getOne(['id' => $orderId]);
  510. if (!$orderInfo) throw new ValidateException('订单不存在');
  511. if (in_array($orderInfo->shipping_type, [2, 4])) throw new ValidateException('订单无法打印');
  512. if (!$orderInfo->express_dump) throw new ValidateException('请先发货');
  513. if (!sys_config('config_export_open', 0)) {
  514. throw new ValidateException('请先在系统设置中打开单子面单打印开关');
  515. }
  516. $dumpInfo = json_decode($orderInfo->express_dump, true);
  517. /** @var ServeServices $expressService */
  518. $expressService = app()->make(ServeServices::class);
  519. $expData['com'] = $dumpInfo['com'];
  520. $expData['to_name'] = $orderInfo->real_name;
  521. $expData['to_tel'] = $orderInfo->user_phone;
  522. $expData['to_addr'] = $orderInfo->user_address;
  523. $expData['from_name'] = $dumpInfo['from_name'];
  524. $expData['from_tel'] = $dumpInfo['from_tel'];
  525. $expData['from_addr'] = $dumpInfo['from_addr'];
  526. $expData['siid'] = sys_config('config_export_siid');
  527. $expData['temp_id'] = $dumpInfo['temp_id'];
  528. $expData['cargo'] = $dumpInfo['cargo'];
  529. $expData['count'] = $orderInfo->total_num;
  530. $expData['weight'] = $this->getOrderSumWeight((int)$orderId);
  531. $expData['order_id'] = $orderInfo->order_id;
  532. try {
  533. $dump = $expressService->express()->dump($expData);
  534. $data['express_dump'] = json_encode([
  535. 'com' => $expData['com'],
  536. 'from_name' => $expData['from_name'],
  537. 'from_tel' => $expData['from_tel'],
  538. 'from_addr' => $expData['from_addr'],
  539. 'temp_id' => $expData['temp_id'],
  540. 'cargo' => $expData['cargo'],
  541. ]);
  542. $data['delivery_id'] = $dump['kuaidinum'] ?? '';
  543. //修改快递面单图片写入数据库
  544. if (!empty($dump['label'])) {
  545. $data['kuaidi_label'] = $dump['label'];
  546. }
  547. $orderService->update($orderId, $data);
  548. } catch (\Throwable $e) {
  549. $dump = [];
  550. }
  551. return $dump;
  552. }
  553. /**
  554. * 返回订单商品总重量
  555. * @param int $id
  556. * @return int|string
  557. */
  558. public function getOrderSumWeight(int $id, $default = false)
  559. {
  560. /** @var StoreOrderCartInfoServices $services */
  561. $services = app()->make(StoreOrderCartInfoServices::class);
  562. $orderGoodInfo = $services->getOrderCartInfo((int)$id);
  563. $weight = 0;
  564. foreach ($orderGoodInfo as $cartInfo) {
  565. $cart = $cartInfo['cart_info'] ?? [];
  566. if ($cart) {
  567. $weight = bcadd((string)$weight, (string)bcmul((string)$cart['cart_num'] ?? '0', (string)$cart['productInfo']['attrInfo']['weight'] ?? '0', 4), 2);
  568. }
  569. }
  570. return $weight ? $weight : ($default === false ? 0 : $default);
  571. }
  572. }