StoreOrderDeliveryServices.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 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 bool
  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. $this->doDelivery($id, $orderInfo, $data);
  78. return true;
  79. }
  80. /**
  81. * 订单快递发货
  82. * @param int $id
  83. * @param array $data
  84. */
  85. public function orderDeliveryGoods(int $id, array $data, $orderInfo, $storeTitle)
  86. {
  87. /** @var StoreOrderCartInfoServices $orderInfoServices */
  88. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  89. if (!$data['delivery_name']) {
  90. throw new AdminException(400007);
  91. }
  92. $data['delivery_type'] = 'express';
  93. if ($data['express_record_type'] == 2) {//电子面单
  94. if (!$data['delivery_code']) {
  95. throw new AdminException(400476);
  96. }
  97. if (!$data['express_temp_id']) {
  98. throw new AdminException(400527);
  99. }
  100. if (!$data['to_name']) {
  101. throw new AdminException(400008);
  102. }
  103. if (!$data['to_tel']) {
  104. throw new AdminException(400477);
  105. }
  106. if (!$data['to_addr']) {
  107. throw new AdminException(400478);
  108. }
  109. /** @var ServeServices $expressService */
  110. $expressService = app()->make(ServeServices::class);
  111. $expData['com'] = $data['delivery_code'];
  112. $expData['to_name'] = $orderInfo->real_name;
  113. $expData['to_tel'] = $orderInfo->user_phone;
  114. $expData['to_addr'] = $orderInfo->user_address;
  115. $expData['from_name'] = $data['to_name'];
  116. $expData['from_tel'] = $data['to_tel'];
  117. $expData['from_addr'] = $data['to_addr'];
  118. $expData['siid'] = sys_config('config_export_siid');
  119. $expData['temp_id'] = $data['express_temp_id'];
  120. $expData['count'] = $orderInfo->total_num;
  121. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
  122. $expData['order_id'] = $orderInfo->order_id;
  123. if (!sys_config('config_export_open', 0)) {
  124. throw new AdminException(400528);
  125. }
  126. $dump = $expressService->express()->dump($expData);
  127. $orderInfo->delivery_id = $dump['kuaidinum'];
  128. $data['express_dump'] = json_encode([
  129. 'com' => $expData['com'],
  130. 'from_name' => $expData['from_name'],
  131. 'from_tel' => $expData['from_tel'],
  132. 'from_addr' => $expData['from_addr'],
  133. 'temp_id' => $expData['temp_id'],
  134. 'cargo' => $expData['cargo'],
  135. ]);
  136. $data['delivery_id'] = $dump['kuaidinum'];
  137. } else {
  138. if (!$data['delivery_id']) {
  139. throw new AdminException(400531);
  140. }
  141. $orderInfo->delivery_id = $data['delivery_id'];
  142. }
  143. $data['status'] = 1;
  144. $orderInfo->delivery_type = $data['delivery_type'];
  145. $orderInfo->delivery_name = $data['delivery_name'];
  146. $orderInfo->status = $data['status'];
  147. /** @var StoreOrderStatusServices $services */
  148. $services = app()->make(StoreOrderStatusServices::class);
  149. $this->transaction(function () use ($id, $data, $services) {
  150. $res = $this->dao->update($id, $data);
  151. $res = $res && $services->save([
  152. 'oid' => $id,
  153. 'change_time' => time(),
  154. 'change_type' => 'delivery_goods',
  155. 'change_message' => '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  156. ]);
  157. if (!$res) {
  158. throw new AdminException(400529);
  159. }
  160. });
  161. return true;
  162. }
  163. /**
  164. * 订单配送
  165. * @param int $id
  166. * @param array $data
  167. */
  168. public function orderDelivery(int $id, array $data, $orderInfo, string $storeTitle)
  169. {
  170. $data['delivery_type'] = 'send';
  171. $data['delivery_name'] = $data['sh_delivery_name'];
  172. $data['delivery_id'] = $data['sh_delivery_id'];
  173. $data['delivery_uid'] = $data['sh_delivery_uid'];
  174. $data['shipping_type'] = 1;
  175. //获取核销码
  176. /** @var StoreOrderCreateServices $storeOrderCreateService */
  177. $storeOrderCreateService = app()->make(StoreOrderCreateServices::class);
  178. $data['verify_code'] = $storeOrderCreateService->getStoreCode();
  179. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['sh_delivery_uid']);
  180. if (!$data['delivery_name']) {
  181. throw new AdminException(400523);
  182. }
  183. if (!$data['delivery_id']) {
  184. throw new AdminException(400524);
  185. }
  186. if (!$data['delivery_uid']) {
  187. throw new AdminException(400525);
  188. }
  189. if (!preg_match("/^1[3456789]{1}\d{9}$/", $data['delivery_id'])) {
  190. throw new AdminException(400526);
  191. }
  192. $data['status'] = 1;
  193. $orderInfo->delivery_type = $data['delivery_type'];
  194. $orderInfo->delivery_name = $data['delivery_name'];
  195. $orderInfo->delivery_id = $data['delivery_id'];
  196. $orderInfo->status = $data['status'];
  197. /** @var StoreOrderStatusServices $services */
  198. $services = app()->make(StoreOrderStatusServices::class);
  199. $this->transaction(function () use ($id, $data, $services) {
  200. $this->dao->update($id, $data);
  201. //记录订单状态
  202. $services->save([
  203. 'oid' => $id,
  204. 'change_type' => 'delivery',
  205. 'change_time' => time(),
  206. 'change_message' => '已配送 发货人:' . $data['delivery_name'] . ' 发货人电话:' . $data['delivery_id']
  207. ]);
  208. });
  209. return true;
  210. }
  211. /**
  212. * 虚拟发货
  213. * @param int $id
  214. * @param array $data
  215. */
  216. public function orderVirtualDelivery(int $id, array $data)
  217. {
  218. $data['delivery_type'] = 'fictitious';
  219. $data['status'] = 1;
  220. unset($data['sh_delivery_name'], $data['sh_delivery_id'], $data['delivery_name'], $data['delivery_id']);
  221. //保存信息
  222. /** @var StoreOrderStatusServices $services */
  223. $services = app()->make(StoreOrderStatusServices::class);
  224. $this->transaction(function () use ($id, $data, $services) {
  225. $this->dao->update($id, $data);
  226. $services->save([
  227. 'oid' => $id,
  228. 'change_type' => 'delivery_fictitious',
  229. 'change_message' => '已虚拟发货',
  230. 'change_time' => time()
  231. ]);
  232. });
  233. }
  234. /**
  235. * 获取修改配送信息表单结构
  236. * @param int $id
  237. * @return array
  238. * @throws \FormBuilder\Exception\FormBuilderException
  239. */
  240. public function distributionForm(int $id)
  241. {
  242. if (!$orderInfo = $this->dao->get($id))
  243. throw new AdminException(400118);
  244. $f[] = Form::input('order_id', '订单号', $orderInfo->getData('order_id'))->disabled(1);
  245. switch ($orderInfo['delivery_type']) {
  246. case 'send':
  247. $f[] = Form::input('delivery_name', '送货人姓名', $orderInfo->getData('delivery_name'))->required('请输入送货人姓名');
  248. $f[] = Form::input('delivery_id', '送货人电话', $orderInfo->getData('delivery_id'))->required('请输入送货人电话');
  249. break;
  250. case 'express':
  251. /** @var ExpressServices $expressServices */
  252. $expressServices = app()->make(ExpressServices::class);
  253. $f[] = Form::select('delivery_code', '快递公司', (string)$orderInfo->getData('delivery_code'))->setOptions($expressServices->expressSelectForm(['is_show' => 1]))->required('请选择快递公司')->filterable(true);
  254. $f[] = Form::input('delivery_id', '快递单号', $orderInfo->getData('delivery_id'))->required('请填写快递单号');
  255. break;
  256. }
  257. return create_form('配送信息', $f, $this->url('/order/distribution/' . $id), 'PUT');
  258. }
  259. /**
  260. * 修改配送信息
  261. * @param int $id 订单id
  262. * @return mixed
  263. */
  264. public function updateDistribution(int $id, array $data)
  265. {
  266. $order = $this->dao->get($id);
  267. if (!$order) {
  268. throw new AdminException(100026);
  269. }
  270. switch ($order['delivery_type']) {
  271. case 'send':
  272. if (!$data['delivery_name']) {
  273. throw new AdminException(400523);
  274. }
  275. if (!$data['delivery_id']) {
  276. throw new AdminException(400524);
  277. }
  278. if (!preg_match("/^1[3456789]{1}\d{9}$/", $data['delivery_id'])) {
  279. throw new AdminException(400526);
  280. }
  281. break;
  282. case 'express':
  283. if (!$data['delivery_id']) {
  284. throw new AdminException(400531);
  285. }
  286. // 检测快递公司编码
  287. /** @var ExpressServices $expressServices */
  288. $expressServices = app()->make(ExpressServices::class);
  289. if ($name = $expressServices->value(['code' => $data['delivery_code']], 'name')) {
  290. $data['delivery_name'] = $name;
  291. } else {
  292. throw new AdminException(410324);
  293. }
  294. break;
  295. case 'fictitious':
  296. throw new AdminException(400479);
  297. break;
  298. default:
  299. throw new AdminException(400480);
  300. break;
  301. }
  302. /** @var StoreOrderStatusServices $statusService */
  303. $statusService = app()->make(StoreOrderStatusServices::class);
  304. $statusService->save([
  305. 'oid' => $id,
  306. 'change_type' => 'distribution',
  307. 'change_message' => '修改发货信息为' . $data['delivery_name'] . '号' . $data['delivery_id'],
  308. 'change_time' => time()
  309. ]);
  310. return $this->dao->update($id, $data);
  311. }
  312. /**订单发货后打印电子面单
  313. * @param $orderId
  314. * @return bool|mixed
  315. */
  316. public function orderDump($orderId)
  317. {
  318. if (!$orderId) throw new AdminException(10100);
  319. /** @var StoreOrderServices $orderService */
  320. $orderService = app()->make(StoreOrderServices::class);
  321. $orderInfo = $orderService->getOne(['id' => $orderId]);
  322. if (!$orderInfo) throw new AdminException(400118);
  323. if ($orderInfo->shipping_type != 1) throw new AdminException(400481);
  324. if (!$orderInfo->express_dump) throw new AdminException(400482);
  325. if (!sys_config('config_export_open', 0)) {
  326. throw new AdminException(400483);
  327. }
  328. $dumpInfo = json_decode($orderInfo->express_dump, true);
  329. /** @var ServeServices $expressService */
  330. $expressService = app()->make(ServeServices::class);
  331. $expData['com'] = $dumpInfo['com'];
  332. $expData['to_name'] = $orderInfo->real_name;
  333. $expData['to_tel'] = $orderInfo->user_phone;
  334. $expData['to_addr'] = $orderInfo->user_address;
  335. $expData['from_name'] = $dumpInfo['from_name'];
  336. $expData['from_tel'] = $dumpInfo['from_tel'];
  337. $expData['from_addr'] = $dumpInfo['from_addr'];
  338. $expData['siid'] = sys_config('config_export_siid');
  339. $expData['temp_id'] = $dumpInfo['temp_id'];
  340. $expData['cargo'] = $dumpInfo['cargo'];
  341. $expData['count'] = $orderInfo->total_num;
  342. $expData['order_id'] = $orderInfo->order_id;
  343. return $expressService->express()->dump($expData);
  344. }
  345. /**
  346. * 订单拆单发货
  347. * @param int $id
  348. * @param array $data
  349. * @return bool
  350. */
  351. public function splitDelivery(int $id, array $data)
  352. {
  353. $orderInfo = $this->dao->get($id, ['*'], ['pink']);
  354. if (!$orderInfo) {
  355. throw new AdminException(400470);
  356. }
  357. if ($orderInfo->is_del) {
  358. throw new AdminException(400471);
  359. }
  360. if ($orderInfo->shipping_type == 2) {
  361. throw new AdminException(400473);
  362. }
  363. if (isset($orderInfo['pinkStatus']) && $orderInfo['pinkStatus'] != 2) {
  364. throw new AdminException(400474);
  365. }
  366. /** @var StoreOrderRefundServices $storeOrderRefundServices */
  367. $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
  368. if ($storeOrderRefundServices->count(['store_order_id' => $id, 'refund_type' => [1, 2, 4, 5], 'is_cancel' => 0, 'is_del' => 0])) {
  369. throw new AdminException(400475);
  370. }
  371. if ($data['type'] == 1) {
  372. // 检测快递公司编码
  373. /** @var ExpressServices $expressServices */
  374. $expressServices = app()->make(ExpressServices::class);
  375. if (!$expressServices->be(['code' => $data['delivery_code']])) {
  376. throw new AdminException(410324);
  377. }
  378. }
  379. $cart_ids = $data['cart_ids'];
  380. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  381. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  382. unset($data['cart_ids']);
  383. $this->transaction(function () use ($id, $cart_ids, $orderInfo, $data, $storeOrderCartInfoServices) {
  384. /** @var StoreOrderSplitServices $storeOrderSplitServices */
  385. $storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
  386. //订单拆单
  387. [$splitOrderInfo, $otherOrder] = $storeOrderSplitServices->equalSplit($id, $cart_ids, $orderInfo);
  388. if ($splitOrderInfo) {
  389. $splitOrderInfo['refund_status'] = 0;
  390. //拆分订单执行发货
  391. $this->doDelivery((int)$splitOrderInfo->id, $splitOrderInfo, $data);
  392. /** @var StoreOrderStatusServices $services */
  393. $services = app()->make(StoreOrderStatusServices::class);
  394. //记录原订单状态
  395. $status_data = ['oid' => $id, 'change_time' => time()];
  396. $status_data['change_type'] = 'delivery_split';
  397. $status_data['change_message'] = '已拆分发货';
  398. $services->save($status_data);
  399. } else {
  400. $this->doDelivery($id, $orderInfo, $data);
  401. }
  402. });
  403. return true;
  404. }
  405. /**
  406. * 具体执行发货
  407. * @param int $id
  408. * @param $orderInfo
  409. * @param array $data
  410. * @return bool
  411. */
  412. public function doDelivery(int $id, $orderInfo, array $data)
  413. {
  414. $type = (int)$data['type'];
  415. unset($data['type']);
  416. //获取购物车内的商品标题
  417. /** @var StoreOrderCartInfoServices $orderInfoServices */
  418. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  419. $storeName = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id);
  420. switch ($type) {
  421. case 1://快递发货
  422. $this->orderDeliverGoods($id, $data, $orderInfo, $storeName);
  423. event('notice.notice', [['orderInfo' => $orderInfo, 'storeName' => $storeName, 'data' => $data], 'order_postage_success']);
  424. break;
  425. case 2://配送
  426. $this->orderDelivery($id, $data, $orderInfo, $storeName);
  427. event('notice.notice', [['orderInfo' => $orderInfo, 'storeName' => $storeName, 'data' => $data], 'order_deliver_success']);
  428. break;
  429. case 3://虚拟发货
  430. $this->orderVirtualDelivery($id, $data, $orderInfo, $storeName);
  431. break;
  432. default:
  433. throw new AdminException(400522);
  434. }
  435. //到期自动收货
  436. event('order.orderDelivery', [$orderInfo, $storeName, $data, $type]);
  437. return true;
  438. }
  439. /**
  440. * 订单快递发货
  441. * @param int $id
  442. * @param array $data
  443. */
  444. public function orderDeliverGoods(int $id, array $data, $orderInfo, $storeTitle)
  445. {
  446. /** @var StoreOrderCartInfoServices $orderInfoServices */
  447. $orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
  448. if (!$data['delivery_name']) {
  449. throw new AdminException(400007);
  450. }
  451. $data['delivery_type'] = 'express';
  452. if ($data['express_record_type'] == 2) {//电子面单
  453. if (!$data['delivery_code']) {
  454. throw new AdminException(400476);
  455. }
  456. if (!$data['express_temp_id']) {
  457. throw new AdminException(400527);
  458. }
  459. if (!$data['to_name']) {
  460. throw new AdminException(400008);
  461. }
  462. if (!$data['to_tel']) {
  463. throw new AdminException(400477);
  464. }
  465. if (!$data['to_addr']) {
  466. throw new AdminException(400478);
  467. }
  468. /** @var ServeServices $expressService */
  469. $expressService = app()->make(ServeServices::class);
  470. $expData['com'] = $data['delivery_code'];
  471. $expData['to_name'] = $orderInfo->real_name;
  472. $expData['to_tel'] = $orderInfo->user_phone;
  473. $expData['to_addr'] = $orderInfo->user_address;
  474. $expData['from_name'] = $data['to_name'];
  475. $expData['from_tel'] = $data['to_tel'];
  476. $expData['from_addr'] = $data['to_addr'];
  477. $expData['siid'] = sys_config('config_export_siid');
  478. $expData['temp_id'] = $data['express_temp_id'];
  479. $expData['count'] = $orderInfo->total_num;
  480. $expData['weight'] = $this->getOrderSumWeight($id);
  481. $expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
  482. $expData['order_id'] = $orderInfo->order_id;
  483. if (!sys_config('config_export_open', 0)) {
  484. throw new AdminException(400528);
  485. }
  486. $dump = $expressService->express()->dump($expData);
  487. $orderInfo->delivery_id = $dump['kuaidinum'];
  488. $data['express_dump'] = json_encode([
  489. 'com' => $expData['com'],
  490. 'from_name' => $expData['from_name'],
  491. 'from_tel' => $expData['from_tel'],
  492. 'from_addr' => $expData['from_addr'],
  493. 'temp_id' => $expData['temp_id'],
  494. 'cargo' => $expData['cargo'],
  495. ]);
  496. $data['delivery_id'] = $dump['kuaidinum'];
  497. } else {
  498. if (!$data['delivery_id']) {
  499. throw new AdminException(400531);
  500. }
  501. $orderInfo->delivery_id = $data['delivery_id'];
  502. }
  503. $data['status'] = 1;
  504. $orderInfo->delivery_type = $data['delivery_type'];
  505. $orderInfo->delivery_name = $data['delivery_name'];
  506. $orderInfo->status = $data['status'];
  507. /** @var StoreOrderStatusServices $services */
  508. $services = app()->make(StoreOrderStatusServices::class);
  509. $this->transaction(function () use ($id, $data, $services) {
  510. $res = $this->dao->update($id, $data);
  511. $res = $res && $services->save([
  512. 'oid' => $id,
  513. 'change_time' => time(),
  514. 'change_type' => 'delivery_goods',
  515. 'change_message' => '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']
  516. ]);
  517. if (!$res) {
  518. throw new AdminException(400529);
  519. }
  520. });
  521. return true;
  522. }
  523. /**
  524. * 返回订单商品总重量
  525. * @param int $id
  526. * @return int|string
  527. */
  528. public function getOrderSumWeight(int $id, $default = false)
  529. {
  530. /** @var StoreOrderCartInfoServices $services */
  531. $services = app()->make(StoreOrderCartInfoServices::class);
  532. $orderGoodInfo = $services->getOrderCartInfo((int)$id);
  533. $weight = 0;
  534. foreach ($orderGoodInfo as $cartInfo) {
  535. $cart = $cartInfo['cart_info'] ?? [];
  536. if ($cart) {
  537. $weight = bcadd((string)$weight, (string)bcmul((string)$cart['cart_num'] ?? '0', (string)$cart['productInfo']['attrInfo']['weight'] ?? '0', 4), 2);
  538. }
  539. }
  540. return $weight ?: ($default === false ? 0 : $default);
  541. }
  542. /**
  543. * 虚拟商品自动发货
  544. * @param $orderInfo
  545. */
  546. public function virtualSend($orderInfo)
  547. {
  548. /** @var StoreOrderStatusServices $statusService */
  549. $statusService = app()->make(StoreOrderStatusServices::class);
  550. /** @var StoreOrderCartInfoServices $services */
  551. $services = app()->make(StoreOrderCartInfoServices::class);
  552. $orderInfo['cart_info'] = $services->getOrderCartInfo((int)$orderInfo['id']);
  553. $activityStatus = $orderInfo['combination_id'] || $orderInfo['seckill_id'] || $orderInfo['bargain_id'];
  554. if ($orderInfo['virtual_type'] == 1) {
  555. /** @var StoreOrderServices $orderService */
  556. $orderService = app()->make(StoreOrderServices::class);
  557. $sku = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['suk'];
  558. if ($activityStatus) {
  559. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  560. /** @var StoreProductAttrValueServices $attrValue */
  561. $attrValue = app()->make(StoreProductAttrValueServices::class);
  562. $disk_info = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'disk_info');
  563. } else {
  564. $disk_info = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['disk_info'];
  565. }
  566. if ($disk_info != '') {
  567. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $disk_info, 'remark' => '密钥自动发放:' . $disk_info]);
  568. $this->SystemSend($orderInfo['uid'], [
  569. 'mark' => 'virtual_info',
  570. 'title' => '虚拟密钥发放',
  571. 'content' => '您购买的密钥商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',密钥:' . $disk_info . ',感谢您的光临!'
  572. ]);
  573. } else {
  574. if ($activityStatus) {
  575. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  576. /** @var StoreProductAttrValueServices $attrValue */
  577. $attrValue = app()->make(StoreProductAttrValueServices::class);
  578. $unique = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'unique');
  579. } else {
  580. $unique = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['unique'];
  581. }
  582. /** @var StoreProductVirtualServices $virtualService */
  583. $virtualService = app()->make(StoreProductVirtualServices::class);
  584. $virtual = $virtualService->get(['attr_unique' => $unique, 'uid' => 0]);
  585. $virtual->order_id = $orderInfo['order_id'];
  586. $virtual->uid = $orderInfo['uid'];
  587. $virtual->save();
  588. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $virtual->card_unique, 'remark' => '卡密已自动发放,卡号:' . $virtual->card_no . ';密码:' . $virtual->card_pwd]);
  589. $this->SystemSend($orderInfo['uid'], [
  590. 'mark' => 'virtual_info',
  591. 'title' => '虚拟卡密发放',
  592. 'content' => '您购买的卡密商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',卡号:' . $virtual->card_no . ';密码:' . $virtual->card_pwd . ',感谢您的光临!'
  593. ]);
  594. }
  595. $statusService->save([
  596. 'oid' => $orderInfo['id'],
  597. 'change_type' => 'delivery_fictitious',
  598. 'change_message' => '卡密自动发货',
  599. 'change_time' => time()
  600. ]);
  601. } elseif ($orderInfo['virtual_type'] == 2) {
  602. if ($activityStatus) {
  603. $sku = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['suk'];
  604. $product_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['product_id'];
  605. /** @var StoreProductAttrValueServices $attrValue */
  606. $attrValue = app()->make(StoreProductAttrValueServices::class);
  607. $coupon_id = $attrValue->value(['product_id' => $product_id, 'suk' => $sku, 'type' => 0, 'is_virtual' => 1], 'coupon_id');
  608. } else {
  609. $coupon_id = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['coupon_id'];
  610. }
  611. /** @var StoreCouponIssueServices $issueService */
  612. $issueService = app()->make(StoreCouponIssueServices::class);
  613. $coupon = $issueService->get($coupon_id);
  614. if ($issueService->setCoupon($coupon, [$orderInfo['uid']])) {
  615. /** @var StoreOrderServices $orderService */
  616. $orderService = app()->make(StoreOrderServices::class);
  617. $orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => $coupon_id, 'remark' => '优惠券已自动发放']);
  618. $this->SystemSend($orderInfo['uid'], [
  619. 'mark' => 'virtual_info',
  620. 'title' => '购买优惠券发放',
  621. 'content' => '您购买的优惠券已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号' . $orderInfo['order_id'] . '请在个人中心优惠券中查看,感谢您的光临!'
  622. ]);
  623. } else {
  624. throw new ApiException(410323);
  625. }
  626. $statusService->save([
  627. 'oid' => $orderInfo['id'],
  628. 'change_type' => 'delivery_fictitious',
  629. 'change_message' => '优惠券自动发货',
  630. 'change_time' => time()
  631. ]);
  632. }
  633. }
  634. /**
  635. * 虚拟商品站内信
  636. * @param int $uid
  637. * @param array $noticeInfo
  638. */
  639. public function SystemSend(int $uid, array $noticeInfo)
  640. {
  641. /** @var MessageSystemServices $MessageSystemServices */
  642. $MessageSystemServices = app()->make(MessageSystemServices::class);
  643. $data = [];
  644. $data['mark'] = $noticeInfo['mark'];
  645. $data['uid'] = $uid;
  646. $data['title'] = $noticeInfo['title'];
  647. $data['content'] = $noticeInfo['content'];
  648. $data['type'] = 1;
  649. $data['add_time'] = time();
  650. $MessageSystemServices->save($data);
  651. }
  652. }