StoreOrderController.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. <?php
  2. namespace app\api\controller\admin;
  3. use app\Request;
  4. use app\models\user\{
  5. User,
  6. UserBill
  7. };
  8. use crmeb\repositories\OrderRepository;
  9. use crmeb\repositories\ShortLetterRepositories;
  10. use crmeb\services\{
  11. MiniProgramService,
  12. UtilService,
  13. WechatService
  14. };
  15. use app\models\store\{
  16. StoreCart,
  17. StoreOrder,
  18. StoreOrderStatus,
  19. StorePink,
  20. StoreService
  21. };
  22. use app\models\system\SystemStoreStaff;
  23. /**
  24. * 订单类
  25. * Class StoreOrderController
  26. * @package app\api\controller\admin\order
  27. */
  28. class StoreOrderController
  29. {
  30. /**
  31. * @api {get} admin/order/statistics 订单数据统计
  32. * @apiName AdminOrderStatistics
  33. * @apiGroup Admin
  34. *
  35. * @apiParam none None
  36. * @apiSuccessExample Succeed
  37. * {
  38. * }
  39. *
  40. */
  41. public function statistics(Request $request)
  42. {
  43. $uid = $request->uid();
  44. if (!StoreService::orderServiceStatus($uid))
  45. return app('json')->fail('权限不足');
  46. $dataCount = StoreOrder::getOrderDataAdmin();
  47. $dataPrice = StoreOrder::getOrderTimeData();
  48. $data = array_merge($dataCount, $dataPrice);
  49. return app('json')->successful($data);
  50. }
  51. /**
  52. * @api {get} admin/order/data 订单每月统计数据
  53. * @apiName AdminOrderData
  54. * @apiGroup Admin
  55. */
  56. public function data(Request $request)
  57. {
  58. $uid = $request->uid();
  59. if (!StoreService::orderServiceStatus($uid))
  60. return app('json')->fail('权限不足');
  61. list($page, $limit, $start, $stop) = UtilService::getMore([
  62. ['page', 1],
  63. ['limit', 7],
  64. ['start', ''],
  65. ['stop', '']
  66. ], $request, true);
  67. if (!$limit) return app('json')->successful([]);
  68. $data = StoreOrder::getOrderDataPriceCount($page, $limit, $start, $stop);
  69. if ($data) return app('json')->successful($data->toArray());
  70. return app('json')->successful([]);
  71. }
  72. /**
  73. * @api {get} admin/order/list 订单列表
  74. * @apiName AdminOrderList
  75. * @apiGroup Admin
  76. */
  77. public function lst(Request $request)
  78. {
  79. $uid = $request->uid();
  80. if (!StoreService::orderServiceStatus($uid))
  81. return app('json')->fail('权限不足');
  82. $where = UtilService::getMore([
  83. ['status', ''],
  84. ['is_del', 0],
  85. ['data', ''],
  86. ['type', ''],
  87. ['order', ''],
  88. ['page', 0],
  89. ['limit', 0]
  90. ], $request);
  91. if (!$where['limit']) return app('json')->successful([]);
  92. return app('json')->successful(StoreOrder::orderList($where));
  93. }
  94. /**
  95. * @api {get} admin/order/detail/:orderId 订单详情
  96. * @apiName AdminOrderDetails
  97. * @apiGroup Admin
  98. */
  99. public function detail(Request $request, $orderId)
  100. {
  101. $uid = $request->uid();
  102. if ((!StoreService::orderServiceStatus($uid)) && !(SystemStoreStaff::verifyStatus($uid)))
  103. return app('json')->fail('权限不足');
  104. $order = StoreOrder::getAdminOrderDetail($orderId, 'id,uid,order_id,add_time,status,total_num,total_price,total_postage,pay_price,pay_postage,paid,refund_status,remark,pink_id,combination_id,mark,seckill_id,bargain_id,delivery_type,pay_type,real_name,user_phone,user_address,coupon_price,freight_price,delivery_name,delivery_type,delivery_id');
  105. if (!$order) return app('json')->fail('订单不存在');
  106. $order = $order->toArray();
  107. $nickname = User::getUserInfo($order['uid'], 'nickname')['nickname'];
  108. $orderInfo = StoreOrder::tidyAdminOrder([$order], true)[0];
  109. unset($orderInfo['uid'], $orderInfo['seckill_id'], $orderInfo['pink_id'], $orderInfo['combination_id'], $orderInfo['bargain_id'], $orderInfo['status'], $orderInfo['total_postage']);
  110. $orderInfo['nickname'] = $nickname;
  111. return app('json')->successful('ok', $orderInfo);
  112. }
  113. /**
  114. * @api {get} admin/order/delivery/gain/:orderId 订单发货获取订单信息
  115. * @apiName AdminOrderDeliveryGain
  116. * @apiGroup Admin
  117. */
  118. public function delivery_gain(Request $request, $orderId)
  119. {
  120. $uid = $request->uid();
  121. if (!StoreService::orderServiceStatus($uid))
  122. return app('json')->fail('权限不足');
  123. $order = StoreOrder::getAdminOrderDetail($orderId, 'real_name,user_phone,user_address,order_id,uid,status,paid');
  124. if (!$order) return app('json')->fail('订单不存在');
  125. if ($order['paid']) {
  126. $order['nickname'] = User::getUserInfo($order['uid'], 'nickname')['nickname'];
  127. $order = $order->hidden(['uid', 'status', 'paid'])->toArray();
  128. return app('json')->successful('ok', $order);
  129. }
  130. return app('json')->fail('状态错误');
  131. }
  132. /**
  133. * @api {post} admin/order/delivery/keep 订单发货
  134. * @apiName AdminOrderDeliveryKeep
  135. * @apiGroup Admin
  136. */
  137. public function delivery_keep(Request $request)
  138. {
  139. $uid = $request->uid();
  140. if (!StoreService::orderServiceStatus($uid))
  141. return app('json')->fail('权限不足');
  142. list($order_id, $delivery_type, $delivery_name, $delivery_id) = UtilService::postMore([
  143. ['order_id', ''],
  144. ['delivery_type', 0],
  145. ['delivery_name', ''],
  146. ['delivery_id', ''],
  147. ], $request, true);
  148. $order = StoreOrder::getAdminOrderDetail($order_id, 'id,status,paid');
  149. if (!$order) return app('json')->fail('订单不存在');
  150. if (!$order['status'] && $order['paid']) {
  151. $deliveryTypeArr = ['send', 'express', 'fictitious'];
  152. if (!strlen(trim($delivery_type))) return app('json')->fail('请填写发货方式');
  153. if (!in_array($delivery_type, $deliveryTypeArr)) return app('json')->fail('发货方式错误');
  154. if ($delivery_type == 'express') {
  155. if (!strlen(trim($delivery_name))) return app('json')->fail('请选择快递公司');
  156. if (!strlen(trim($delivery_id))) return app('json')->fail('请填写快递单号');
  157. }
  158. if ($delivery_type == 'send') {
  159. if (!strlen(trim($delivery_name))) return app('json')->fail('请填写发货人');
  160. if (!strlen(trim($delivery_id))) return app('json')->fail('请填写发货手机号');
  161. }
  162. $data['status'] = 1;
  163. $data['delivery_type'] = $delivery_type;
  164. $data['delivery_name'] = $delivery_name;
  165. $data['delivery_id'] = $delivery_id;
  166. $res = StoreOrder::edit($data, $order['id'], 'id');
  167. if ($res) {
  168. if ($delivery_type == 'express') {
  169. StoreOrderStatus::status($order['id'], 'delivery_goods', '已发货 快递公司:' . $data['delivery_name'] . ' 快递单号:' . $data['delivery_id']);
  170. } else if ($delivery_type == 'send') {
  171. StoreOrderStatus::status($order['id'], 'delivery', '已配送 发货人:' . $delivery_name . ' 发货人电话:' . $delivery_id);
  172. } else if ($delivery_type == 'fictitious') {
  173. StoreOrderStatus::status($order['id'], 'delivery_fictitious', '虚拟产品已发货');
  174. }
  175. }
  176. event('StoreProductOrderDeliveryGoodsAfter', [$data, $order['id']]);
  177. return app('json')->successful('发货成功!');
  178. }
  179. return app('json')->fail('状态错误');
  180. }
  181. /**
  182. * @api {post} admin/order/price 订单改价
  183. * @apiName AdminOrderPrice
  184. * @apiGroup Admin
  185. */
  186. public function price(Request $request)
  187. {
  188. $uid = $request->uid();
  189. if (!StoreService::orderServiceStatus($uid))
  190. return app('json')->fail('权限不足');
  191. list($order_id, $price) = UtilService::postMore([
  192. ['order_id', ''],
  193. ['price', '']
  194. ], $request, true);
  195. $order = StoreOrder::getAdminOrderDetail($order_id, 'id,paid,user_phone,pay_price,order_id,total_price,total_postage,pay_postage,gain_integral');
  196. if (!$order) return app('json')->fail('订单不存在');
  197. $order = $order->toArray();
  198. if (!$order['paid']) {
  199. if ($price === '') return app('json')->fail('请填写实际支付金额');
  200. if ($price < 0) return app('json')->fail('实际支付金额不能小于0元');
  201. if ($order['pay_price'] == $price) return app('json')->successful('修改成功');
  202. $order['order_id'] = StoreOrder::changeOrderId($order['order_id']);
  203. if (!StoreOrder::edit(['pay_price' => $price, 'order_id' => $order['order_id']], $order['id'], 'id'))
  204. return app('json')->fail('状态错误');
  205. $order['pay_price'] = $price;
  206. event('StoreProductOrderEditAfter', [$order, $order['id']]);
  207. StoreOrderStatus::status($order['id'], 'order_edit', '修改实际支付金额' . $price);
  208. //改价短信提醒
  209. if ($price != $order['pay_price']) {
  210. $switch = sys_config('price_revision_switch') ? true : false;
  211. ShortLetterRepositories::send($switch, $order['user_phone'], ['order_id' => $order_id, 'pay_price' => $order['pay_price']], 'PRICE_REVISION_CODE');
  212. }
  213. return app('json')->successful('修改成功');
  214. }
  215. return app('json')->fail('状态错误');
  216. }
  217. /**
  218. * @api {post} admin/order/remark 订单备注
  219. * @apiName AdminOrderRemark
  220. * @apiGroup Admin
  221. */
  222. public function remark(Request $request)
  223. {
  224. $uid = $request->uid();
  225. if (!StoreService::orderServiceStatus($uid))
  226. return app('json')->fail('权限不足');
  227. list($order_id, $remark) = UtilService::postMore([
  228. ['order_id', ''],
  229. ['remark', '']
  230. ], $request, true);
  231. $order = StoreOrder::getAdminOrderDetail($order_id, 'id');
  232. if (!$order) return app('json')->fail('订单不存在');
  233. $order = $order->toArray();
  234. if (!strlen(trim($remark))) return app('json')->fail('请填写备注内容');
  235. if (!StoreOrder::edit(['remark' => $remark], $order['id']))
  236. return app('json')->fail('备注失败');
  237. return app('json')->successful('备注成功');
  238. }
  239. /**
  240. * @api {get} admin/order/time 订单交易额/订单数量时间统计
  241. * @apiName AdminOrderTime
  242. * @apiGroup Admin
  243. */
  244. public function time(Request $request)
  245. {
  246. $uid = $request->uid();
  247. if (!StoreService::orderServiceStatus($uid))
  248. return app('json')->fail('权限不足');
  249. list($start, $stop, $type) = UtilService::getMore([
  250. ['start', strtotime(date('Y-m'))],
  251. ['stop', time()],
  252. ['type', 1]
  253. ], $request, true);
  254. if ($start == $stop) {
  255. return app('json')->fail('开始时间不能等于结束时间');
  256. }
  257. if ($start > $stop) {
  258. $middle = $stop;
  259. $stop = $start;
  260. $start = $middle;
  261. }
  262. $space = bcsub($stop, $start, 0); //间隔时间段
  263. $front = bcsub($start, $space, 0); //第一个时间段
  264. if ($type == 1) { //销售额
  265. $frontPrice = StoreOrder::getOrderTimeBusinessVolumePrice($front, $start);
  266. $afterPrice = StoreOrder::getOrderTimeBusinessVolumePrice($start, $stop);
  267. $chartInfo = StoreOrder::chartTimePrice($start, $stop);
  268. $data['chart'] = $chartInfo; //营业额图表数据
  269. $data['time'] = $afterPrice; //时间区间营业额
  270. $increase = (float)bcsub($afterPrice, $frontPrice, 2); //同比上个时间区间增长营业额
  271. $growthRate = abs($increase);
  272. if ($growthRate == 0) $data['growth_rate'] = 0;
  273. else if ($frontPrice == 0) $data['growth_rate'] = $growthRate;
  274. else $data['growth_rate'] = (int)bcmul(bcdiv($growthRate, $frontPrice, 2), 100, 0); //时间区间增长率
  275. $data['increase_time'] = abs($increase); //同比上个时间区间增长营业额
  276. $data['increase_time_status'] = $increase >= 0 ? 1 : 2; //同比上个时间区间增长营业额增长 1 减少 2
  277. } else { //订单数
  278. $frontNumber = StoreOrder::getOrderTimeBusinessVolumeNumber($front, $start);
  279. $afterNumber = StoreOrder::getOrderTimeBusinessVolumeNumber($start, $stop);
  280. $chartInfo = StoreOrder::chartTimeNumber($start, $stop);
  281. $data['chart'] = $chartInfo; //订单数图表数据
  282. $data['time'] = $afterNumber; //时间区间订单数
  283. $increase = (int)bcsub($afterNumber, $frontNumber, 0); //同比上个时间区间增长订单数
  284. $growthRate = abs($increase);
  285. if ($growthRate == 0) $data['growth_rate'] = 0;
  286. else if ($frontNumber == 0) $data['growth_rate'] = $growthRate;
  287. else $data['growth_rate'] = (int)bcmul(bcdiv($growthRate, $frontNumber, 2), 100, 0); //时间区间增长率
  288. $data['increase_time'] = abs($increase); //同比上个时间区间增长营业额
  289. $data['increase_time_status'] = $increase >= 0 ? 1 : 2; //同比上个时间区间增长营业额增长 1 减少 2
  290. }
  291. return app('json')->successful($data);
  292. }
  293. /**
  294. * @api {post} admin/order/offline' 订单支付
  295. * @apiName AdminOrderOffline
  296. * @apiGroup Admin
  297. */
  298. public function offline(Request $request)
  299. {
  300. list($orderId) = UtilService::postMore([['order_id', '']], $request, true);
  301. $orderInfo = StoreOrder::getAdminOrderDetail($orderId, 'id');
  302. if (!$orderInfo) return app('json')->fail('参数错误');
  303. $id = $orderInfo->id;
  304. $res = StoreOrder::updateOffline($id);
  305. if ($res) {
  306. event('StoreProductOrderOffline', [$id]);
  307. StoreOrderStatus::status($id, 'offline', '线下付款');
  308. return app('json')->successful('修改成功!');
  309. }
  310. return app('json')->fail(StoreOrder::getErrorInfo('修改失败!'));
  311. }
  312. /**
  313. * @api {post} admin/order/refund 订单退款
  314. * @apiName AdminOrderRefund
  315. * @apiGroup Admin
  316. */
  317. public function refund(Request $request)
  318. {
  319. list($orderId, $price, $type) = UtilService::postMore([
  320. ['order_id', ''],
  321. ['price', 0],
  322. ['type', 1],
  323. ], $request, true);
  324. if (!strlen(trim($orderId))) return app('json')->fail('参数错误');
  325. $orderInfo = StoreOrder::getAdminOrderDetail($orderId);
  326. if (!$orderInfo) return app('json')->fail('数据不存在!');
  327. $orderInfo = $orderInfo->toArray();
  328. if ($type == 1)
  329. $data['refund_status'] = 2;
  330. else if ($type == 2)
  331. $data['refund_status'] = 0;
  332. else
  333. return app('json')->fail('退款修改状态错误');
  334. if ($orderInfo['pay_price'] == 0 || $type == 2) {
  335. StoreOrder::update($data, ['order_id' => $orderId]);
  336. return app('json')->successful('修改退款状态成功!');
  337. }
  338. if ($orderInfo['pay_price'] == $orderInfo['refund_price']) return app('json')->fail('已退完支付金额!不能再退款了');
  339. if (!$price) return app('json')->fail('请输入退款金额');
  340. $data['refund_price'] = bcadd($price, $orderInfo['refund_price'], 2);
  341. $bj = bccomp((float)$orderInfo['pay_price'], (float)$data['refund_price'], 2);
  342. if ($bj < 0) return app('json')->fail('退款金额大于支付金额,请修改退款金额');
  343. $refundData['pay_price'] = $orderInfo['pay_price'];
  344. $refundData['refund_price'] = $price;
  345. if ($orderInfo['pay_type'] == 'weixin') {
  346. if ($orderInfo['is_channel'] == 1) { // 小程序
  347. try {
  348. MiniProgramService::payOrderRefund($orderInfo['order_id'], $refundData);
  349. } catch (\Exception $e) {
  350. return app('json')->fail($e->getMessage());
  351. }
  352. } else { // 公众号
  353. try {
  354. WechatService::payOrderRefund($orderInfo['order_id'], $refundData);
  355. } catch (\Exception $e) {
  356. return app('json')->fail($e->getMessage());
  357. }
  358. }
  359. } else if ($orderInfo['pay_type'] == 'yue') { //余额
  360. StoreOrder::beginTrans();
  361. $userInfo = User::getUserInfo($orderInfo['uid'], 'now_money');
  362. if (!$userInfo) {
  363. StoreOrder::rollbackTrans();
  364. return app('json')->fail('订单用户不存在');
  365. }
  366. $res1 = User::bcInc($orderInfo['uid'], 'now_money', $price, 'uid');
  367. $res2 = $res2 = UserBill::income('商品退款', $orderInfo['uid'], 'now_money', 'pay_product_refund', $price, $orderInfo['id'], bcadd($userInfo['now_money'], $price, 2), '订单退款到余额' . floatval($price) . '元');
  368. try {
  369. OrderRepository::storeOrderYueRefund($orderInfo, $refundData);
  370. } catch (\Exception $e) {
  371. StoreOrder::rollbackTrans();
  372. return app('json')->fail($e->getMessage());
  373. }
  374. $res = $res1 && $res2;
  375. StoreOrder::checkTrans($res);
  376. if (!$res) return app('json')->fail('余额退款失败!');
  377. }
  378. $resEdit = StoreOrder::edit($data, $orderInfo['id'], 'id');
  379. if ($resEdit) {
  380. $data['type'] = $type;
  381. if ($data['type'] == 1) StorePink::setRefundPink($orderInfo['id']);
  382. try {
  383. OrderRepository::storeProductOrderRefundY($data, $orderInfo['id']);
  384. } catch (\Exception $e) {
  385. return app('json')->fail($e->getMessage());
  386. }
  387. StoreOrderStatus::status($orderInfo['id'], 'refund_price', '退款给用户' . $price . '元');
  388. //退佣金
  389. $brokerage_list = UserBill::where('category', 'now_money')
  390. ->where('type', 'brokerage')
  391. ->where('link_id', $orderId)
  392. ->where('pm', 1)
  393. ->select()->toArray();
  394. if ($brokerage_list)
  395. foreach ($brokerage_list as $item) {
  396. $usermoney = User::where('uid', $item['uid'])->value('brokerage_price');
  397. if ($item['number'] > $usermoney)
  398. $item['number'] = $usermoney;
  399. User::bcDec($item['uid'], 'brokerage_price', $item['number'], 'uid');
  400. UserBill::expend('退款退佣金', $item['uid'], 'now_money', 'brokerage', $item['number'], $orderId, bcsub($usermoney, $item['number'], 2), '订单退款扣除佣金' . floatval($item['number']) . '元');
  401. }
  402. //退款扣除用户积分
  403. //购买赠送的积分
  404. $bill_integral = UserBill::where('category', 'integral')
  405. ->where('type', 'gain')
  406. ->where('link_id', $orderId)
  407. ->where('pm', 1)
  408. ->find();
  409. if ($bill_integral) {
  410. $bill_integral = $bill_integral->toArray();
  411. //用户积分
  412. $user_integral = User::where('uid', $bill_integral['uid'])->value('integral');
  413. if ($bill_integral['number'] > $user_integral)
  414. $bill_integral['number'] = $user_integral;
  415. User::bcDec($bill_integral['uid'], 'integral', $bill_integral['number'], 'uid');
  416. UserBill::expend('退款扣除积分', $bill_integral['uid'], 'integral', 'gain', $bill_integral['number'], $orderId, bcsub($user_integral, $bill_integral['number'], 2), '订单退款扣除积分' . floatval($bill_integral['number']) . '积分');
  417. }
  418. return app('json')->successful('修改成功!');
  419. } else {
  420. StoreOrderStatus::status($orderInfo['id'], 'refund_price', '退款给用户' . $price . '元失败');
  421. return app('json')->successful('修改失败!');
  422. }
  423. }
  424. /**
  425. * @api {post} order/order_verific 门店核销
  426. * @apiName AdminOrderVerify
  427. * @apiGroup Admin
  428. */
  429. public function order_verific(Request $request)
  430. {
  431. list($verify_code, $is_confirm) = UtilService::postMore([
  432. ['verify_code', ''],
  433. ['is_confirm', 0]
  434. ], $request, true);
  435. if (!$verify_code) return app('json')->fail('缺少核销码');
  436. $orderInfo = StoreOrder::where('verify_code', $verify_code)->where('paid', 1)->where('refund_status', 0)->find();
  437. if (!$orderInfo) return app('json')->fail('核销的订单不存在或未支付或已退款');
  438. if ($orderInfo->status > 0) return app('json')->fail('订单已经核销');
  439. if ($orderInfo->combination_id && $orderInfo->pink_id) {
  440. $res = StorePink::where('id', $orderInfo->pink_id)->where('status', '<>', 2)->count();
  441. if ($res) return app('json')->fail('拼团订单暂未成功无法核销!');
  442. }
  443. if (!$is_confirm) {
  444. $orderInfo['image'] = StoreCart::getProductImage($orderInfo->cart_id);
  445. return app('json')->success($orderInfo->toArray());
  446. }
  447. StoreOrder::beginTrans();
  448. try {
  449. $uid = $request->uid();
  450. if (SystemStoreStaff::verifyStatus($uid) && ($storeStaff = SystemStoreStaff::where('uid', $uid)->field(['store_id', 'id'])->find())) {
  451. $orderInfo->store_id = $storeStaff['store_id'];
  452. $orderInfo->clerk_id = $storeStaff['id'];
  453. }
  454. $orderInfo->status = 2;
  455. if ($orderInfo->save()) {
  456. OrderRepository::storeProductOrderTakeDeliveryAdmin($orderInfo);
  457. StoreOrderStatus::status($orderInfo->id, 'take_delivery', '已核销');
  458. event('ShortMssageSend', [$orderInfo['order_id'], 'Receiving']);
  459. StoreOrder::commitTrans();
  460. return app('json')->success('核销成功');
  461. } else {
  462. StoreOrder::rollbackTrans();
  463. return app('json')->fail('核销失败');
  464. }
  465. } catch (\PDOException $e) {
  466. StoreOrder::rollbackTrans();
  467. return app('json')->fail($e->getMessage());
  468. }
  469. }
  470. }