Order.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <?php
  2. namespace app\admin\controller;
  3. use app\BaseController;
  4. use app\admin\model\FundsRecord;
  5. use app\admin\model\User;
  6. use app\admin\model\Admin;
  7. use Exception;
  8. use app\admin\model\Order as OrderModel;
  9. use think\facade\Db;
  10. class Order extends BaseController
  11. {
  12. /**
  13. * 订单手动退款
  14. */
  15. public function adminRefund()
  16. {
  17. $errors = [];
  18. DB::beginTransaction();
  19. try {
  20. $params = $this->request->param();
  21. $admin = Admin::where('id', $this->admin_id)->findOrFail();
  22. if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
  23. $orderList = OrderModel::whereIn('id', $params['order_id'])->get();
  24. foreach ($orderList as $order) {
  25. if ($order->return_status != 0 || $order->pay_status != 1) {
  26. continue;
  27. }
  28. $order->status = 3;
  29. $order->return_status = 2;
  30. $order->return_operation_time = time();
  31. $order->save();
  32. $user = User::where('user_id', $order->user_id)->findOrFail();
  33. if (!$user) continue;
  34. if ($user->type == 1) {
  35. FundsRecord::addData([
  36. 'transaction_type' => 'return_order',
  37. 'amount_change' => $order->amount,
  38. 'balance_before' => $user->money,
  39. 'balance_after' => bcsub($user->money, $order->amount, 2),
  40. 'user_id' => $user->user_id,
  41. ]);
  42. $user->money = bcsub($user->money, $order->amount, 2);
  43. $user->save();
  44. }
  45. }
  46. DB::commit();
  47. } catch (Exception $e) {
  48. DB::rollBack();
  49. return $this->error($e->getMessage(), $errors);
  50. }
  51. return $this->success();
  52. }
  53. /**
  54. * @api {post} /order/refund 同意退款
  55. * @apiGroup 订单管理
  56. */
  57. public function refund()
  58. {
  59. $errors = [];
  60. DB::beginTransaction();
  61. try {
  62. $params = $this->request->param();
  63. $orderId = $params['order_id'];
  64. $safeWord = $params['safe_word'];
  65. $admin = Admin::where('id', $this->admin_id)->findOrFail();
  66. if (!password_verify($safeWord, $admin->payment_password)) throw new Exception('资金密码错误');
  67. $order = OrderModel::where('id', $orderId)->findOrFail();
  68. if (!$order) throw new Exception('订单不存在');
  69. if ($order->return_status != 1 || $order->pay_status != 1) {
  70. $errors = ['id' => $orderId];
  71. throw new Exception("该订单状态无法操作");
  72. }
  73. $order->status = 3;
  74. $order->return_status = 2;
  75. $order->return_operation_time = time();
  76. $order->save();
  77. $user = User::where('user_id', $order->user_id)->findOrFail();
  78. $balanceAfter = bcadd($user->money, $order->amount, 2);
  79. FundsRecord::addData([
  80. 'transaction_type' => 'return_order',
  81. 'amount_change' => $order->amount,
  82. 'balance_before' => $user->money,
  83. 'balance_after' => $balanceAfter,
  84. 'user_id' => $user->user_id,
  85. ]);
  86. $user->money = $balanceAfter;
  87. $user->save();
  88. DB::commit();
  89. } catch (Exception $e) {
  90. DB::rollBack();
  91. return $this->error($e->getMessage(), $errors);
  92. }
  93. return $this->success();
  94. }
  95. /**
  96. * 驳回退款申请
  97. * @apiGroup 订单管理
  98. */
  99. public function rejection()
  100. {
  101. $errors = [];
  102. DB::beginTransaction();
  103. try {
  104. $params = $this->request->param();
  105. if (empty($params['failure_msg'])) $params['failure_msg'] = '';
  106. $order = OrderModel::where('id', $params['order_id'])->first();
  107. if (!$order) throw new Exception('订单不存在');
  108. if ($order->status != 1 || $order->return_status != 1) {
  109. $errors = ['id' => $params['order_id']];
  110. throw new Exception("该订单状态无法操作");
  111. }
  112. $order->return_operation_time = time();
  113. $order->failure_msg = $params['failure_msg'];
  114. $order->save();
  115. DB::commit();
  116. } catch (Exception $e) {
  117. DB::rollBack();
  118. return $this->error($e->getMessage(), $errors);
  119. }
  120. return $this->success();
  121. }
  122. /**
  123. * @api {get} /order/list 订单列表
  124. * @apiGroup 订单管理
  125. * @apiVersion 1.0.0
  126. * @apiUse header
  127. * @apiUse lang
  128. *
  129. * @apiParam {int} [page=1]
  130. * @apiParam {int} [limit=15]
  131. * @apiParam {String} [id] 订单编号
  132. * @apiParam {String} [user_id] 买家ID
  133. * @apiParam {String} [store_id] 卖家ID
  134. * @apiParam {String} [phone] 手机号
  135. * @apiParam {String} [contacts] 收货人
  136. * @apiParam {int=0,1} [pay_status] 支付状态 0待支付 1已支付
  137. * @apiParam {int=0,1} [profit_status] 利润发放 0未发放 1已发放
  138. * @apiParam {String} [start_time] 开始时间
  139. * - 格式:`yyyy-mm-dd`
  140. * @apiParam {String} [end_time] 开始时间
  141. * - 格式:`yyyy-mm-dd`
  142. * @apiParam {int=-1,0,1,2,3,4,5,6,7} [type=7] 订单类别
  143. * - `7 全部订单`,`0 待付款`,`1 已确认`,`2 待发货`,`3 待收货`,`4 已收货`,`5 已评价`,`6 已退款`,`-1 已取消`
  144. * @apiSuccess {String} id 订单编号
  145. * @apiSuccess {Object} store 店铺信息
  146. * @apiSuccess {String} store.user_id 店铺ID
  147. * @apiSuccess {String} store.seller_name 店铺名
  148. * @apiSuccess {String} store.seller_img 店铺logo
  149. * @apiSuccess {String} store.seller_address 店铺地址
  150. * @apiSuccess {String} contacts 收货人姓名
  151. * @apiSuccess {String} user_id 买家ID
  152. * @apiSuccess {String} store_id 卖家ID
  153. * @apiSuccess {String} total_cost 采购价格
  154. * @apiSuccess {String} price_count 订单金额
  155. * @apiSuccess {String} profit 利润
  156. * @apiSuccess {int} pay_status 支付状态 0待支付 1已支付
  157. * @apiSuccess {int} status 订单状态
  158. * - -1 已取消
  159. * - 0 待付款
  160. * - 1 待发货
  161. * - 2 待发货
  162. * - 3 待收货
  163. * - 4 已确认
  164. * - 5 已评价
  165. *
  166. */
  167. public function getList(Request $request)
  168. {
  169. try {
  170. $params = request()->validate([
  171. 'page' => ['nullable', 'integer', 'min:1'],
  172. 'limit' => ['nullable', 'integer', 'min:1'],
  173. 'id' => ['nullable', 'string'],
  174. 'user_id' => ['nullable', 'string'],
  175. 'store_id' => ['nullable', 'string'],
  176. 'phone' => ['nullable', 'string'],
  177. 'contacts' => ['nullable', 'string'],
  178. 'pay_status' => ['nullable', 'integer', 'in:0,1'],
  179. 'return_status' => ['nullable', 'integer', 'in:0,1,2,3'],
  180. 'purchase_status' => ['nullable', 'integer', 'in:0,1,2'],
  181. 'purchase_amount_status' => ['nullable', 'integer', 'in:0,1'],
  182. 'profit_status' => ['nullable', 'integer', 'in:0,1'],
  183. 'status' => ['nullable', 'integer', 'in:0,1,2,3,4,5,6,7,-1'],
  184. 'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
  185. 'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
  186. 'order_task_id' => ['nullable', 'string'],
  187. 'type' => ['nullable', 'integer', 'in:1,2'],
  188. ]);
  189. $page = request()->input('page', 1);
  190. $limit = request()->input('limit', 15);
  191. $admin_id = $request->user->id;
  192. if ($admin_id != 1 && Config::adminOpenAllData($admin_id) === false) {
  193. $user_code = $request->user->user_code;
  194. $query = OrderModel::leftJoin('users', 'orders.user_id', '=', 'users.user_id')
  195. ->leftJoin('users as stores', 'orders.store_id', '=', 'stores.user_id')
  196. ->where(function ($query) use ($user_code){
  197. $query->where('users.user_code', $user_code)
  198. ->orWhere('stores.user_code', $user_code);
  199. });
  200. } else {
  201. $query = OrderModel::query();
  202. }
  203. if (!empty($params['start_time'])) {
  204. $query = $query->where('orders.created_at', '>=', $params['start_time'] . " 00:00:00")
  205. ->where('orders.created_at', '<=', $params['end_time'] . " 23:59:59");
  206. }
  207. if (!empty($params['id'])) {
  208. $query = $query->where('orders.id', $params['id']);
  209. }
  210. if (!empty($params['user_id'])) {
  211. $query = $query->where('orders.user_id', $params['user_id']);
  212. }
  213. if (!empty($params['store_id'])) {
  214. $query = $query->where('orders.store_id', $params['store_id']);
  215. }
  216. if (!empty($params['phone'])) {
  217. $query = $query->where('orders.phone', $params['phone']);
  218. }
  219. if (!empty($params['contacts'])) {
  220. $query = $query->where('orders.contacts', 'like', '%' . $params['contacts'] . '%');
  221. }
  222. if (isset($params['status'])) {
  223. $query = $query->where('orders.status', $params['status']);
  224. }
  225. if (isset($params['return_status'])) {
  226. $query = $query->where('orders.return_status', $params['return_status']);
  227. }
  228. if (isset($params['pay_status'])) {
  229. $query = $query->where('orders.pay_status', $params['pay_status']);
  230. }
  231. if (isset($params['profit_status'])) {
  232. $query = $query->where('orders.profit_status', $params['profit_status']);
  233. }
  234. if (isset($params['purchase_status'])) {
  235. $query = $query->where('orders.purchase_status', $params['purchase_status']);
  236. }
  237. if (isset($params['purchase_amount_status'])) {
  238. $query = $query->where('orders.purchase_amount_status', $params['purchase_amount_status']);
  239. }
  240. if (!empty($params['order_task_id'])) {
  241. $query = $query->where('orders.order_task_id', $params['order_task_id']);
  242. }
  243. if (!empty($params['type'])) {
  244. $query = $query->where('orders.type', $params['type']);
  245. }
  246. $count = $query->count();
  247. $list = $query->with(['store', 'orderLog'])
  248. ->select('orders.*')
  249. ->forPage($page, $limit)
  250. ->orderByDesc('orders.created_at')
  251. ->get();
  252. } catch (ValidationException $e) {
  253. return $this->error($e->validator->errors()->first());
  254. } catch (Exception $e) {
  255. return $this->error($e->getMessage());
  256. }
  257. return $this->success(['count' => $count, 'stateList' => OrderShip::getStateList(), 'list' => $list]);
  258. }
  259. //订单详情
  260. function info()
  261. {
  262. try {
  263. request()->validate([
  264. 'order_id' => ['required', 'string', 'min:19', 'max:19'],
  265. ]);
  266. $orderId = request()->input('order_id');
  267. $order = OrderModel::with(['store'])->where('id', $orderId)->first();
  268. if (!$order) throw new Exception('订单不存在');
  269. $order = $order->toArray();
  270. ksort($order);
  271. //订单的商品列表
  272. $list = OrderItem::where('order_id', $orderId)
  273. ->get()->makeHidden(['total_cost', 'system_price', 'profit'])
  274. ->toArray();
  275. foreach ($list as &$item) {
  276. $goodsLanguages = GoodsLanguages::where('goods_id', $item['goods_id'])
  277. ->get()->toArray();
  278. $goodsLanguages = Util::getDataByLanguageCode($goodsLanguages, $this->lang);
  279. $item['goods_name'] = $goodsLanguages['name'];
  280. $sku = GoodsSku::where('sku_id', $item['sku_id'])->first();
  281. if (empty($sku)) {
  282. $item['cover_img'] = '';
  283. $item['attributes'] = [];
  284. } else {
  285. $sku = $sku->toArray();
  286. $item['cover_img'] = $sku['cover_img'];
  287. $item['attributes'] = AttrValue::getAttr($sku['attr_value_ids'], $this->lang);
  288. }
  289. }
  290. $order['goods'] = $list;
  291. //退款驳回的原因
  292. $order['failure_msg'] = '';
  293. if ($order['return_status'] == 3) {
  294. $order['failure_msg'] = OrderRefund::where('order_id', $orderId)->pluck('failure_msg')->first();
  295. }
  296. } catch (ValidationException $e) {
  297. return $this->error($e->validator->errors()->first());
  298. } catch (Exception $e) {
  299. return $this->error($e->getMessage());
  300. }
  301. $order['stateList'] = OrderShip::getStateList();
  302. $order['ship_time'] = OrderShip::where(['order_id' => $orderId, 'state' => 3])->value('created_at');
  303. return $this->success($order);
  304. }
  305. /**
  306. * @api {post} /order/ship 发货
  307. * @apiGroup 订单管理
  308. * @apiVersion 1.0.0
  309. * @apiUse header
  310. * @apiUse lang
  311. *
  312. * @apiParam {String[]} order_id 订单id
  313. */
  314. public function ship()
  315. {
  316. $errors = [];
  317. DB::beginTransaction();
  318. try {
  319. $params = request()->validate([
  320. 'order_id' => ['required', 'array', 'min:1'],
  321. 'order_id.*' => ['string', 'min:19', 'max:19'],
  322. ]);
  323. $orderIds = $params['order_id'];
  324. foreach ($orderIds as $orderId) {
  325. $order = OrderModel::where('id', $orderId)->first();
  326. if (!$order) continue;
  327. if ($order->pay_status != 1 ) {
  328. continue;
  329. // $errors = ['id' => $orderId];
  330. // throw new Exception("当前订单未支付");
  331. }
  332. if ($order->purchase_status != 1 ) {
  333. continue;
  334. // $errors = ['id' => $orderId];
  335. // throw new Exception("当前订单未采购");
  336. }
  337. if ($order->status != 2 ) {
  338. continue;
  339. // $errors = ['id' => $orderId];
  340. // throw new Exception("当前订单未到待发货状态");
  341. }
  342. if ($order->return_status != 0 ) {
  343. continue;
  344. // $errors = ['id' => $orderId];
  345. // throw new Exception("当前订单已申请退款");
  346. }
  347. $order->status = 3;
  348. $order->ship_state = 3;
  349. $order->save();
  350. OrderLog::addData([
  351. 'order_id' => $order->id,
  352. 'state' => 7
  353. ]);
  354. //记录物流
  355. OrderShip::addData($order->id, 3);
  356. }
  357. DB::commit();
  358. } catch (ValidationException $e) {
  359. DB::rollBack();
  360. return $this->error($e->validator->errors()->first());
  361. } catch (Exception $e) {
  362. DB::rollBack();
  363. return $this->error($e->getMessage(), $errors);
  364. }
  365. return $this->success();
  366. }
  367. public function updateOrderShip()
  368. {
  369. try {
  370. $params = request()->validate([
  371. 'order_id' => ['required', 'string', 'min:19', 'max:19'],
  372. 'state' => ['required', 'integer', 'in:4,5,6,7,8,9'],
  373. ]);
  374. $orderId = $params['order_id'];
  375. $state = $params['state'];
  376. $order = OrderModel::where('id', $orderId)->first();
  377. if (!$order) throw new Exception('订单不存在');
  378. if ($order->status < 3 ) {
  379. throw new Exception("当前订单未到已发货状态");
  380. }
  381. Db::beginTransaction();
  382. $order->ship_state = $state;
  383. $order->save();
  384. OrderShip::addData($order->id, $state);
  385. Db::commit();
  386. } catch (ValidationException $e) {
  387. return $this->error($e->validator->errors()->first());
  388. } catch (Exception $e) {
  389. Db::rollBack();
  390. return $this->error($e->getMessage());
  391. }
  392. return $this->success();
  393. }
  394. //查看订单物流
  395. public function orderShip()
  396. {
  397. try {
  398. $params = request()->validate([
  399. 'order_id' => ['required', 'string', 'min:19', 'max:19'],
  400. ]);
  401. $orderId = $params['order_id'];
  402. $ship = OrderModel::getOrderShip($orderId);
  403. } catch (ValidationException $e) {
  404. return $this->error($e->validator->errors()->first());
  405. } catch (Exception $e) {
  406. return $this->error($e->getMessage());
  407. }
  408. return $this->success($ship);
  409. }
  410. }