Order.php 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  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\common\controller;
  12. use app\jobs\BatchHandleJob;
  13. use app\Request;
  14. use app\services\activity\coupon\StoreCouponIssueServices;
  15. use app\services\order\store\WriteOffOrderServices;
  16. use app\services\order\StoreOrderCartInfoServices;
  17. use app\services\order\StoreOrderCreateServices;
  18. use app\services\order\StoreOrderDeliveryServices;
  19. use app\services\order\StoreOrderRefundServices;
  20. use app\services\order\StoreOrderServices;
  21. use app\services\order\StoreOrderStatusServices;
  22. use app\services\order\StoreOrderTakeServices;
  23. use app\services\order\StoreOrderWriteOffServices;
  24. use app\services\order\StoreOrderPromotionsServices;
  25. use app\services\order\supplier\SupplierOrderServices;
  26. use app\services\pay\OrderOfflineServices;
  27. use app\services\other\queue\QueueServices;
  28. use app\services\serve\ServeServices;
  29. use app\services\other\ExpressServices;
  30. use app\services\store\SystemStoreServices;
  31. use app\services\supplier\SystemSupplierServices;
  32. use app\services\user\UserServices;
  33. use app\validate\admin\order\StoreOrderValidate;
  34. use crmeb\services\SystemConfigService;
  35. use crmeb\traits\MacroTrait;
  36. /**
  37. * Trait Order
  38. * @package app\common\controller
  39. * @property StoreOrderServices $services
  40. */
  41. trait Order
  42. {
  43. use MacroTrait;
  44. /**
  45. * 获取订单类型数量
  46. * @param Request $request
  47. * @return mixed
  48. */
  49. public function chart(Request $request)
  50. {
  51. $where = $request->getMore([
  52. ['status', ''],
  53. ['real_name', ''],
  54. ['data', '', '', 'time'],
  55. ['type', ''],
  56. ['plat_type', 0],
  57. ['pay_type', ''],
  58. ['field_key', ''],
  59. ['store_id', ''],
  60. ['supplier_id', '']
  61. ]);
  62. $where['type'] = trim($where['type']);
  63. if (!in_array($where['status'], [-1, -2, -3])) {
  64. $where['pid'] = [0, -1];
  65. }
  66. $where['type'] = trim($where['type'], ' ');
  67. $data = $this->services->orderCount($where);
  68. return app('json')->success($data);
  69. }
  70. /**
  71. * 获取订单列表
  72. * @param Request $request
  73. * @return mixed
  74. * @throws \think\db\exception\DataNotFoundException
  75. * @throws \think\db\exception\DbException
  76. * @throws \think\db\exception\ModelNotFoundException
  77. */
  78. public function lst(Request $request)
  79. {
  80. $where = $request->getMore([
  81. ['status', ''],
  82. ['real_name', ''],
  83. ['is_del', ''],
  84. ['data', '', '', 'time'],
  85. ['type', ''],
  86. ['pay_type', ''],
  87. ['plat_type', -1],
  88. ['order', ''],
  89. ['field_key', ''],
  90. ['store_id', ''],
  91. ['supplier_id', '']
  92. ]);
  93. $where['type'] = trim($where['type']);
  94. $where['is_system_del'] = 0;
  95. if ($where['store_id'] || $where['supplier_id'] || in_array($where['plat_type'], [0, 1, 2])) {
  96. $where['pid'] = 0;
  97. } elseif (!in_array($where['status'], [-1, -2, -3])) {
  98. $where['pid'] = [0, -1];
  99. }
  100. $where['type'] = trim($where['type'], ' ');
  101. return app('json')->success($this->services->getOrderList($where, ['*'], ['split' => function ($query) {
  102. $query->field('id,pid');
  103. }, 'pink', 'invoice']));
  104. }
  105. /**
  106. * 获取订单拆分子订单列表
  107. * @return mixed
  108. */
  109. public function split_order(Request $request, $id)
  110. {
  111. [$status] = $request->getMore([
  112. ['status', -1]
  113. ], true);
  114. if (!$id) {
  115. return app('json')->fail('缺少订单ID');
  116. }
  117. $where = ['pid' => $id, 'is_system_del' => 0];
  118. if (!$this->services->count($where)) {
  119. $where = ['id' => $id, 'is_system_del' => 0];
  120. }
  121. return app('json')->success($this->services->getSplitOrderList($where, ['*'], ['split', 'pink', 'invoice', 'supplier', 'store' => function ($query) {
  122. $query->field('id,name')->bind(['store_name' => 'name']);
  123. }]));
  124. }
  125. /**
  126. * 核销码核销
  127. * @param Request $request
  128. * @param WriteOffOrderServices $writeOffOrderServices
  129. * @return \think\Response
  130. * @throws \think\db\exception\DataNotFoundException
  131. * @throws \think\db\exception\DbException
  132. * @throws \think\db\exception\ModelNotFoundException
  133. */
  134. public function write_order(Request $request, WriteOffOrderServices $writeOffOrderServices)
  135. {
  136. [$code, $confirm] = $request->getMore([
  137. ['code', ''],
  138. ['confirm', 0]
  139. ], true);
  140. if (!$code) return app('json')->fail('Lack of write-off code');
  141. $orderInfo = $writeOffOrderServices->writeoffOrderInfo(0, $code, 0);
  142. if ($confirm == 0) {
  143. return app('json')->success('验证成功', $orderInfo);
  144. }
  145. $writeOffOrderServices->writeoffOrder(0, $orderInfo, [], 0);
  146. return app('json')->success('Write off successfully');
  147. }
  148. /**
  149. * 订单号核销
  150. * @param WriteOffOrderServices $writeOffOrderServices
  151. * @param $order_id
  152. * @return \think\Response
  153. * @throws \think\db\exception\DataNotFoundException
  154. * @throws \think\db\exception\DbException
  155. * @throws \think\db\exception\ModelNotFoundException
  156. */
  157. public function write_update(WriteOffOrderServices $writeOffOrderServices, $order_id)
  158. {
  159. $orderInfo = $this->services->getOne(['order_id' => $order_id, 'is_del' => 0], '*', ['pink']);
  160. if (!$orderInfo || $orderInfo->shipping_type != 2 && $orderInfo->delivery_type != 'send') {
  161. return app('json')->fail('核销订单未查到!');
  162. } else {
  163. if (!$orderInfo->verify_code) {
  164. return app('json')->fail('Lack of write-off code');
  165. }
  166. $orderInfo = $writeOffOrderServices->writeOffOrder(0, $orderInfo->toArray(), [], 0);
  167. if ($orderInfo) {
  168. return app('json')->success('Write off successfully');
  169. } else {
  170. return app('json')->fail('核销失败!');
  171. }
  172. }
  173. }
  174. /**
  175. * 修改支付金额等
  176. * @param $id
  177. * @return mixed
  178. * @throws \FormBuilder\Exception\FormBuilderException
  179. */
  180. public function edit($id)
  181. {
  182. if (!$id) return app('json')->fail('Data does not exist!');
  183. return app('json')->success($this->services->updateForm($id));
  184. }
  185. /**
  186. * 修改订单
  187. * @param $id
  188. * @return mixed
  189. */
  190. public function update($id)
  191. {
  192. if (!$id) return app('json')->fail('Missing order ID');
  193. $data = $this->request->postMore([
  194. ['order_id', ''],
  195. ['total_price', 0],
  196. ['total_postage', 0],
  197. ['pay_price', 0],
  198. ['pay_postage', 0],
  199. ['gain_integral', 0],
  200. ]);
  201. $this->validate($data, StoreOrderValidate::class);
  202. if ($data['total_price'] < 0) return app('json')->fail('Please enter the total price');
  203. if ($data['pay_price'] < 0) return app('json')->fail('Please enter the actual payment amount');
  204. $this->services->updateOrder((int)$id, $data);
  205. return app('json')->success('Modified success');
  206. }
  207. /**
  208. * 获取快递公司
  209. * @param Request $request
  210. * @param ExpressServices $services
  211. * @return mixed
  212. */
  213. public function express(Request $request, ExpressServices $services)
  214. {
  215. [$status] = $request->getMore([
  216. ['status', ''],
  217. ], true);
  218. if ($status != '' && $status != 'undefined') $data['status'] = (int)$status;
  219. $data['is_show'] = 1;
  220. return app('json')->success($services->express($data));
  221. }
  222. /**
  223. * 批量删除用户已经删除的订单
  224. * @param Request $request
  225. * @return mixed
  226. */
  227. public function del_orders(Request $request)
  228. {
  229. [$ids, $all, $where] = $request->postMore([
  230. ['ids', []],
  231. ['all', 0],
  232. ['where', []],
  233. ], true);
  234. if (!count($ids) && $all == 0) return app('json')->fail('请选择需要删除的订单');
  235. if ($this->services->getOrderIdsCount($ids) && $all == 0) return app('json')->fail('您选择的的订单存在用户未删除的订单');
  236. if ($all == 0 && $this->services->batchUpdate($ids, ['is_system_del' => 1])) return app('json')->success('删除成功');
  237. if ($all == 1) $ids = [];
  238. $type = 6;// 订单删除
  239. $where['status'] = -4;
  240. /** @var QueueServices $queueService */
  241. $queueService = app()->make(QueueServices::class);
  242. $queueService->setQueueData($where, 'id', $ids, $type);
  243. //加入队列
  244. BatchHandleJob::dispatch([false, $type]);
  245. return app('json')->success('后台程序已执行批量删除任务!');
  246. }
  247. /**
  248. * 删除订单
  249. * @param $id
  250. * @return mixed
  251. */
  252. public function del($id)
  253. {
  254. if (!$id || !($orderInfo = $this->services->get($id)))
  255. return app('json')->fail('订单不存在');
  256. if (!$orderInfo->is_del)
  257. return app('json')->fail('订单用户未删除无法删除');
  258. $orderInfo->is_system_del = 1;
  259. if ($orderInfo->save())
  260. return app('json')->success('SUCCESS');
  261. else
  262. return app('json')->fail('ERROR');
  263. }
  264. /**
  265. * 订单发送货
  266. * @param Request $request
  267. * @param StoreOrderDeliveryServices $services
  268. * @param $id
  269. * @return mixed
  270. * @throws \think\db\exception\DataNotFoundException
  271. * @throws \think\db\exception\DbException
  272. * @throws \think\db\exception\ModelNotFoundException
  273. */
  274. public function update_delivery(Request $request, StoreOrderDeliveryServices $services, $id)
  275. {
  276. $data = $request->postMore([
  277. ['type', 1],
  278. ['delivery_name', ''],//快递公司名称
  279. ['delivery_id', ''],//快递单号
  280. ['delivery_code', ''],//快递公司编码
  281. ['express_record_type', 2],//发货记录类型
  282. ['express_temp_id', ""],//电子面单模板
  283. ['to_name', ''],//寄件人姓名
  284. ['to_tel', ''],//寄件人电话
  285. ['to_addr', ''],//寄件人地址
  286. ['sh_delivery_name', ''],//送货人姓名
  287. ['sh_delivery_id', ''],//送货人电话
  288. ['sh_delivery_uid', ''],//送货人ID
  289. ['delivery_type', 1],//送货类型
  290. ['station_type', 1],//送货类型
  291. ['cargo_weight', 0],//重量
  292. ['mark', '', '', 'remark'],//管理员备注
  293. ['remark', '', '', 'delivery_remark'],//第三方配送备注
  294. ['fictitious_content', '']//虚拟发货内容
  295. ]);
  296. if (!$id) {
  297. return app('json')->fail('缺少发货ID');
  298. }
  299. return app('json')->success('SUCCESS', $services->delivery((int)$id, $data));
  300. }
  301. /**
  302. * 订单拆单发送货
  303. * @param Request $request
  304. * @param StoreOrderDeliveryServices $services
  305. * @param $id
  306. * @return mixed
  307. * @throws \think\db\exception\DataNotFoundException
  308. * @throws \think\db\exception\DbException
  309. * @throws \think\db\exception\ModelNotFoundException
  310. */
  311. public function split_delivery(Request $request, StoreOrderDeliveryServices $services, $id)
  312. {
  313. $data = $request->postMore([
  314. ['type', 1],
  315. ['delivery_name', ''],//快递公司名称
  316. ['delivery_id', ''],//快递单号
  317. ['delivery_code', ''],//快递公司编码
  318. ['express_record_type', 2],//发货记录类型
  319. ['express_temp_id', ""],//电子面单模板
  320. ['to_name', ''],//寄件人姓名
  321. ['to_tel', ''],//寄件人电话
  322. ['to_addr', ''],//寄件人地址
  323. ['sh_delivery_name', ''],//送货人姓名
  324. ['sh_delivery_id', ''],//送货人电话
  325. ['sh_delivery_uid', ''],//送货人ID
  326. ['delivery_type', 1],//送货类型
  327. ['station_type', 1],//送货类型
  328. ['cargo_weight', 0],//重量
  329. ['mark', ''],//备注
  330. ['remark', ''],//配送备注
  331. ['fictitious_content', ''],//虚拟发货内容
  332. ['cart_ids', []]
  333. ]);
  334. if (!$id) {
  335. return app('json')->fail('缺少发货ID');
  336. }
  337. if (!$data['cart_ids']) {
  338. return app('json')->fail('请选择发货商品');
  339. }
  340. foreach ($data['cart_ids'] as $cart) {
  341. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
  342. return app('json')->fail('请重新选择发货商品,或发货件数');
  343. }
  344. }
  345. $services->splitDelivery((int)$id, $data);
  346. return app('json')->success('SUCCESS');
  347. }
  348. /**
  349. * 获取订单可拆分发货商品列表
  350. * @param StoreOrderCartInfoServices $services
  351. * @param $id
  352. * @return mixed
  353. */
  354. public function split_cart_info(StoreOrderCartInfoServices $services, $id)
  355. {
  356. if (!$id) {
  357. return app('json')->fail('缺少发货ID');
  358. }
  359. return app('json')->success($services->getSplitCartList((int)$id));
  360. }
  361. /**
  362. * 获取核销订单商品列表
  363. * @param Request $request
  364. * @param WriteOffOrderServices $writeOffOrderServices
  365. * @return mixed
  366. * @throws \think\db\exception\DataNotFoundException
  367. * @throws \think\db\exception\DbException
  368. * @throws \think\db\exception\ModelNotFoundException
  369. */
  370. public function orderCartInfo(Request $request, WriteOffOrderServices $writeOffOrderServices)
  371. {
  372. [$oid] = $request->postMore([
  373. ['oid', '']
  374. ], true);
  375. return app('json')->success($writeOffOrderServices->getOrderCartInfo(0, (int)$oid, 1, (int)$this->storeStaffId));
  376. }
  377. /**
  378. * 核销订单
  379. * @param Request $request
  380. * @param WriteOffOrderServices $writeOffOrderServices
  381. * @param $order_id
  382. * @return mixed
  383. * @throws \think\db\exception\DataNotFoundException
  384. * @throws \think\db\exception\DbException
  385. * @throws \think\db\exception\ModelNotFoundException
  386. */
  387. public function wirteoff(Request $request, WriteOffOrderServices $writeOffOrderServices, $order_id)
  388. {
  389. $orderInfo = $this->services->getOne(['order_id' => $order_id, 'is_del' => 0], '*', ['pink']);
  390. if (!$orderInfo) {
  391. return app('json')->fail('核销订单未查到!');
  392. }
  393. [$cart_ids] = $request->postMore([
  394. ['cart_ids', []]
  395. ], true);
  396. if ($cart_ids) {
  397. foreach ($cart_ids as $cart) {
  398. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
  399. return app('json')->fail('请重新选择发货商品,或发货件数');
  400. }
  401. }
  402. }
  403. return app('json')->success('核销成功', $writeOffOrderServices->writeoffOrder(0, $orderInfo->toArray(), $cart_ids, 1, (int)$this->storeStaffId));
  404. }
  405. /**
  406. * 确认收货
  407. * @param StoreOrderTakeServices $services
  408. * @param $id
  409. * @return mixed
  410. */
  411. public function take_delivery(StoreOrderTakeServices $services, $id)
  412. {
  413. if (!$id) return app('json')->fail('缺少参数');
  414. $order = $this->services->get($id);
  415. if (!$order)
  416. return app('json')->fail('Data does not exist!');
  417. if ($order['status'] == 2)
  418. return app('json')->fail('不能重复收货!');
  419. if ($order['paid'] == 1 && $order['status'] == 1)
  420. $data['status'] = 2;
  421. else if ($order['pay_type'] == 'offline')
  422. $data['status'] = 2;
  423. else
  424. return app('json')->fail('请先发货或者送货!');
  425. if ($services->count(['pid' => $id])) {
  426. return app('json')->fail('该订单已拆分发货!');
  427. }
  428. if (!$this->services->update($id, $data)) {
  429. return app('json')->fail('收货失败,请稍候再试!');
  430. } else {
  431. $services->storeProductOrderUserTakeDelivery($order);
  432. return app('json')->success('收货成功');
  433. }
  434. }
  435. /**
  436. * 获取配置信息
  437. * @return mixed
  438. */
  439. public function getDeliveryInfo()
  440. {
  441. $data = SystemConfigService::more([
  442. 'config_export_temp_id',
  443. 'config_export_to_name',
  444. 'config_export_id',
  445. 'config_export_to_tel',
  446. 'config_export_to_address',
  447. 'config_export_open',
  448. 'city_delivery_status',
  449. 'self_delivery_status',
  450. 'dada_delivery_status',
  451. 'uu_delivery_status'
  452. ]);
  453. return app('json')->success([
  454. 'express_temp_id' => $data['config_export_temp_id'] ?? '',
  455. 'id' => $data['config_export_id'] ?? '',
  456. 'to_name' => $data['config_export_to_name'] ?? '',
  457. 'to_tel' => $data['config_export_to_tel'] ?? '',
  458. 'to_add' => $data['config_export_to_address'] ?? '',
  459. 'export_open' => (bool)((int)($data['config_export_open'] ?? 0)),
  460. 'city_delivery_status' => $data['city_delivery_status'] && ($data['self_delivery_status'] || $data['dada_delivery_status'] || $data['uu_delivery_status']),
  461. 'self_delivery_status' => $data['city_delivery_status'] && $data['self_delivery_status'],
  462. 'dada_delivery_status' => $data['city_delivery_status'] && $data['dada_delivery_status'],
  463. 'uu_delivery_status' => $data['city_delivery_status'] && $data['uu_delivery_status'],
  464. ]);
  465. }
  466. /**
  467. * 订单主动退款表单生成
  468. * @param StoreOrderRefundServices $services
  469. * @param $id
  470. * @return mixed
  471. * @throws \FormBuilder\Exception\FormBuilderException
  472. */
  473. public function refund(StoreOrderRefundServices $services, $id)
  474. {
  475. if (!$id) {
  476. return app('json')->fail('Data does not exist!');
  477. }
  478. return app('json')->success($services->refundOrderForm((int)$id, 'order'));
  479. }
  480. /**
  481. * 订单主动退款
  482. * @param Request $request
  483. * @param StoreOrderRefundServices $services
  484. * @param $id
  485. * @return mixed
  486. */
  487. public function update_refund(Request $request, StoreOrderRefundServices $services, StoreOrderCreateServices $storeOrderCreateServices, StoreOrderCartInfoServices $storeOrderCartInfoServices, $id)
  488. {
  489. $data = $request->postMore([
  490. ['refund_price', 0],
  491. ['type', 1]
  492. ]);
  493. if (!$id) {
  494. return $this->fail('Data does not exist!');
  495. }
  496. $data['refund_price'] = sprintf("%.2f", $data['refund_price']);
  497. $order = $this->services->get($id);
  498. if (!$order) {
  499. return $this->fail('Data does not exist!');
  500. }
  501. if ($services->count(['store_order_id' => $id, 'refund_type' => [0, 1, 2, 4, 5], 'is_cancel' => 0, 'is_del' => 1])) {
  502. return $this->fail('请先处理售后申请');
  503. }
  504. //0元退款
  505. if ($order['pay_price'] == 0 && in_array($order['refund_status'], [0, 1])) {
  506. $refund_price = 0;
  507. } else {
  508. if ($order['pay_price'] == $order['refund_price']) {
  509. return $this->fail('已退完支付金额!不能再退款了');
  510. }
  511. if (!$data['refund_price']) {
  512. return $this->fail('请输入退款金额');
  513. }
  514. $refund_price = $data['refund_price'];
  515. $data['refund_price'] = bcadd($data['refund_price'], $order['refund_price'], 2);
  516. $bj = bccomp((string)$order['pay_price'], (string)$data['refund_price'], 2);
  517. if ($bj < 0) {
  518. return $this->fail('退款金额大于支付金额,请修改退款金额');
  519. }
  520. }
  521. if ($data['type'] == 1) {
  522. $data['refund_status'] = 2;
  523. $data['refund_type'] = 6;
  524. } else if ($data['type'] == 2) {
  525. $data['refund_status'] = 0;
  526. $data['refund_type'] = 3;
  527. }
  528. $type = $data['type'];
  529. //拒绝退款
  530. if ($type == 2) {
  531. $this->services->update((int)$order['id'], ['refund_status' => 0, 'refund_type' => 3]);
  532. return app('json')->successful('修改退款状态成功!');
  533. } else {
  534. unset($data['type']);
  535. $refund_data['pay_price'] = $order['pay_price'];
  536. $refund_data['refund_price'] = $refund_price;
  537. if ($order['refund_price'] > 0) {
  538. mt_srand();
  539. $refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
  540. }
  541. //生成退款订单
  542. $refundOrderData['uid'] = $order['uid'];
  543. $refundOrderData['store_id'] = $order['store_id'];
  544. $refundOrderData['store_order_id'] = $id;
  545. $refundOrderData['refund_num'] = $order['total_num'];
  546. $refundOrderData['refund_type'] = $data['refund_type'];
  547. $refundOrderData['refund_price'] = $order['pay_price'];
  548. $refundOrderData['refunded_price'] = $refund_price;
  549. $refundOrderData['refund_reason'] = '管理员手动退款';
  550. $refundOrderData['order_id'] = $storeOrderCreateServices->getNewOrderId('');
  551. $refundOrderData['refunded_time'] = time();
  552. $refundOrderData['add_time'] = time();
  553. $cartInfos = $storeOrderCartInfoServices->getCartColunm(['oid' => $id], 'id,cart_id,cart_num,cart_info');
  554. foreach ($cartInfos as &$cartInfo) {
  555. $cartInfo['cart_info'] = is_string($cartInfo['cart_info']) ? json_decode($cartInfo['cart_info'], true) : $cartInfo['cart_info'];
  556. }
  557. $refundOrderData['cart_info'] = json_encode(array_column($cartInfos, 'cart_info'));
  558. $res = $services->save($refundOrderData);
  559. //修改订单退款状态
  560. if ($services->agreeRefund($res->id, $refund_data)) {
  561. //主动退款清楚原本退款单
  562. $services->delete(['store_order_id' => $id]);
  563. $this->services->update($id, $data);
  564. return app('json')->success('退款成功');
  565. } else {
  566. $services->storeProductOrderRefundYFasle((int)$id, $refund_price);
  567. return app('json')->fail('退款失败');
  568. }
  569. }
  570. }
  571. /**后台拆单退款
  572. * @param Request $request
  573. * @param StoreOrderRefundServices $services
  574. * @param StoreOrderCreateServices $storeOrderCreateServices
  575. * @param StoreOrderCartInfoServices $storeOrderCartInfoServices
  576. * @param $id
  577. * @return \think\Response
  578. * @throws \think\db\exception\DataNotFoundException
  579. * @throws \think\db\exception\DbException
  580. * @throws \think\db\exception\ModelNotFoundException
  581. */
  582. public function open_order_refund(Request $request, StoreOrderRefundServices $services, $id)
  583. {
  584. $data = $request->postMore([
  585. ['refund_price', 0],
  586. ['type', 1],
  587. ['is_split_order', 0],
  588. ['cart_ids', []]
  589. ]);
  590. if (!$id) {
  591. return app('json')->fail('Data does not exist!');
  592. }
  593. $data['refund_price'] = sprintf("%.2f", $data['refund_price']);
  594. $order = $this->services->get($id);
  595. if (!$order) {
  596. return $this->fail('Data does not exist!');
  597. }
  598. if ($services->count(['store_order_id' => $id, 'refund_type' => [0, 1, 2, 4, 5], 'is_cancel' => 0, 'is_del' => 1])) {
  599. return $this->fail('请先处理售后申请');
  600. }
  601. //0元退款
  602. if ($order['pay_price'] == 0 && in_array($order['refund_status'], [0, 1])) {
  603. $refund_price = 0;
  604. } else {
  605. if ($order['pay_price'] == $order['refund_price']) {
  606. return $this->fail('已退完支付金额!不能再退款了');
  607. }
  608. if (!$data['refund_price']) {
  609. return $this->fail('请输入退款金额');
  610. }
  611. $refund_price = $data['refund_price'];
  612. $data['refund_price'] = bcadd($data['refund_price'], $order['refund_price'], 2);
  613. $bj = bccomp((string)$order['pay_price'], (string)$data['refund_price'], 2);
  614. if ($bj < 0) {
  615. return $this->fail('退款金额大于支付金额,请修改退款金额');
  616. }
  617. }
  618. if ($data['type'] == 1) {
  619. $data['refund_status'] = 2;
  620. $data['refund_type'] = 6;
  621. } else if ($data['type'] == 2) {
  622. $data['refund_status'] = 0;
  623. $data['refund_type'] = 3;
  624. }
  625. $type = $data['type'];
  626. if ($data['is_split_order']) {
  627. if (!$data['cart_ids']) {
  628. return app('json')->fail('请选择商品');
  629. }
  630. foreach ($data['cart_ids'] as $cart) {
  631. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
  632. return app('json')->fail('请重新选择商品,或件数');
  633. }
  634. }
  635. }
  636. //拒绝退款
  637. if ($type == 2) {
  638. $this->services->update((int)$order['id'], ['refund_status' => 0, 'refund_type' => 3]);
  639. return app('json')->successful('修改退款状态成功!');
  640. } else {
  641. unset($data['type']);
  642. $refund_data['pay_price'] = $order['pay_price'];
  643. $refund_data['refund_price'] = $refund_price;
  644. if ($order['refund_price'] > 0) {
  645. mt_srand();
  646. $refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
  647. }
  648. $refundId = $services->splitApplyRefund((int)$id, $order, $data['cart_ids'], $data['refund_type'], $refund_price, $data);
  649. //修改订单退款状态
  650. if ($services->agreeRefund($refundId, $refund_data)) {
  651. //主动退款清楚原本退款单
  652. $services->delete(['store_order_id' => $id]);
  653. if ($data['is_split_order']) {
  654. $services->update($refundId, $data);
  655. } else {
  656. $this->services->update($id, $data);
  657. }
  658. return app('json')->success('退款成功');
  659. } else {
  660. $services->storeProductOrderRefundYFasle((int)$id, $refund_price);
  661. return app('json')->fail('退款失败');
  662. }
  663. }
  664. }
  665. /**
  666. * 订单详情
  667. * @param $id
  668. * @return mixed
  669. */
  670. public function order_info($id)
  671. {
  672. if (!$id || !($orderInfo = $this->services->get($id, ['*'], ['invoice', 'virtual', 'pink', 'refund', 'supplierInfo']))) {
  673. return app('json')->fail('订单不存在');
  674. }
  675. $userInfo = ['spread_uid' => '', 'spread_name' => '无'];
  676. if ($orderInfo['uid']) {
  677. /** @var UserServices $services */
  678. $services = app()->make(UserServices::class);
  679. $userInfo = $services->getUserWithTrashedInfo($orderInfo['uid']);
  680. if (!$userInfo) return app('json')->fail('用户信息不存在');
  681. $userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
  682. $userInfo = $userInfo->toArray();
  683. $userInfo['spread_name'] = '无';
  684. if ($orderInfo['spread_uid']) {
  685. $spreadName = $services->value(['uid' => $orderInfo['spread_uid']], 'nickname');
  686. if ($spreadName) {
  687. $userInfo['spread_name'] = $orderInfo['uid'] == $orderInfo['spread_uid'] ? $spreadName . '(自购)' : $spreadName;
  688. $userInfo['spread_uid'] = $orderInfo['spread_uid'];
  689. } else {
  690. $userInfo['spread_uid'] = '';
  691. }
  692. } else {
  693. $userInfo['spread_uid'] = '';
  694. }
  695. }
  696. $orderInfo = is_object($orderInfo) ? $orderInfo->toArray() : $orderInfo;
  697. $orderInfo = $this->services->tidyOrder($orderInfo, true, true);
  698. $_status = $orderInfo['_status'];
  699. [$pink_name, $color] = $this->services->tidyOrderType($orderInfo);
  700. $orderInfo['pink_name'] = $pink_name;
  701. $orderInfo['store_order_sn'] = $orderInfo['pid'] ? $this->services->value(['id' => $orderInfo['pid']], 'order_id') : '';
  702. //核算优惠金额
  703. $vipTruePrice = 0;
  704. foreach ($orderInfo['cartInfo'] ?? [] as $cart) {
  705. $vipTruePrice = bcadd((string)$vipTruePrice, (string)$cart['vip_sum_truePrice'], 2);
  706. }
  707. $orderInfo['vip_true_price'] = $vipTruePrice;
  708. // $orderInfo['total_price'] = floatval(bcsub((string)$orderInfo['total_price'], (string)$vipTruePrice, 2));
  709. //优惠活动优惠详情
  710. /** @var StoreOrderPromotionsServices $storeOrderPromotiosServices */
  711. $storeOrderPromotiosServices = app()->make(StoreOrderPromotionsServices::class);
  712. $orderInfo['promotions_detail'] = $storeOrderPromotiosServices->getOrderPromotionsDetail((int)$orderInfo['id']);
  713. if ($orderInfo['give_coupon']) {
  714. $couponIds = is_string($orderInfo['give_coupon']) ? explode(',', $orderInfo['give_coupon']) : $orderInfo['give_coupon'];
  715. /** @var StoreCouponIssueServices $couponIssueService */
  716. $couponIssueService = app()->make(StoreCouponIssueServices::class);
  717. $orderInfo['give_coupon'] = $couponIssueService->getColumn([['id', 'IN', $couponIds]], 'id,coupon_title');
  718. }
  719. $orderInfo['_store_name'] = '';
  720. if ($orderInfo['store_id'] && in_array($orderInfo['shipping_type'], [2, 4])) {
  721. /** @var $storeServices */
  722. $storeServices = app()->make(SystemStoreServices::class);
  723. $orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
  724. }
  725. $orderInfo = $this->services->tidyOrderList([$orderInfo])[0];
  726. $orderInfo['_status_new'] = $orderInfo['_status'];
  727. $orderInfo['_status'] = $_status;
  728. $refund_num = array_sum(array_column($orderInfo['refund'], 'refund_num'));
  729. $cart_num = 0;
  730. foreach ($orderInfo['_info'] as $items) {
  731. if (isset($items['cart_info']['is_gift']) && $items['cart_info']['is_gift']) continue;
  732. $cart_num += $items['cart_info']['cart_num'];
  733. }
  734. $orderInfo['is_all_refund'] = $refund_num == $cart_num;
  735. return app('json')->success(compact('orderInfo', 'userInfo'));
  736. }
  737. /**
  738. * 查询物流信息
  739. * @param ExpressServices $services
  740. * @param $id
  741. * @return mixed
  742. */
  743. public function get_express(ExpressServices $services, $id)
  744. {
  745. if (!$id || !($orderInfo = $this->services->get($id)))
  746. return app('json')->fail('订单不存在');
  747. if ($orderInfo['delivery_type'] != 'express')
  748. return app('json')->fail('该订单不是快递发货,无法查询物流信息');
  749. if (!$orderInfo['delivery_id'])
  750. return app('json')->fail('该订单不存在快递单号');
  751. $cacheName = $orderInfo['order_id'] . $orderInfo['delivery_id'];
  752. $data['delivery_name'] = $orderInfo['delivery_name'];
  753. $data['delivery_id'] = $orderInfo['delivery_id'];
  754. $data['result'] = $services->query($cacheName, $orderInfo['delivery_id'], $orderInfo['delivery_code'] ?? null);
  755. return app('json')->success($data);
  756. }
  757. /**
  758. * 获取修改配送信息表单结构
  759. * @param StoreOrderDeliveryServices $services
  760. * @param $id
  761. * @return mixed
  762. * @throws \FormBuilder\Exception\FormBuilderException
  763. */
  764. public function distribution(StoreOrderDeliveryServices $services, $id)
  765. {
  766. if (!$id) {
  767. return app('json')->fail('订单不存在');
  768. }
  769. return app('json')->success($services->distributionForm((int)$id));
  770. }
  771. /**
  772. * 修改配送信息
  773. * @param StoreOrderDeliveryServices $services
  774. * @param ExpressServices $expressServices
  775. * @param $id
  776. * @return mixed
  777. */
  778. public function update_distribution(StoreOrderDeliveryServices $services, ExpressServices $expressServices, $id)
  779. {
  780. $data = $this->request->postMore([['delivery_name', ''], ['delivery_id', '']]);
  781. if (!$id) return app('json')->fail('Data does not exist!');
  782. $orderInfo = $this->services->get((int)$id);
  783. if (!$orderInfo) {
  784. return app('json')->fail('订单不存在');
  785. }
  786. $express = [];
  787. if ($orderInfo['delivery_type'] == 'express') {
  788. $express = $expressServices->getOne(['name' => $data['delivery_name']], 'id,name,code');
  789. if (!$express) {
  790. return app('json')->fail('Data does not exist!');
  791. }
  792. }
  793. $data['delivery_code'] = $express['code'];
  794. $services->updateDistribution($id, $data);
  795. return app('json')->success('Modified success');
  796. }
  797. /**
  798. * 不退款表单结构
  799. * @param StoreOrderRefundServices $services
  800. * @param $id
  801. * @return mixed
  802. * @throws \FormBuilder\Exception\FormBuilderException
  803. */
  804. public function no_refund(StoreOrderRefundServices $services, $id)
  805. {
  806. if (!$id) return app('json')->fail('Data does not exist!');
  807. return app('json')->success($services->noRefundForm((int)$id));
  808. }
  809. /**
  810. * 订单不退款
  811. * @param StoreOrderRefundServices $services
  812. * @param $id
  813. * @return mixed
  814. */
  815. public function update_un_refund(StoreOrderRefundServices $services, $id)
  816. {
  817. if (!$id || !($orderRefundInfo = $services->get($id)))
  818. return app('json')->fail('订单不存在');
  819. [$refund_reason] = $this->request->postMore([['refund_reason', '']], true);
  820. if (!$refund_reason) {
  821. return app('json')->fail('请输入不退款原因');
  822. }
  823. $refundData = [
  824. 'refuse_reason' => $refund_reason,
  825. 'refund_type' => 3,
  826. 'refunded_time' => time()
  827. ];
  828. //拒绝退款处理
  829. $services->refuseRefund((int)$id, $refundData, $orderRefundInfo);
  830. return app('json')->success('Modified success');
  831. }
  832. /**
  833. * 线下支付
  834. * @param OrderOfflineServices $services
  835. * @param $id
  836. * @return mixed
  837. */
  838. public function pay_offline(OrderOfflineServices $services, $id)
  839. {
  840. if (!$id) return app('json')->fail('缺少参数');
  841. $res = $services->orderOffline((int)$id);
  842. if ($res) {
  843. return app('json')->success('Modified success');
  844. } else {
  845. return app('json')->fail('Modification failed');
  846. }
  847. }
  848. /**
  849. * 退积分表单获取
  850. * @param StoreOrderRefundServices $services
  851. * @param $id
  852. * @return mixed
  853. * @throws \FormBuilder\Exception\FormBuilderException
  854. */
  855. public function refund_integral(StoreOrderRefundServices $services, $id)
  856. {
  857. if (!$id)
  858. return app('json')->fail('订单不存在');
  859. return app('json')->success($services->refundIntegralForm((int)$id));
  860. }
  861. /**
  862. * 退积分保存
  863. * @param $id
  864. * @return mixed
  865. */
  866. public function update_refund_integral(StoreOrderRefundServices $services, $id)
  867. {
  868. [$back_integral] = $this->request->postMore([['back_integral', 0]], true);
  869. if (!$id || !($orderInfo = $this->services->get($id))) {
  870. return app('json')->fail('订单不存在');
  871. }
  872. if ($orderInfo->is_del) {
  873. return app('json')->fail('订单已删除无法退积分');
  874. }
  875. if ($back_integral <= 0) {
  876. return app('json')->fail('请输入积分');
  877. }
  878. if ($orderInfo['use_integral'] == $orderInfo['back_integral']) {
  879. return app('json')->fail('已退完积分!不能再积分了');
  880. }
  881. $data['back_integral'] = bcadd((string)$back_integral, (string)$orderInfo['back_integral'], 2);
  882. $bj = bccomp((string)$orderInfo['use_integral'], (string)$data['back_integral'], 2);
  883. if ($bj < 0) {
  884. return app('json')->fail('退积分大于支付积分,请修改退积分');
  885. }
  886. //积分退款处理
  887. $orderInfo->back_integral = $data['back_integral'];
  888. if ($services->refundIntegral($orderInfo, $back_integral)) {
  889. return app('json')->success('退积分成功');
  890. } else {
  891. return app('json')->fail('退积分失败');
  892. }
  893. }
  894. /**
  895. * 修改备注
  896. * @param $id
  897. * @return mixed
  898. */
  899. public function remark($id)
  900. {
  901. $data = $this->request->postMore([['remark', '']]);
  902. if (!$data['remark'])
  903. return app('json')->fail('请输入要备注的内容');
  904. if (!$id)
  905. return app('json')->fail('缺少参数');
  906. if (!$order = $this->services->get($id)) {
  907. return app('json')->fail('修改的订单不存在!');
  908. }
  909. $order->remark = $data['remark'];
  910. if ($order->save()) {
  911. return app('json')->success('备注成功');
  912. } else
  913. return app('json')->fail('备注失败');
  914. }
  915. /**
  916. * 获取订单状态列表并分页
  917. * @param $id
  918. * @return mixed
  919. */
  920. public function status(StoreOrderStatusServices $services, $id)
  921. {
  922. if (!$id) return app('json')->fail('缺少参数');
  923. return app('json')->success($services->getStatusList(['oid' => $id])['list']);
  924. }
  925. /**
  926. * 电子面单模板
  927. * @param $com
  928. * @return mixed
  929. */
  930. public function expr_temp(ServeServices $services, $com)
  931. {
  932. if (!$com) {
  933. return app('json')->fail('快递公司编号缺失');
  934. }
  935. $list = $services->express()->temp($com);
  936. return app('json')->success($list);
  937. }
  938. /**
  939. * 获取模板
  940. * @param ServeServices $services
  941. * @return mixed
  942. */
  943. public function express_temp(ServeServices $services)
  944. {
  945. $data = $this->request->getMore([['com', '']]);
  946. $tpd = $services->express()->temp($data['com']);
  947. return app('json')->success($tpd['data']);
  948. }
  949. /**
  950. * 订单发货后打印电子面单
  951. * @param $orderId
  952. * @param StoreOrderDeliveryServices $storeOrderDeliveryServices
  953. * @return mixed
  954. */
  955. public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
  956. {
  957. return app('json')->success($storeOrderDeliveryServices->orderDump($order_id));
  958. }
  959. /**手动批量发货
  960. * @return \think\Response
  961. * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
  962. * @throws \think\db\exception\DataNotFoundException
  963. * @throws \think\db\exception\DbException
  964. * @throws \think\db\exception\ModelNotFoundException
  965. */
  966. public function hand_batch_delivery()
  967. {
  968. $data = $this->request->getMore([
  969. ['file', ""]
  970. ]);
  971. if (!$data['file']) return app('json')->fail('请上传文件');
  972. $file = public_path() . substr($data['file'], 1);
  973. $type = 7;//手动批量发货
  974. /** @var QueueServices $queueService */
  975. $queueService = app()->make(QueueServices::class);
  976. $expreData = $this->services->readExpreExcel($file, 2);
  977. $queueId = $queueService->setQueueData([], false, $expreData, $type);
  978. $data['queueType'] = $type;
  979. $data['cacheType'] = 3;
  980. $data['type'] = 1;
  981. $data['queueId'] = $queueId ? $queueId : 0;
  982. $this->services->adminQueueOrderDo($data);
  983. return app('json')->success('后台程序已执行批量发货任务!');
  984. }
  985. /**
  986. * 批量手动以外发货
  987. * @return mixed
  988. * @throws \think\db\exception\DataNotFoundException
  989. * @throws \think\db\exception\DbException
  990. * @throws \think\db\exception\ModelNotFoundException
  991. */
  992. public function other_batch_delivery()
  993. {
  994. $data = $this->request->postMore([
  995. ['where', []],
  996. ['ids', []],
  997. ['express_record_type', 1],
  998. ['type', 1],
  999. ['delivery_name', ''],//快递公司名称
  1000. ['delivery_id', ''],//快递单号
  1001. ['delivery_code', ''],//快递公司编码
  1002. ['all', 0],//发货记录类型
  1003. ['express_temp_id', ""],//电子面单模板
  1004. ['to_name', ''],//寄件人姓名
  1005. ['to_tel', ''],//寄件人电话
  1006. ['to_addr', ''],//寄件人地址
  1007. ['sh_delivery_name', ''],//送货人姓名
  1008. ['sh_delivery_id', ''],//送货人电话
  1009. ['sh_delivery_uid', ''],//送货人ID
  1010. ['fictitious_content', '']//虚拟发货内容
  1011. ]);
  1012. if ($data['all'] == 0 && empty($data['ids'])) return app('json')->fail('请选择需要发货的订单');
  1013. if ($data['express_record_type'] == 2 && !sys_config('config_export_open', 0)) return app('json')->fail('请先在系统设置中打开单子面单打印开关');
  1014. if ($data['all'] == 1) $data['ids'] = [];
  1015. if ($data['type'] == 1) {//批量打印电子面单
  1016. $data['queueType'] = 8;
  1017. $data['cacheType'] = 4;
  1018. }
  1019. if ($data['type'] == 2) {//批量送货
  1020. $data['queueType'] = 9;
  1021. $data['cacheType'] = 5;
  1022. }
  1023. if ($data['type'] == 3) {//批量虚拟
  1024. $data['queueType'] = 10;
  1025. $data['cacheType'] = 6;
  1026. }
  1027. /** @var QueueServices $queueService */
  1028. $queueService = app()->make(QueueServices::class);
  1029. $queueId = $queueService->setQueueData($data['where'], 'id', $data['ids'], $data['queueType']);
  1030. $data['queueId'] = $queueId ? $queueId : 0;
  1031. /** @var StoreOrderDeliveryServices $deliveryService */
  1032. $this->services->adminQueueOrderDo($data);
  1033. return app('json')->success('后台程序已执行批量发货任务');
  1034. }
  1035. /**
  1036. * 配货单信息
  1037. * @return mixed
  1038. */
  1039. public function distributionInfo()
  1040. {
  1041. [$ids] = $this->request->postMore([
  1042. ['ids', '']
  1043. ], true);
  1044. if (!$ids) {
  1045. return app('json')->fail('缺少参数');
  1046. }
  1047. $id = explode(',', $ids);
  1048. /** @var SupplierOrderServices $supplierOrderServices */
  1049. $supplierOrderServices = app()->make(SupplierOrderServices::class);
  1050. $data = $supplierOrderServices->getDistribution($id);
  1051. $order = $data[0] ?? [];
  1052. if (!$data || !$order) {
  1053. return app('json')->fail('获取失败');
  1054. }
  1055. $res['list'] = $data;
  1056. $station = [];
  1057. if ($order['store_id']) {//门店
  1058. /** @var SystemStoreServices $storeServices */
  1059. $storeServices = app()->make(SystemStoreServices::class);
  1060. $storeInfo = $storeServices->get($order['store_id']);
  1061. $station['site_name'] = $storeInfo['name'];
  1062. $station['refund_phone'] = $storeInfo['phone'];
  1063. $station['refund_address'] = $storeInfo['detailed_address'];
  1064. } elseif ($order['supplier_id']) {//供应商
  1065. /** @var SystemSupplierServices $supplierServices */
  1066. $supplierServices = app()->make(SystemSupplierServices::class);
  1067. $supplierIno = $supplierServices->get($order['supplier_id']);
  1068. $station['site_name'] = $supplierIno['supplier_name'];
  1069. $station['refund_phone'] = $supplierIno['phone'];
  1070. $station['refund_address'] = $supplierIno['detailed_address'];
  1071. } else {//平台
  1072. $station = SystemConfigService::more(['site_name', 'refund_address', 'refund_phone']);
  1073. }
  1074. $res = array_merge($res, $station);
  1075. return app('json')->success($res);
  1076. }
  1077. }