StoreOrderDeliveryServices.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2023 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\activity\coupon\StoreCouponIssueServices;
  13. use app\services\BaseServices;
  14. use app\dao\order\StoreOrderDao;
  15. use app\services\message\MessageSystemServices;
  16. use app\services\product\sku\StoreProductAttrValueServices;
  17. use app\services\product\sku\StoreProductVirtualServices;
  18. use app\services\serve\ServeServices;
  19. use crmeb\exceptions\AdminException;
  20. use crmeb\exceptions\ApiException;
  21. use crmeb\services\FormBuilder as Form;
  22. use app\services\shipping\ExpressServices;
  23. use think\facade\Log;
  24. /**
  25. * 订单发货
  26. * Class StoreOrderDeliveryServices
  27. * @package app\services\order
  28. */
  29. class StoreOrderDeliveryServices extends BaseServices
  30. {
  31. /**
  32. * 构造方法
  33. * StoreOrderDeliveryServices constructor.
  34. * @param StoreOrderDao $dao
  35. */
  36. public function __construct(StoreOrderDao $dao)
  37. {
  38. $this->dao = $dao;
  39. }
  40. /**
  41. * 订单发货
  42. * @param int $id
  43. * @param array $data
  44. * @return array
  45. */
  46. public function delivery(int $id, array $data)
  47. {
  48. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  49. if (!$orderInfo) {
  50. throw new AdminException(400470);
  51. }
  52. if ($orderInfo->is_del) {
  53. throw new AdminException(400471);
  54. }
  55. if ($orderInfo->status) {
  56. throw new AdminException(400472);
  57. }
  58. if ($orderInfo->shipping_type == 2) {
  59. throw new AdminException(400473);
  60. }
  61. if (isset($orderInfo['pinkStatus']) && $orderInfo['pinkStatus'] != 2) {
  62. throw new AdminException(400474);
  63. }
  64. if ($data['type'] == 1) {
  65. // 检测快递公司编码
  66. /** @var ExpressServices $expressServices */
  67. $expressServices = app()->make(ExpressServices::class);
  68. if (!$expressServices->be(['code' => $data['delivery_code']])) {
  69. throw new AdminException(410324);
  70. }
  71. }
  72. /** @var StoreOrderRefundServices $storeOrderRefundServices */
  73. $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
  74. if ($storeOrderRefundServices->count(['store_order_id' => $id, 'refund_type' => [1, 2, 4, 5], 'is_cancel' => 0, 'is_del' => 0])) {
  75. throw new AdminException(400475);
  76. }
  77. return $this->doDelivery($id, $orderInfo, $data);
  78. }
  79. /**
  80. * 订单快递发货
  81. * @param int $id
  82. * @param array $data
  83. */
  84. public function orderDeliveryGoods(int $id, array $data, $orderInfo, $storeTitle)
  85. {
  86. /** @var StoreOrderCartInfoServices $orderInfoServices */
  87. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  88. if (!$data['delivery_name']) {
  89. throw new AdminException(400007);
  90. }
  91. $data['delivery_type'] = 'express';
  92. if ($data['express_record_type'] == 2) {//电子面单
  93. if (!$data['delivery_code']) {
  94. throw new AdminException(400476);
  95. }
  96. if (!$data['express_temp_id']) {
  97. throw new AdminException(400527);
  98. }
  99. if (!$data['to_name']) {
  100. throw new AdminException(400008);
  101. }
  102. if (!$data['to_tel']) {
  103. throw new AdminException(400477);
  104. }
  105. if (!$data['to_addr']) {
  106. throw new AdminException(400478);
  107. }
  108. /** @var ServeServices $expressService */
  109. $expressService = app()->make(ServeServices::class);
  110. $expData['com'] = $data['delivery_code'];
  111. $expData['to_name'] = $orderInfo->real_name;
  112. $expData['to_tel'] = $orderInfo->user_phone;
  113. $expData['to_addr'] = $orderInfo->user_address;
  114. $expData['from_name'] = $data['to_name'];
  115. $expData['from_tel'] = $data['to_tel'];
  116. $expData['from_addr'] = $data['to_addr'];
  117. $expData['siid'] = sys_config('config_export_siid');
  118. $expData['temp_id'] = $data['express_temp_id'];
  119. $expData['count'] = $orderInfo->total_num;
  120. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
  121. $expData['order_id'] = $orderInfo->order_id;
  122. if (!sys_config('config_export_open', 0)) {
  123. throw new AdminException(400528);
  124. }
  125. $dump = $expressService->express()->dump($expData);
  126. $orderInfo->delivery_id = $dump['kuaidinum'];
  127. $data['express_dump'] = json_encode([
  128. 'com' => $expData['com'],
  129. 'from_name' => $expData['from_name'],
  130. 'from_tel' => $expData['from_tel'],
  131. 'from_addr' => $expData['from_addr'],
  132. 'temp_id' => $expData['temp_id'],
  133. 'cargo' => $expData['cargo'],
  134. ]);
  135. $data['delivery_id'] = $dump['kuaidinum'];
  136. } else {
  137. if (!$data['delivery_id']) {
  138. throw new AdminException(400531);
  139. }
  140. $orderInfo->delivery_id = $data['delivery_id'];
  141. }
  142. $data['status'] = 1;
  143. $orderInfo->delivery_type = $data['delivery_type'];
  144. $orderInfo->delivery_name = $data['delivery_name'];
  145. $orderInfo->status = $data['status'];
  146. /** @var StoreOrderStatusServices $services */
  147. $services = app()->make(StoreOrderStatusServices::class);
  148. $this->transaction(function () use ($id, $data, $services) {
  149. $res = $this->dao->update($id, $data);
  150. $res = $res && $services->save([
  151. 'oid' => $id,
  152. 'change_time' => time(),
  153. 'change_type' => 'delivery_goods',
  154. 'change_message' => '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  155. ]);
  156. if (!$res) {
  157. throw new AdminException(400529);
  158. }
  159. });
  160. return true;
  161. }
  162. /**
  163. * 订单配送
  164. * @param int $id
  165. * @param array $data
  166. */
  167. public function orderDelivery(int $id, array $data, $orderInfo, string $storeTitle)
  168. {
  169. $data['delivery_type'] = 'send';
  170. $data['delivery_name'] = $data['sh_delivery_name'];
  171. $data['delivery_id'] = $data['sh_delivery_id'];
  172. $data['delivery_uid'] = $data['sh_delivery_uid'];
  173. $data['shipping_type'] = 1;
  174. //获取核销码
  175. /** @var StoreOrderCreateServices $storeOrderCreateService */
  176. $storeOrderCreateService = app()->make(StoreOrderCreateServices::class);
  177. $data['verify_code'] = $storeOrderCreateService->getStoreCode();
  178. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['sh_delivery_uid']);
  179. if (!$data['delivery_name']) {
  180. throw new AdminException(400523);
  181. }
  182. if (!$data['delivery_id']) {
  183. throw new AdminException(400524);
  184. }
  185. if (!$data['delivery_uid']) {
  186. throw new AdminException(400525);
  187. }
  188. if (!preg_match("/^1[3456789]{1}\d{9}$/", $data['delivery_id'])) {
  189. throw new AdminException(400526);
  190. }
  191. $data['status'] = 1;
  192. $orderInfo->delivery_type = $data['delivery_type'];
  193. $orderInfo->delivery_name = $data['delivery_name'];
  194. $orderInfo->delivery_id = $data['delivery_id'];
  195. $orderInfo->status = $data['status'];
  196. /** @var StoreOrderStatusServices $services */
  197. $services = app()->make(StoreOrderStatusServices::class);
  198. $this->transaction(function () use ($id, $data, $services) {
  199. $this->dao->update($id, $data);
  200. //记录订单状态
  201. $services->save([
  202. 'oid' => $id,
  203. 'change_type' => 'delivery',
  204. 'change_time' => time(),
  205. 'change_message' => '已配送 发货人:' . $data['delivery_name'] . ' 发货人电话:' . $data['delivery_id']
  206. ]);
  207. });
  208. return true;
  209. }
  210. /**
  211. * 虚拟发货
  212. * @param int $id
  213. * @param array $data
  214. */
  215. public function orderVirtualDelivery(int $id, array $data)
  216. {
  217. $data['delivery_type'] = 'fictitious';
  218. $data['status'] = 1;
  219. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['delivery_name'], $data['delivery_id']);
  220. //保存信息
  221. /** @var StoreOrderStatusServices $services */
  222. $services = app()->make(StoreOrderStatusServices::class);
  223. $this->transaction(function () use ($id, $data, $services) {
  224. $this->dao->update($id, $data);
  225. $services->save([
  226. 'oid' => $id,
  227. 'change_type' => 'delivery_fictitious',
  228. 'change_message' => '已虚拟发货',
  229. 'change_time' => time()
  230. ]);
  231. });
  232. }
  233. /**
  234. * 获取修改配送信息表单结构
  235. * @param int $id
  236. * @return array
  237. * @throws \FormBuilder\Exception\FormBuilderException
  238. */
  239. public function distributionForm(int $id)
  240. {
  241. if (!$orderInfo = $this->dao->get($id))
  242. throw new AdminException(400118);
  243. $f[] = Form::input('order_id', '订单号', $orderInfo->getData('order_id'))->disabled(1);
  244. switch ($orderInfo['delivery_type']) {
  245. case 'send':
  246. $f[] = Form::input('delivery_name', '送货人姓名', $orderInfo->getData('delivery_name'))->required('请输入送货人姓名');
  247. $f[] = Form::input('delivery_id', '送货人电话', $orderInfo->getData('delivery_id'))->required('请输入送货人电话');
  248. break;
  249. case 'express':
  250. /** @var ExpressServices $expressServices */
  251. $expressServices = app()->make(ExpressServices::class);
  252. $f[] = Form::select('delivery_code', '快递公司', (string)$orderInfo->getData('delivery_code'))->setOptions($expressServices->expressSelectForm(['is_show' => 1]))->required('请选择快递公司')->filterable(true);
  253. $f[] = Form::input('delivery_id', '快递单号', $orderInfo->getData('delivery_id'))->required('请填写快递单号');
  254. break;
  255. }
  256. return create_form('配送信息', $f, $this->url('/order/distribution/' . $id), 'PUT');
  257. }
  258. /**
  259. * 修改配送信息
  260. * @param int $id 订单id
  261. * @return mixed
  262. */
  263. public function updateDistribution(int $id, array $data)
  264. {
  265. $order = $this->dao->get($id);
  266. if (!$order) {
  267. throw new AdminException(100026);
  268. }
  269. switch ($order['delivery_type']) {
  270. case 'send':
  271. if (!$data['delivery_name']) {
  272. throw new AdminException(400523);
  273. }
  274. if (!$data['delivery_id']) {
  275. throw new AdminException(400524);
  276. }
  277. if (!preg_match("/^1[3456789]{1}\d{9}$/", $data['delivery_id'])) {
  278. throw new AdminException(400526);
  279. }
  280. break;
  281. case 'express':
  282. if (!$data['delivery_id']) {
  283. throw new AdminException(400531);
  284. }
  285. // 检测快递公司编码
  286. /** @var ExpressServices $expressServices */
  287. $expressServices = app()->make(ExpressServices::class);
  288. if ($name = $expressServices->value(['code' => $data['delivery_code']], 'name')) {
  289. $data['delivery_name'] = $name;
  290. } else {
  291. throw new AdminException(410324);
  292. }
  293. break;
  294. case 'fictitious':
  295. throw new AdminException(400479);
  296. break;
  297. default:
  298. throw new AdminException(400480);
  299. break;
  300. }
  301. /** @var StoreOrderStatusServices $statusService */
  302. $statusService = app()->make(StoreOrderStatusServices::class);
  303. $statusService->save([
  304. 'oid' => $id,
  305. 'change_type' => 'distribution',
  306. 'change_message' => '修改发货信息为' . $data['delivery_name'] . '号' . $data['delivery_id'],
  307. 'change_time' => time()
  308. ]);
  309. return $this->dao->update($id, $data);
  310. }
  311. /**订单发货后打印电子面单
  312. * @param $orderId
  313. * @return bool|mixed
  314. */
  315. public function orderDump($orderId)
  316. {
  317. if (!$orderId) throw new AdminException(10100);
  318. /** @var StoreOrderServices $orderService */
  319. $orderService = app()->make(StoreOrderServices::class);
  320. $orderInfo = $orderService->getOne(['id' => $orderId]);
  321. if (!$orderInfo) throw new AdminException(400118);
  322. if ($orderInfo->shipping_type != 1) throw new AdminException(400481);
  323. if (!$orderInfo->express_dump) throw new AdminException(400482);
  324. if (!sys_config('config_export_open', 0)) {
  325. throw new AdminException(400483);
  326. }
  327. $dumpInfo = json_decode($orderInfo->express_dump, true);
  328. /** @var ServeServices $expressService */
  329. $expressService = app()->make(ServeServices::class);
  330. $expData['com'] = $dumpInfo['com'];
  331. $expData['to_name'] = $orderInfo->real_name;
  332. $expData['to_tel'] = $orderInfo->user_phone;
  333. $expData['to_addr'] = $orderInfo->user_address;
  334. $expData['from_name'] = $dumpInfo['from_name'];
  335. $expData['from_tel'] = $dumpInfo['from_tel'];
  336. $expData['from_addr'] = $dumpInfo['from_addr'];
  337. $expData['siid'] = sys_config('config_export_siid');
  338. $expData['temp_id'] = $dumpInfo['temp_id'];
  339. $expData['cargo'] = $dumpInfo['cargo'];
  340. $expData['count'] = $orderInfo->total_num;
  341. $expData['order_id'] = $orderInfo->order_id;
  342. return $expressService->express()->dump($expData);
  343. }
  344. /**
  345. * 订单拆单发货
  346. * @param int $id
  347. * @param array $data
  348. * @return bool
  349. * @throws \think\db\exception\DataNotFoundException
  350. * @throws \think\db\exception\DbException
  351. * @throws \think\db\exception\ModelNotFoundException
  352. * @author 吴汐
  353. * @email 442384644@qq.com
  354. * @date 2023/02/21
  355. */
  356. public function splitDelivery(int $id, array $data, $delivery_code = true)
  357. {
  358. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  359. if (!$orderInfo) {
  360. throw new AdminException(400470);
  361. }
  362. if ($orderInfo->is_del) {
  363. throw new AdminException(400471);
  364. }
  365. if ($orderInfo->shipping_type == 2) {
  366. throw new AdminException(400473);
  367. }
  368. if (isset($orderInfo['pinkStatus']) && $orderInfo['pinkStatus'] != 2) {
  369. throw new AdminException(400474);
  370. }
  371. /** @var StoreOrderRefundServices $storeOrderRefundServices */
  372. $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
  373. if ($storeOrderRefundServices->count(['store_order_id' => $id, 'refund_type' => [1, 2, 4, 5], 'is_cancel' => 0, 'is_del' => 0])) {
  374. throw new AdminException(400475);
  375. }
  376. if ($data['type'] == 1 && $delivery_code) {
  377. // 检测快递公司编码
  378. /** @var ExpressServices $expressServices */
  379. $expressServices = app()->make(ExpressServices::class);
  380. if (!$expressServices->be(['code' => $data['delivery_code']])) {
  381. throw new AdminException(410324);
  382. }
  383. }
  384. $cart_ids = $data['cart_ids'];
  385. unset($data['cart_ids']);
  386. $this->transaction(function () use ($id, $cart_ids, $orderInfo, $data) {
  387. /** @var StoreOrderSplitServices $storeOrderSplitServices */
  388. $storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
  389. //订单拆单
  390. [$splitOrderInfo, $otherOrder] = $storeOrderSplitServices->equalSplit($id, $cart_ids, $orderInfo);
  391. if ($splitOrderInfo) {
  392. $splitOrderInfo['refund_status'] = 0;
  393. //拆分订单执行发货
  394. $this->doDelivery((int)$splitOrderInfo->id, $splitOrderInfo, $data);
  395. /** @var StoreOrderStatusServices $services */
  396. $services = app()->make(StoreOrderStatusServices::class);
  397. //记录原订单状态
  398. $status_data = ['oid' => $id, 'change_time' => time()];
  399. $status_data['change_type'] = 'delivery_split';
  400. $status_data['change_message'] = '已拆分发货';
  401. $services->save($status_data);
  402. } else {
  403. $this->doDelivery($id, $orderInfo, $data);
  404. }
  405. });
  406. return true;
  407. }
  408. /**
  409. * 具体执行发货
  410. * @param int $id
  411. * @param $orderInfo
  412. * @param array $data
  413. * @return array
  414. */
  415. public function doDelivery(int $id, $orderInfo, array $data)
  416. {
  417. $type = (int)$data['type'];
  418. unset($data['type']);
  419. //获取购物车内的商品标题
  420. /** @var StoreOrderCartInfoServices $orderInfoServices */
  421. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  422. $storeName = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id);
  423. if (isset($data['pickup_time']) && count($data['pickup_time']) == 2) {
  424. $data['pickup_start_time'] = $data['pickup_time'][0];
  425. $data['pickup_end_time'] = $data['pickup_time'][1];
  426. } else {
  427. $data['pickup_start_time'] = '';
  428. $data['pickup_end_time'] = '';
  429. }
  430. // 发货信息录入
  431. $res = [];
  432. switch ($type) {
  433. case 1://快递发货
  434. $res = $this->orderDeliverGoods($id, $data, $orderInfo, $storeName);
  435. event('NoticeListener', [['orderInfo' => $orderInfo, 'storeName' => $storeName, 'data' => $data], 'order_postage_success']);
  436. //自定义消息-快递发货
  437. $orderInfo['storeName'] = $storeName;
  438. $orderInfo['delivery_name'] = $data['delivery_name'];
  439. $orderInfo['delivery_id'] = $data['delivery_id'];
  440. $orderInfo['time'] = date('Y-m-d H:i:s');
  441. $orderInfo['phone'] = $orderInfo['user_phone'];
  442. event('CustomNoticeListener', [$orderInfo['uid'], $orderInfo, 'order_express_success']);
  443. break;
  444. case 2://配送
  445. $this->orderDelivery($id, $data, $orderInfo, $storeName);
  446. event('NoticeListener', [['orderInfo' => $orderInfo, 'storeName' => $storeName, 'data' => $data], 'order_deliver_success']);
  447. //自定义消息-配送员配送
  448. $orderInfo['storeName'] = $storeName;
  449. $orderInfo['delivery_name'] = $data['delivery_name'];
  450. $orderInfo['delivery_id'] = $data['delivery_id'];
  451. $orderInfo['time'] = date('Y-m-d H:i:s');
  452. $orderInfo['phone'] = $orderInfo['user_phone'];
  453. event('CustomNoticeListener', [$orderInfo['uid'], $orderInfo, 'order_send_success']);
  454. break;
  455. case 3://虚拟发货
  456. $this->orderVirtualDelivery($id, $data, $orderInfo, $storeName);
  457. break;
  458. default:
  459. throw new AdminException(400522);
  460. }
  461. if (!$data['delivery_id'] && !empty($res['kuaidinum'])) {
  462. $data['delivery_id'] = $res['kuaidinum'];
  463. }
  464. if (!$data['delivery_id']) {
  465. $data['delivery_id'] = uniqid();
  466. }
  467. // 小程序订单管理
  468. event('OrderShippingListener', ['product', $orderInfo, $type, $data['delivery_id'], $data['delivery_name']]);
  469. //到期自动收货
  470. event('OrderDeliveryListener', [$orderInfo, $storeName, $data, $type]);
  471. //自定义事件-订单发货
  472. event('CustomEventListener', ['admin_order_express', [
  473. 'uid' => $orderInfo['uid'],
  474. 'real_name' => $orderInfo['real_name'],
  475. 'user_phone' => $orderInfo['user_phone'],
  476. 'user_address' => $orderInfo['user_address'],
  477. 'order_id' => $orderInfo['order_id'],
  478. 'delivery_name' => $orderInfo['delivery_name'],
  479. 'delivery_id' => $orderInfo['delivery_id'],
  480. 'express_time' => date('Y-m-d H:i:s'),
  481. ]]);
  482. return $res;
  483. }
  484. /**
  485. * 订单快递发货
  486. * @param int $id
  487. * @param array $data
  488. */
  489. public function orderDeliverGoods(int $id, array $data, $orderInfo, $storeTitle)
  490. {
  491. /** @var StoreOrderCartInfoServices $orderInfoServices */
  492. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  493. if (!$data['delivery_name']) {
  494. throw new AdminException(400007);
  495. }
  496. $dump = [];
  497. $data['delivery_type'] = 'express';
  498. if ($data['express_record_type'] == 2) {//电子面单
  499. if (!$data['delivery_code']) {
  500. throw new AdminException(400476);
  501. }
  502. if (!$data['express_temp_id']) {
  503. throw new AdminException(400527);
  504. }
  505. if (!$data['to_name']) {
  506. throw new AdminException(400008);
  507. }
  508. if (!$data['to_tel']) {
  509. throw new AdminException(400477);
  510. }
  511. if (!$data['to_addr']) {
  512. throw new AdminException(400478);
  513. }
  514. /** @var ServeServices $expressService */
  515. $expressService = app()->make(ServeServices::class);
  516. $expData['com'] = $data['delivery_code'];
  517. $expData['to_name'] = $orderInfo->real_name;
  518. $expData['to_tel'] = $orderInfo->user_phone;
  519. $expData['to_addr'] = $orderInfo->user_address;
  520. $expData['from_name'] = $data['to_name'];
  521. $expData['from_tel'] = $data['to_tel'];
  522. $expData['from_addr'] = $data['to_addr'];
  523. $expData['siid'] = sys_config('config_export_siid');
  524. $expData['temp_id'] = $data['express_temp_id'];
  525. $expData['count'] = $orderInfo->total_num;
  526. $expData['weight'] = $this->getOrderSumWeight($id);
  527. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
  528. $expData['order_id'] = $orderInfo->order_id;
  529. if (!sys_config('config_export_open', 0)) {
  530. throw new AdminException(400528);
  531. }
  532. $dump = $expressService->express()->dump($expData);
  533. $orderInfo->delivery_id = $dump['kuaidinum'];
  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. if (!empty($dump['label'])) {
  544. $data['kuaidi_label'] = $dump['label'];
  545. }
  546. } else if ($data['express_record_type'] == 3) {
  547. //商家寄件
  548. if (!$data['delivery_code']) {
  549. throw new AdminException(400476);
  550. }
  551. if (!$data['express_temp_id']) {
  552. throw new AdminException(400527);
  553. }
  554. if (!$data['to_name']) {
  555. throw new AdminException(400008);
  556. }
  557. if (!$data['to_tel']) {
  558. throw new AdminException(400477);
  559. }
  560. if (!$data['to_addr']) {
  561. throw new AdminException(400478);
  562. }
  563. /** @var ServeServices $expressService */
  564. $expressService = app()->make(ServeServices::class);
  565. $expData['kuaidicom'] = $data['delivery_code'];
  566. $expData['man_name'] = $orderInfo->real_name;
  567. $expData['phone'] = $orderInfo->user_phone;
  568. $expData['address'] = $orderInfo->user_address;
  569. $expData['send_real_name'] = $data['to_name'];
  570. $expData['send_phone'] = $data['to_tel'];
  571. $expData['send_address'] = $data['to_addr'];
  572. $expData['temp_id'] = $data['express_temp_id'];
  573. $expData['weight'] = $this->getOrderSumWeight($id);
  574. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
  575. $expData['day_type'] = $data['day_type'];
  576. $expData['pickup_start_time'] = $data['pickup_start_time'];
  577. $expData['pickup_end_time'] = $data['pickup_end_time'];
  578. // if (!sys_config('config_shippment_open', 0)) {
  579. // throw new AdminException('商家寄件未开启无法寄件');
  580. // }
  581. $dump = $expressService->express()->shippmentCreateOrder($expData);
  582. Log::error('商家寄件返回数据:' . json_encode($dump));
  583. $orderInfo->delivery_id = $dump['kuaidinum'] ?? '';
  584. $data['express_dump'] = json_encode([
  585. 'com' => $expData['kuaidicom'],
  586. 'from_name' => $expData['send_real_name'],
  587. 'from_tel' => $expData['send_phone'],
  588. 'from_addr' => $expData['send_address'],
  589. 'temp_id' => $expData['temp_id'],
  590. 'cargo' => $expData['cargo'],
  591. ]);
  592. $data['delivery_id'] = $dump['kuaidinum'] ?? '';
  593. $data['kuaidi_label'] = $dump['label'] ?? '';
  594. $data['kuaidi_task_id'] = $dump['task_id'] ?? '';
  595. $data['kuaidi_order_id'] = $dump['order_id'] ?? '';
  596. } else {
  597. if (!$data['delivery_id']) {
  598. throw new AdminException(400531);
  599. }
  600. $orderInfo->delivery_id = $data['delivery_id'];
  601. }
  602. if ($data['express_record_type'] != 3) {
  603. $data['status'] = 1;
  604. $orderInfo->delivery_type = $data['delivery_type'];
  605. $orderInfo->delivery_name = $data['delivery_name'];
  606. $orderInfo->status = $data['status'];
  607. /** @var StoreOrderStatusServices $services */
  608. $services = app()->make(StoreOrderStatusServices::class);
  609. $this->transaction(function () use ($id, $data, $services) {
  610. $res = $this->dao->update($id, $data);
  611. $res = $res && $services->save([
  612. 'oid' => $id,
  613. 'change_time' => time(),
  614. 'change_type' => 'delivery_goods',
  615. 'change_message' => '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  616. ]);
  617. if (!$res) {
  618. throw new AdminException(400529);
  619. }
  620. });
  621. } else {
  622. $update = [
  623. 'is_stock_up' => 1,
  624. 'delivery_type' => $data['delivery_type'],
  625. 'delivery_name' => $data['delivery_name'],
  626. 'delivery_code' => $data['delivery_code'],
  627. 'delivery_id' => $data['delivery_id'],
  628. 'kuaidi_label' => $data['kuaidi_label'],
  629. 'kuaidi_task_id' => $data['kuaidi_task_id'],
  630. 'kuaidi_order_id' => $data['kuaidi_order_id'],
  631. 'express_dump' => $data['express_dump']
  632. ];
  633. /** @var StoreOrderStatusServices $services */
  634. $services = app()->make(StoreOrderStatusServices::class);
  635. $this->transaction(function () use ($id, $data, $services, $update) {
  636. $res = $this->dao->update($id, $update);
  637. $res = $res && $services->save([
  638. 'oid' => $id,
  639. 'change_time' => time(),
  640. 'change_type' => 'stock_up_goods',
  641. 'change_message' => '备货中 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  642. ]);
  643. if (!$res) {
  644. throw new AdminException(400529);
  645. }
  646. });
  647. }
  648. return $dump;
  649. }
  650. /**
  651. * 返回订单商品总重量
  652. * @param int $id
  653. * @return int|string
  654. */
  655. public function getOrderSumWeight(int $id, $default = false)
  656. {
  657. /** @var StoreOrderCartInfoServices $services */
  658. $services = app()->make(StoreOrderCartInfoServices::class);
  659. $orderGoodInfo = $services->getOrderCartInfo((int)$id);
  660. $weight = 0;
  661. foreach ($orderGoodInfo as $cartInfo) {
  662. $cart = $cartInfo['cart_info'] ?? [];
  663. if ($cart) {
  664. $weight = bcadd((string)$weight, (string)bcmul((string)$cart['cart_num'] ?? '0', (string)$cart['productInfo']['attrInfo']['weight'] ?? '0', 4), 2);
  665. }
  666. }
  667. return $weight ?: ($default === false ? 0 : $default);
  668. }
  669. /**
  670. * 虚拟商品自动发货
  671. * @param $orderInfo
  672. * @throws \ReflectionException
  673. */
  674. public function virtualSend($orderInfo)
  675. {
  676. /** @var StoreOrderStatusServices $statusService */
  677. $statusService = app()->make(StoreOrderStatusServices::class);
  678. /** @var StoreOrderCartInfoServices $services */
  679. $services = app()->make(StoreOrderCartInfoServices::class);
  680. $orderInfo['cart_info'] = $services->getOrderCartInfo((int)$orderInfo['id']);
  681. $activityStatus = $orderInfo['combination_id'] || $orderInfo['seckill_id'] || $orderInfo['bargain_id'];
  682. if ($orderInfo['virtual_type'] == 1) {
  683. /** @var StoreOrderServices $orderService */
  684. $orderService = app()->make(StoreOrderServices::class);
  685. $sku = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['suk'];
  686. if ($activityStatus) {
  687. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  688. /** @var StoreProductAttrValueServices $attrValue */
  689. $attrValue = app()->make(StoreProductAttrValueServices::class);
  690. $disk_info = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'disk_info');
  691. } else {
  692. $disk_info = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['disk_info'];
  693. }
  694. if ($disk_info != '') {
  695. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $disk_info, 'remark' => '密钥自动发放:' . $disk_info]);
  696. $this->SystemSend($orderInfo['uid'], [
  697. 'mark' => 'virtual_info',
  698. 'title' => '虚拟密钥发放',
  699. 'content' => '您购买的密钥商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',密钥:' . $disk_info . ',感谢您的光临!'
  700. ]);
  701. } else {
  702. if ($activityStatus) {
  703. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  704. /** @var StoreProductAttrValueServices $attrValue */
  705. $attrValue = app()->make(StoreProductAttrValueServices::class);
  706. $unique = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'unique');
  707. } else {
  708. $unique = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['unique'];
  709. }
  710. /** @var StoreProductVirtualServices $virtualService */
  711. $virtualService = app()->make(StoreProductVirtualServices::class);
  712. $virtual = $virtualService->get(['attr_unique' => $unique, 'uid' => 0]);
  713. if (!$virtual) throw new ApiException(100026);
  714. $virtual->order_id = $orderInfo['order_id'];
  715. $virtual->uid = $orderInfo['uid'];
  716. $virtual->save();
  717. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $virtual->card_unique, 'remark' => '卡密已自动发放,卡号:' . $virtual->card_no . ';密码:' . $virtual->card_pwd]);
  718. $this->SystemSend($orderInfo['uid'], [
  719. 'mark' => 'virtual_info',
  720. 'title' => '虚拟卡密发放',
  721. 'content' => '您购买的卡密商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',卡号:' . $virtual->card_no . ';密码:' . $virtual->card_pwd . ',感谢您的光临!'
  722. ]);
  723. }
  724. $statusService->save([
  725. 'oid' => $orderInfo['id'],
  726. 'change_type' => 'delivery_fictitious',
  727. 'change_message' => '卡密自动发货',
  728. 'change_time' => time()
  729. ]);
  730. } elseif ($orderInfo['virtual_type'] == 2) {
  731. if ($activityStatus) {
  732. $sku = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['suk'];
  733. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  734. /** @var StoreProductAttrValueServices $attrValue */
  735. $attrValue = app()->make(StoreProductAttrValueServices::class);
  736. $coupon_id = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'coupon_id');
  737. } else {
  738. $coupon_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['coupon_id'];
  739. }
  740. /** @var StoreCouponIssueServices $issueService */
  741. $issueService = app()->make(StoreCouponIssueServices::class);
  742. $coupon = $issueService->get($coupon_id);
  743. if ($issueService->setCoupon($coupon, [$orderInfo['uid']])) {
  744. /** @var StoreOrderServices $orderService */
  745. $orderService = app()->make(StoreOrderServices::class);
  746. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $coupon_id, 'remark' => '优惠券已自动发放']);
  747. $this->SystemSend($orderInfo['uid'], [
  748. 'mark' => 'virtual_info',
  749. 'title' => '购买优惠券发放',
  750. 'content' => '您购买的优惠券已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号' . $orderInfo['order_id'] . '请在个人中心优惠券中查看,感谢您的光临!'
  751. ]);
  752. } else {
  753. throw new ApiException(410323);
  754. }
  755. $statusService->save([
  756. 'oid' => $orderInfo['id'],
  757. 'change_type' => 'delivery_fictitious',
  758. 'change_message' => '优惠券自动发货',
  759. 'change_time' => time()
  760. ]);
  761. }
  762. }
  763. /**
  764. * 虚拟商品站内信
  765. * @param int $uid
  766. * @param array $noticeInfo
  767. */
  768. public function SystemSend(int $uid, array $noticeInfo)
  769. {
  770. /** @var MessageSystemServices $MessageSystemServices */
  771. $MessageSystemServices = app()->make(MessageSystemServices::class);
  772. $data = [];
  773. $data['mark'] = $noticeInfo['mark'];
  774. $data['uid'] = $uid;
  775. $data['title'] = $noticeInfo['title'];
  776. $data['content'] = $noticeInfo['content'];
  777. $data['type'] = 1;
  778. $data['add_time'] = time();
  779. $MessageSystemServices->save($data);
  780. }
  781. }