Order.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  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\controller\cashier;
  12. use app\common\controller\Order as CommonOrder;
  13. use app\jobs\system\SocketPushJob;
  14. use app\Request;
  15. use app\services\order\OtherOrderServices;
  16. use app\services\activity\coupon\StoreCouponIssueServices;
  17. use app\services\cashier\OrderServices;
  18. use app\services\order\cashier\CashierOrderServices;
  19. use app\services\order\cashier\StoreHangOrderServices;
  20. use app\services\order\store\WriteOffOrderServices;
  21. use app\services\order\StoreCartServices;
  22. use app\services\order\StoreOrderDeliveryServices;
  23. use app\services\order\StoreOrderRefundServices;
  24. use app\services\order\StoreOrderServices;
  25. use app\services\order\StoreOrderSplitServices;
  26. use app\services\pay\PayServices;
  27. use app\services\store\DeliveryServiceServices;
  28. use app\services\user\UserServices;
  29. use app\services\user\UserRechargeServices;
  30. use crmeb\services\AliPayService;
  31. use crmeb\services\CacheService;
  32. use crmeb\services\wechat\Payment;
  33. use think\db\exception\DataNotFoundException;
  34. use think\db\exception\ModelNotFoundException;
  35. use think\facade\App;
  36. /**
  37. * 收银台订单控制器
  38. */
  39. class Order extends AuthController
  40. {
  41. use CommonOrder;
  42. /**
  43. * StoreOrder constructor.
  44. * @param App $app
  45. * @param StoreOrderServices $service
  46. */
  47. public function __construct(App $app, StoreOrderServices $service)
  48. {
  49. parent::__construct($app);
  50. $this->services = $service;
  51. }
  52. /**
  53. * 获取收银订单用户
  54. * @param OrderServices $services
  55. * @param $storeId
  56. * @param $cashierId
  57. * @return mixed
  58. */
  59. public function getUserList(OrderServices $services, $cashierId)
  60. {
  61. $data = $services->getOrderUserList($this->storeId);
  62. return $this->success($data);
  63. }
  64. /**
  65. * 获取门店订单列表
  66. * @param Request $request
  67. * @param StoreOrderServices $services
  68. * @param UserRechargeServices $rechargeServices
  69. * @param OtherOrderServices $otherOrderServices
  70. * @param $orderType
  71. * @return mixed
  72. * @throws DataNotFoundException
  73. * @throws ModelNotFoundException
  74. * @throws \think\db\exception\DbException
  75. */
  76. public function getOrderList(Request $request, StoreOrderServices $services, UserRechargeServices $rechargeServices, OtherOrderServices $otherOrderServices, $orderType = 1)
  77. {
  78. if (!$orderType) $orderType = 1;
  79. $where = $request->postMore([
  80. ['type', ''],
  81. ['pay_type', ''],
  82. ['status', ''],
  83. ['time', ''],
  84. ['staff_id', ''],
  85. ['keyword', '', '', 'real_name']
  86. ]);
  87. if ($where['time'] && is_array($where['time']) && count($where['time']) == 2) {
  88. [$start, $end] = $where['time'];
  89. if (strtotime($start) > strtotime($end)) {
  90. return $this->fail('开始时间不能大于结束时间,请重新选择时间');
  91. }
  92. }
  93. $where['store_id'] = $this->storeId;
  94. if (!$where['real_name'] && !in_array($where['status'], [-1, -2, -3])) {
  95. $where['pid'] = 0;
  96. }
  97. switch ($orderType) {
  98. case 1:
  99. case 5:
  100. $where['is_system_del'] = 0;
  101. $with = [
  102. 'user',
  103. 'split' => function ($query) {
  104. $query->field('id,pid');
  105. },
  106. 'pink',
  107. 'invoice',
  108. 'storeStaff'
  109. ];
  110. $data = $services->getOrderList($where, ['*'], $with, true, 'add_time desc,status asc,refund_status asc');
  111. $list = $data['data'] ?? [];
  112. if ($list) {
  113. /** @var StoreCouponIssueServices $couponIssueService */
  114. $couponIssueService = app()->make(StoreCouponIssueServices::class);
  115. foreach ($list as $key => &$item) {
  116. if ($item['give_coupon']) {
  117. $couponIds = is_string($item['give_coupon']) ? explode(',', $item['give_coupon']) : $item['give_coupon'];
  118. $item['give_coupon'] = $couponIssueService->getColumn([['id', 'IN', $couponIds]], 'id,coupon_title');
  119. }
  120. }
  121. }
  122. $count = $data['count'] ?? 0;
  123. return $this->success(compact('list', 'count'));
  124. case 2:
  125. return $this->success($rechargeServices->getRechargeList($where, '*', 0, ['staff', 'user']));
  126. case 3:
  127. $where['paid'] = 1;
  128. return $this->success($otherOrderServices->getMemberRecord($where));
  129. }
  130. return $this->success(['list' => [], 'count' => 0]);
  131. }
  132. /**获取单个订单信息
  133. * @param Request $request
  134. * @param StoreOrderServices $services
  135. * @return mixed
  136. * @throws DataNotFoundException
  137. * @throws ModelNotFoundException
  138. * @throws \think\db\exception\DbException
  139. */
  140. public function getOneOrder(Request $request, StoreOrderServices $services)
  141. {
  142. $where = $request->postMore([
  143. ['order_id', ''],
  144. ['uid', '']
  145. ]);
  146. $detail = $services->getOneOrderList($where['order_id'], $where['uid'],
  147. [
  148. 'user',
  149. 'split' => function ($query) {
  150. $query->field('id,pid');
  151. },
  152. 'pink',
  153. 'invoice',
  154. 'storeStaff'
  155. ]
  156. );
  157. return $this->success($detail);
  158. }
  159. /**
  160. * 获取收银台挂单列表
  161. * @param Request $request
  162. * @param StoreHangOrderServices $services
  163. * @param int $cashierId
  164. * @return mixed
  165. * @throws DataNotFoundException
  166. * @throws ModelNotFoundException
  167. * @throws \think\db\exception\DbException
  168. */
  169. public function getHangList(Request $request, StoreHangOrderServices $services, $cashierId = 0)
  170. {
  171. $search = $request->get('keyword', '');
  172. $data = $services->getHangOrderList((int)$this->storeId, 0, $search);
  173. $data['list'] = $data['data'];
  174. unset($data['data']);
  175. return $this->success($data);
  176. }
  177. /**
  178. * 收银台退款订单列表
  179. * @param Request $request
  180. * @param StoreOrderRefundServices $service
  181. * @return mixed
  182. * @throws DataNotFoundException
  183. * @throws ModelNotFoundException
  184. * @throws \think\db\exception\DbException
  185. */
  186. public function getRefundList(Request $request, StoreOrderRefundServices $service)
  187. {
  188. $where = $request->getMore([
  189. ['keyword', '', '', 'order_id'],
  190. ['time', ''],
  191. ['refund_type', 0]
  192. ]);
  193. $where['store_id'] = $this->storeId;
  194. return $this->success($service->refundList($where));
  195. }
  196. /**
  197. * 收银台核销订单
  198. * @param Request $request
  199. * @param StoreOrderServices $services
  200. * @return mixed
  201. * @throws DataNotFoundException
  202. * @throws ModelNotFoundException
  203. * @throws \think\db\exception\DbException
  204. */
  205. public function getVerifyList(Request $request, StoreOrderServices $services)
  206. {
  207. $where = $request->postMore([
  208. ['status', ''],
  209. ['time', ''],
  210. ['staff_id', ''],
  211. ['keyword', '', '', 'real_name']
  212. ]);
  213. if ($where['time'] && is_array($where['time']) && count($where['time']) == 2) {
  214. [$start, $end] = $where['time'];
  215. if (strtotime($start) > strtotime($end)) {
  216. return $this->fail('开始时间不能大于结束时间,请重新选择时间');
  217. }
  218. }
  219. $where['is_system_del'] = 0;
  220. $where['type'] = 5;
  221. $where['store_id'] = $this->storeId;
  222. if (!$where['real_name'] && !in_array($where['status'], [-1, -2, -3])) {
  223. $where['pid'] = 0;
  224. }
  225. $result = $services->getOrderList($where, ['*'], ['split' => function ($query) {
  226. $query->field('id,pid');
  227. }, 'pink', 'invoice', 'storeStaff'], true);
  228. if ($result['data']) {
  229. /** @var StoreCouponIssueServices $couponIssueService */
  230. $couponIssueService = app()->make(StoreCouponIssueServices::class);
  231. foreach ($result['data'] as $key => &$item) {
  232. if ($item['give_coupon']) {
  233. $couponIds = is_string($item['give_coupon']) ? explode(',', $item['give_coupon']) : $item['give_coupon'];
  234. $item['give_coupon'] = $couponIssueService->getColumn([['id', 'IN', $couponIds]], 'id,coupon_title');
  235. }
  236. }
  237. }
  238. return $this->success($result);
  239. }
  240. /**
  241. * 退款订单详情
  242. * @param StoreOrderRefundServices $service
  243. * @param UserServices $userServices
  244. * @param $id
  245. * @return mixed
  246. */
  247. public function refundInfo(StoreOrderRefundServices $service, UserServices $userServices, $id)
  248. {
  249. $order = $service->refundDetail($id);
  250. $order['total_price'] = floatval(bcadd((string)$order['total_price'], (string)$order['vip_true_price'], 2));
  251. $data['orderInfo'] = $order;
  252. $userInfo = ['spread_uid' => '', 'spread_name' => '无'];
  253. if ($order['uid']) {
  254. $userInfo = $userServices->getUserWithTrashedInfo((int)$order['uid']);
  255. if (!$userInfo) return $this->fail('用户信息不存在');
  256. $userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
  257. $userInfo = $userInfo->toArray();
  258. $userInfo['spread_name'] = '无';
  259. if ($order['spread_uid']) {
  260. $spreadName = $userServices->value(['uid' => $order['spread_uid']], 'nickname');
  261. if ($spreadName) {
  262. $userInfo['spread_name'] = $order['uid'] == $order['spread_uid'] ? $spreadName . '(自购)' : $spreadName;
  263. $userInfo['spread_uid'] = $order['spread_uid'];
  264. } else {
  265. $userInfo['spread_uid'] = '';
  266. }
  267. } else {
  268. $userInfo['spread_uid'] = '';
  269. }
  270. }
  271. $data['userInfo'] = $userInfo;
  272. return $this->success('ok', $data);
  273. }
  274. /**
  275. * 加入购物车
  276. * @param Request $request
  277. * @param StoreCartServices $services
  278. * @param $uid
  279. * @return mixed
  280. * @throws DataNotFoundException
  281. * @throws ModelNotFoundException
  282. * @throws \think\db\exception\DbException
  283. */
  284. public function addCart(Request $request, StoreCartServices $services, $uid)
  285. {
  286. $where = $request->postMore([
  287. ['productId', 0],//普通商品编号
  288. [['cartNum', 'd'], 1], //购物车数量
  289. ['uniqueId', ''],//属性唯一值
  290. ['staff_id', ''],//店员ID
  291. ['secKillId', 0],//秒杀ID
  292. ['new', 1],//1直接购买,0=加入购物车
  293. ['tourist_uid', ''],//虚拟用户uid
  294. [['secKillId', 'd'], 0],//秒杀商品编号
  295. ]);
  296. $new = !!$where['new'];
  297. if (!$where['productId']) {
  298. return app('json')->fail('参数错误');
  299. }
  300. //真实用户存在,虚拟用户uid为空
  301. if ($uid) {
  302. $where['tourist_uid'] = '';
  303. }
  304. if (!$uid && !$where['tourist_uid']) {
  305. return $this->fail('缺少用户UID');
  306. }
  307. $services->setItem('store_id', $this->storeId)
  308. ->setItem('tourist_uid', $where['tourist_uid'])
  309. ->setItem('staff_id', $where['staff_id']);
  310. $activityId = $type = 0;
  311. if ($where['secKillId']) {
  312. $type = 1;
  313. $activityId = $where['secKillId'];
  314. }
  315. [$cartId, $cartNum] = $services->setCart($uid, (int)$where['productId'], (int)$where['cartNum'], $where['uniqueId'], $type, $new, (int)$activityId);
  316. $services->reset();
  317. SocketPushJob::dispatch([$this->cashierId, 'changCart', ['uid' => $uid], 'cashier']);
  318. return $this->success(['cartId' => $cartId]);
  319. }
  320. /**
  321. * 收银台更改购物车数量
  322. * @param Request $request
  323. * @param StoreCartServices $services
  324. * @param $uid
  325. * @return mixed
  326. * @throws DataNotFoundException
  327. * @throws ModelNotFoundException
  328. * @throws \think\db\exception\DbException
  329. */
  330. public function numCart(Request $request, StoreCartServices $services, $uid)
  331. {
  332. $where = $request->postMore([
  333. ['id', 0],//购物车编号
  334. ['number', 0],//购物数量
  335. ]);
  336. if (!$where['id'] || !$where['number'] || !is_numeric($where['id']) || !is_numeric($where['number'])) {
  337. return $this->fail('参数错误!');
  338. }
  339. if ($services->changeCashierCartNum((int)$where['id'], (int)$where['number'], $uid, $this->storeId)) {
  340. //发送消息
  341. SocketPushJob::dispatch([$this->cashierId, 'changCart', ['uid' => $uid], 'cashier']);
  342. return $this->success('修改成功');
  343. } else {
  344. return $this->fail('修改失败');
  345. }
  346. }
  347. /**
  348. * 收银台删除购物车信息
  349. * @param Request $request
  350. * @param StoreCartServices $services
  351. * @param $uid
  352. * @return mixed
  353. */
  354. public function delCart(Request $request, StoreCartServices $services, $uid)
  355. {
  356. $where = $request->postMore([
  357. ['ids', []],//购物车编号
  358. ]);
  359. if (!count($where['ids'])) {
  360. return $this->fail('参数错误!');
  361. }
  362. if ($services->removeUserCart((int)$uid, $where['ids'])) {
  363. //发送消息
  364. SocketPushJob::dispatch([$this->cashierId, 'changCart', ['uid' => $uid], 'cashier']);
  365. return $this->success('删除成功');
  366. } else {
  367. return $this->fail('清除失败!');
  368. }
  369. }
  370. /**
  371. * 收银台重选商品规格
  372. * @param Request $request
  373. * @param StoreCartServices $services
  374. * @return mixed
  375. */
  376. public function changeCart(Request $request, StoreCartServices $services)
  377. {
  378. [$cart_id, $product_id, $unique] = $request->postMore([
  379. ['cart_id', 0],
  380. ['product_id', 0],
  381. ['unique', '']
  382. ], true);
  383. $services->modifyCashierCart($this->storeId, (int)$cart_id, (int)$product_id, $unique);
  384. //发送消息
  385. SocketPushJob::dispatch([$this->cashierId, 'changCart', [], 'cashier']);
  386. return $this->success('重选成功');
  387. }
  388. /**
  389. * 获取购物车数据
  390. * @param Request $request
  391. * @param StoreCartServices $services
  392. * @param $uid
  393. * @param $cashierId
  394. * @return mixed
  395. * @throws \think\db\exception\DataNotFoundException
  396. * @throws \think\db\exception\DbException
  397. * @throws \think\db\exception\ModelNotFoundException
  398. */
  399. public function getCartList(Request $request, StoreCartServices $services, $uid, $cashierId)
  400. {
  401. $cartIds = $request->get('cart_ids', '');
  402. $touristUid = $request->get('tourist_uid', '');
  403. $new = $request->get('new', false);
  404. $cartIds = $cartIds ? explode(',', $cartIds) : [];
  405. if (!$touristUid && !$uid) {
  406. return $this->fail('缺少用户信息');
  407. }
  408. $result = $services->getUserCartList((int)$uid, -1, $cartIds, $this->storeId, 0, 4, (int)$touristUid, 0, $new);
  409. $result['valid'] = $services->getReturnCartList($result['valid'] ?? [], $result['promotions'] ?? []);
  410. unset($result['promotions']);
  411. return $this->success($result);
  412. }
  413. /**
  414. * 收银台计算订单金额
  415. * @param Request $request
  416. * @param CashierOrderServices $services
  417. * @param $uid
  418. * @return mixed
  419. * @throws \think\db\exception\DataNotFoundException
  420. * @throws \think\db\exception\DbException
  421. * @throws \think\db\exception\ModelNotFoundException
  422. */
  423. public function orderCompute(Request $request, CashierOrderServices $services, $uid)
  424. {
  425. [$integral, $coupon, $cartIds, $coupon_id, $new] = $request->postMore([
  426. ['integral', 0],
  427. ['coupon', 0],
  428. ['cart_id', []],
  429. ['coupon_id', 0],
  430. ['new', 0]
  431. ], true);
  432. if (!$cartIds) {
  433. return $this->fail('缺少购物车ID');
  434. }
  435. $socket = $request->post('socket', '');
  436. //发送消息
  437. if (!$socket) {
  438. SocketPushJob::dispatch([$this->cashierId, 'changCompute', [
  439. 'uid' => $uid,
  440. 'post_data' => [
  441. 'integral' => $integral,
  442. 'coupon' => $coupon,
  443. 'cart_id' => $cartIds,
  444. 'coupon_id' => $coupon_id,
  445. 'new' => $new,
  446. ],
  447. ], 'cashier']);
  448. }
  449. return $this->success($services->computeOrder((int)$uid, (int)$this->storeId, $cartIds, !!$integral, !!$coupon, [], $coupon_id, !!$new));
  450. }
  451. /**
  452. * 生成订单
  453. * @param CashierOrderServices $services
  454. * @param $uid
  455. * @return mixed
  456. */
  457. public function createOrder(CashierOrderServices $services, $uid)
  458. {
  459. [$integral, $coupon, $cartIds, $payType, $remarks, $staffId, $changePrice, $isPrice, $userCode, $coupon_id, $authCode, $touristUid, $seckillId, $collate_code_id, $new] = $this->request->postMore([
  460. ['integral', 0],
  461. ['coupon', 0],
  462. ['cart_id', []],
  463. ['pay_type', ''],
  464. ['remarks', ''],
  465. ['staff_id', 0],
  466. ['change_price', 0],
  467. ['is_price', 0],
  468. ['userCode', ''],
  469. ['coupon_id', 0],
  470. ['auth_code', ''],
  471. ['tourist_uid', ''],
  472. ['seckill_id', 0],
  473. ['collate_code_id', 0],//拼单ID 、桌码ID
  474. ['new', 0]
  475. ], true);
  476. if (!$staffId) {
  477. $staffId = $this->request->cashierId();
  478. }
  479. if (!$cartIds) {
  480. return $this->fail('缺少购物车ID');
  481. }
  482. if (!in_array($payType, ['yue', 'cash']) && $authCode) {
  483. if (Payment::isWechatAuthCode($authCode)) {
  484. $payType = PayServices::WEIXIN_PAY;
  485. } else if (AliPayService::isAliPayAuthCode($authCode)) {
  486. $payType = PayServices::ALIAPY_PAY;
  487. } else {
  488. return $this->fail('未知,付款二维码');
  489. }
  490. }
  491. $userInfo = [];
  492. if ($uid) {
  493. /** @var UserServices $userService */
  494. $userService = app()->make(UserServices::class);
  495. $userInfo = $userService->getUserInfo($uid);
  496. if (!$userInfo) {
  497. return $this->fail('用户不存在');
  498. }
  499. $userInfo = $userInfo->toArray();
  500. }
  501. $computeData = $services->computeOrder($uid, $this->storeId, $cartIds, $integral, $coupon, $userInfo, $coupon_id, !!$new);
  502. $cartInfo = $computeData['cartInfo'];
  503. try {
  504. $res = $services->transaction(function () use ($services, $userInfo, $computeData, $authCode, $uid, $staffId, $cartIds, $payType, $integral, $coupon, $remarks, $changePrice, $isPrice, $userCode, $coupon_id, $seckillId, $collate_code_id) {
  505. $orderInfo = $services->createOrder((int)$uid, $userInfo, $computeData, $this->storeId, (int)$staffId, $cartIds, $payType, !!$integral, !!$coupon, $remarks, $changePrice, !!$isPrice, $coupon_id, $seckillId, $collate_code_id);
  506. if (in_array($payType, [PayServices::YUE_PAY, PayServices::CASH_PAY, PayServices::ALIAPY_PAY, PayServices::WEIXIN_PAY])) {
  507. $res = $services->paySuccess($orderInfo['order_id'], $payType, $userCode, $authCode);
  508. $res['order_id'] = $orderInfo['order_id'];
  509. $res['oid'] = $orderInfo['id'];
  510. return $res;
  511. } else {
  512. return ['status' => 'ORDER_CREATE', 'order_id' => $orderInfo['order_id'], 'oid' => $orderInfo['id']];
  513. }
  514. });
  515. if (isset($res['status']) && $res['status'] === 'SUCCESS') {
  516. //发送消息
  517. SocketPushJob::dispatch([$this->cashierId, 'changSuccess', [], 'cashier']);
  518. CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId)->clear();
  519. }
  520. return app('json')->success($res);
  521. } catch (\Throwable $e) {
  522. //回退库存
  523. if ($seckillId) {
  524. foreach ($cartInfo as $item) {
  525. if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue;
  526. $type = $item['type'];
  527. if (in_array($type, [1, 2, 3])) CacheService::setStock($item['product_attr_unique'], (int)$item['cart_num'], $type, false);
  528. }
  529. }
  530. return app('json')->fail($e->getMessage());
  531. }
  532. }
  533. /**
  534. * 订单支付
  535. * @param CashierOrderServices $services
  536. * @param $orderId
  537. * @return mixed
  538. */
  539. public function payOrder(CashierOrderServices $services, $orderId)
  540. {
  541. if (!$orderId) {
  542. return $this->fail('缺少订单号');
  543. }
  544. $payType = $this->request->post('payType', 'yue');
  545. $userCode = $this->request->post('userCode', '');
  546. $authCode = $this->request->post('auth_code', '');
  547. $is_cashier_yue_pay_verify = (int)sys_config('is_cashier_yue_pay_verify'); // 收银台余额支付是否需要验证【是/否】
  548. if ($payType == PayServices::YUE_PAY && !$userCode && $is_cashier_yue_pay_verify) {
  549. return $this->fail('缺少用户余额支付CODE');
  550. }
  551. if (!in_array($payType, ['yue', 'cash']) && $authCode) {
  552. if (Payment::isWechatAuthCode($authCode)) {
  553. $payType = PayServices::WEIXIN_PAY;
  554. } else if (AliPayService::isAliPayAuthCode($authCode)) {
  555. $payType = PayServices::ALIAPY_PAY;
  556. } else {
  557. return $this->fail('未知,付款二维码');
  558. }
  559. }
  560. $res = $services->paySuccess($orderId, $payType, $userCode, $authCode);
  561. $res['order_id'] = $orderId;
  562. if (isset($res['status']) && $res['status'] === 'SUCCESS') {
  563. //发送消息
  564. SocketPushJob::dispatch([$this->cashierId, 'changSuccess', [], 'cashier']);
  565. CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId)->clear();
  566. }
  567. return $this->success($res);
  568. }
  569. /**
  570. * 订单核销订单数据
  571. * @param Request $request
  572. * @param WriteOffOrderServices $writeOffOrderServices
  573. * @return mixed
  574. * @throws DataNotFoundException
  575. * @throws ModelNotFoundException
  576. * @throws \think\db\exception\DbException
  577. */
  578. public function verifyCartInfo(Request $request, WriteOffOrderServices $writeOffOrderServices)
  579. {
  580. [$oid] = $request->postMore([
  581. ['oid', '']
  582. ], true);
  583. return $this->success($writeOffOrderServices->getOrderCartInfo(0, (int)$oid, 1, (int)$this->cashierId, true));
  584. }
  585. /**
  586. * 订单核销
  587. * @param Request $request
  588. * @param StoreOrderServices $services
  589. * @param WriteOffOrderServices $writeOffOrderServices
  590. * @param $id
  591. * @return mixed
  592. * @throws DataNotFoundException
  593. * @throws ModelNotFoundException
  594. * @throws \think\db\exception\DbException
  595. */
  596. public function writeOff(Request $request, StoreOrderServices $services, WriteOffOrderServices $writeOffOrderServices, $id)
  597. {
  598. if (!$id) {
  599. return $this->fail('核销订单未查到!');
  600. }
  601. [$cart_ids] = $request->postMore([
  602. ['cart_ids', []]
  603. ], true);
  604. if ($cart_ids) {
  605. foreach ($cart_ids as $cart) {
  606. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num'] || $cart['cart_num'] <= 0) {
  607. return $this->fail('请重新选择发货商品,或发货件数');
  608. }
  609. }
  610. }
  611. $orderInfo = $writeOffOrderServices->getOrderCartInfo(0, (int)$id, 1, (int)$this->cashierId);
  612. $writeOffOrderServices->writeoffOrder(0, $orderInfo, $cart_ids, 1, (int)$this->cashierId);
  613. return $this->success('核销成功');
  614. }
  615. /**
  616. * 订单可用的优惠券列表
  617. * @param Request $request
  618. * @param CashierOrderServices $services
  619. * @param $uid
  620. * @return mixed
  621. * @throws DataNotFoundException
  622. * @throws ModelNotFoundException
  623. * @throws \think\db\exception\DbException
  624. */
  625. public function couponList(Request $request, CashierOrderServices $services, $uid)
  626. {
  627. [$cartIds] = $request->postMore([
  628. ['cart_id', []],
  629. ], true);
  630. if (!$uid) return $this->success([]);
  631. return $this->success($services->getCouponList((int)$uid, $this->storeId, $cartIds));
  632. }
  633. /**
  634. * 领取优惠券
  635. *
  636. * @param Request $request
  637. * @return mixed
  638. */
  639. public function couponReceive(Request $request, StoreCouponIssueServices $storeCouponIssueServices, UserServices $userServices, $uid)
  640. {
  641. [$couponId] = $request->getMore([
  642. ['couponId', 0]
  643. ], true);
  644. if (!$uid || !$couponId || !is_numeric($couponId)) return app('json')->fail('参数错误!');
  645. $userInfo = $userServices->getUserInfo($uid);
  646. if (!$userInfo) {
  647. return app('json')->fail('请选择用户');
  648. }
  649. $coupon = $storeCouponIssueServices->issueUserCoupon((int)$couponId, $userInfo);
  650. if ($coupon) {
  651. $coupon = $coupon->toArray();
  652. return app('json')->success('领取成功', $coupon);
  653. }
  654. return app('json')->fail('领取失败');
  655. }
  656. /**
  657. * 收银台删除挂单
  658. * @param Request $request
  659. * @param StoreCartServices $services
  660. * @return mixed
  661. */
  662. public function deleteHangOrder(Request $request, StoreCartServices $services)
  663. {
  664. $id = $request->get('id');
  665. if (!$id) {
  666. return $this->fail('缺少参数');
  667. }
  668. $id = explode(',', $id) ?: [];
  669. if ($services->search(['id' => $id])->delete()) {
  670. return $this->success('删除成功');
  671. } else {
  672. return $this->fail('删除失败');
  673. }
  674. }
  675. /**
  676. * 收银台售后订单退款
  677. * @param Request $request
  678. * @param StoreOrderServices $services
  679. * @param StoreOrderRefundServices $refundService
  680. * @param $id
  681. * @return mixed
  682. * @throws DataNotFoundException
  683. * @throws ModelNotFoundException
  684. * @throws \think\db\exception\DbException
  685. */
  686. public function agreeRefund(Request $request, StoreOrderServices $services, StoreOrderRefundServices $refundService, $id)
  687. {
  688. $data = $request->postMore([
  689. ['refund_price', 0],
  690. ['type', 1]
  691. ]);
  692. if (!$id) {
  693. return $this->fail('Data does not exist!');
  694. }
  695. $orderRefund = $refundService->get($id);
  696. if (!$orderRefund) {
  697. return $this->fail('Data does not exist!');
  698. }
  699. if ($orderRefund['is_cancel'] == 1) {
  700. return $this->fail('用户已取消申请');
  701. }
  702. $order = $services->get((int)$orderRefund['store_order_id']);
  703. if (!$order) {
  704. return $this->fail('Data does not exist!');
  705. }
  706. if (!in_array($orderRefund['refund_type'], [1, 2, 5])) {
  707. return $this->fail('售后订单状态不支持该操作');
  708. }
  709. if ($data['type'] == 1) {
  710. $data['refund_type'] = 6;
  711. } else if ($data['type'] == 2) {
  712. $data['refund_type'] = 3;
  713. }
  714. $data['refunded_time'] = time();
  715. $type = $data['type'];
  716. //拒绝退款
  717. if ($type == 2) {
  718. $refundService->refuseRefund((int)$orderRefund['id'], $data, $orderRefund);
  719. return $this->success('修改退款状态成功!');
  720. } else {
  721. //0元退款
  722. if ($orderRefund['refund_price'] == 0) {
  723. $refund_price = 0;
  724. } else {
  725. if (!$data['refund_price']) {
  726. return $this->fail('请输入退款金额');
  727. }
  728. if ($orderRefund['refund_price'] == $orderRefund['refunded_price']) {
  729. return $this->fail('已退完支付金额!不能再退款了');
  730. }
  731. $refund_price = $data['refund_price'];
  732. $data['refunded_price'] = bcadd((string)$data['refund_price'], (string)$orderRefund['refunded_price'], 2);
  733. $bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
  734. if ($bj < 0) {
  735. return $this->fail('退款金额大于支付金额,请修改退款金额');
  736. }
  737. }
  738. unset($data['type']);
  739. $refund_data['pay_price'] = $order['pay_price'];
  740. $refund_data['refund_price'] = $refund_price;
  741. //修改订单退款状态
  742. unset($data['refund_price']);
  743. if ($refundService->agreeRefund($id, $refund_data)) {
  744. //退款处理
  745. $refundService->update($id, $data);
  746. return $this->success('退款成功');
  747. } else {
  748. $refundService->storeProductOrderRefundYFasle((int)$id, $refund_price);
  749. return $this->fail('退款失败');
  750. }
  751. }
  752. }
  753. /**
  754. * 收银台获取配送员
  755. * @param DeliveryServiceServices $services
  756. * @return mixed
  757. * @throws DataNotFoundException
  758. * @throws ModelNotFoundException
  759. * @throws \think\db\exception\DbException
  760. */
  761. public function getDeliveryList(DeliveryServiceServices $services)
  762. {
  763. return $this->success($services->getDeliveryList(1, $this->storeId));
  764. }
  765. /**
  766. * 面单默认配置信息
  767. * @return mixed
  768. */
  769. public function getSheetInfo()
  770. {
  771. return $this->success([
  772. 'express_temp_id' => store_config($this->storeId, 'store_config_export_temp_id'),
  773. 'id' => store_config($this->storeId, 'store_config_export_id'),
  774. 'to_name' => store_config($this->storeId, 'store_config_export_to_name'),
  775. 'to_tel' => store_config($this->storeId, 'store_config_export_to_tel'),
  776. 'to_add' => store_config($this->storeId, 'store_config_export_to_address'),
  777. 'export_open' => (bool)store_config($this->storeId, 'store_config_export_open')
  778. ]);
  779. }
  780. /**
  781. * 收银台订单发货
  782. * @param Request $request
  783. * @param StoreOrderDeliveryServices $services
  784. * @param $id
  785. * @return mixed
  786. * @throws DataNotFoundException
  787. * @throws ModelNotFoundException
  788. * @throws \think\db\exception\DbException
  789. */
  790. public function updateDelivery(Request $request, StoreOrderDeliveryServices $services, $id)
  791. {
  792. $data = $request->postMore([
  793. ['type', 1],
  794. ['delivery_name', ''],//快递公司名称
  795. ['delivery_id', ''],//快递单号
  796. ['delivery_code', ''],//快递公司编码
  797. ['express_record_type', 2],//发货记录类型
  798. ['express_temp_id', ""],//电子面单模板
  799. ['to_name', ''],//寄件人姓名
  800. ['to_tel', ''],//寄件人电话
  801. ['to_addr', ''],//寄件人地址
  802. ['sh_delivery_name', ''],//送货人姓名
  803. ['sh_delivery_id', ''],//送货人电话
  804. ['sh_delivery_uid', ''],//送货人ID
  805. ['fictitious_content', ''],//虚拟发货内容
  806. ['cart_ids', []]
  807. ]);
  808. if (!$id) {
  809. return $this->fail('缺少发货ID');
  810. }
  811. if (!$data['cart_ids']) {
  812. $res = $services->delivery((int)$id, $data, $this->cashierId);
  813. return $this->success('发货成功', $res);
  814. }
  815. foreach ($data['cart_ids'] as $cart) {
  816. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
  817. return $this->fail('请重新选择发货商品,或发货件数');
  818. }
  819. }
  820. $res = $services->splitDelivery((int)$id, $data, $this->cashierId);
  821. return $this->success('发货成功', $res);
  822. }
  823. /**
  824. * 获取次卡商品核销表单
  825. * @param WriteOffOrderServices $writeOffOrderServices
  826. * @param $id
  827. * @return mixed
  828. * @throws \think\db\exception\DataNotFoundException
  829. * @throws \think\db\exception\DbException
  830. * @throws \think\db\exception\ModelNotFoundException
  831. */
  832. public function writeOrderFrom(WriteOffOrderServices $writeOffOrderServices, $id)
  833. {
  834. if (!$id) {
  835. return $this->fail('缺少核销订单ID');
  836. }
  837. [$cart_num] = $this->request->getMore([
  838. ['cart_num', 1]
  839. ], true);
  840. return $this->success($writeOffOrderServices->writeOrderFrom((int)$id, (int)$this->cashierId, (int)$cart_num));
  841. }
  842. /**
  843. * 次卡商品核销表单提交
  844. * @param WriteOffOrderServices $writeOffOrderServices
  845. * @param $id
  846. * @return \think\Response
  847. * @throws \think\db\exception\DataNotFoundException
  848. * @throws \think\db\exception\DbException
  849. * @throws \think\db\exception\ModelNotFoundException
  850. */
  851. public function writeoffFrom(WriteOffOrderServices $writeOffOrderServices, $id)
  852. {
  853. if (!$id) {
  854. return $this->fail('缺少核销订单ID');
  855. }
  856. $orderInfo = $this->services->getOne(['id' => $id, 'is_del' => 0], '*', ['pink']);
  857. if (!$orderInfo) {
  858. return $this->fail('核销订单未查到!');
  859. }
  860. $data = $this->request->postMore([
  861. ['cart_id', ''],//核销订单商品cart_id
  862. ['cart_num', 0]
  863. ]);
  864. $cart_ids[] = $data;
  865. if ($cart_ids) {
  866. foreach ($cart_ids as $cart) {
  867. if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num'] || $cart['cart_num'] <= 0) {
  868. return $this->fail('请重新选择发货商品,或发货件数');
  869. }
  870. }
  871. }
  872. return app('json')->success('核销成功', $writeOffOrderServices->writeoffOrder(0, $orderInfo->toArray(), $cart_ids, 1, (int)$this->cashierId));
  873. }
  874. /**
  875. * 易联云打印机打印
  876. * @param $id
  877. * @return mixed
  878. */
  879. public function order_print($id)
  880. {
  881. if (!$id) return app('json')->fail('缺少参数');
  882. $order = $this->services->get($id);
  883. if (!$order) {
  884. return app('json')->fail('订单没有查到,无法打印!');
  885. }
  886. $res = $this->services->orderPrint((int)$id, 1, (int)$this->storeId);
  887. if ($res) {
  888. return app('json')->success('打印成功');
  889. } else {
  890. return app('json')->fail('打印失败');
  891. }
  892. }
  893. }