OrderService.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services\Api;
  12. use App\Models\GoodsModel;
  13. use App\Models\MemberModel;
  14. use App\Models\OrderGoodsModel;
  15. use App\Models\OrderModel;
  16. use App\Models\StoreModel;
  17. use App\Services\BaseService;
  18. use App\Services\ConfigService;
  19. use App\Services\Kd100Service;
  20. use App\Services\PaymentService;
  21. use App\Services\RedisService;
  22. use Illuminate\Support\Facades\DB;
  23. /**
  24. * 订单-服务类
  25. * @author laravel开发员
  26. * @since 2020/11/11
  27. * @package App\Services\Api
  28. */
  29. class OrderService extends BaseService
  30. {
  31. // 静态对象
  32. protected static $instance = null;
  33. /**
  34. * 构造函数
  35. * @author laravel开发员
  36. * @since 2020/11/11
  37. */
  38. public function __construct()
  39. {
  40. $this->model = new OrderModel();
  41. }
  42. /**
  43. * 静态入口
  44. */
  45. public static function make()
  46. {
  47. if (!self::$instance) {
  48. self::$instance = new static();
  49. }
  50. return self::$instance;
  51. }
  52. /**
  53. * 订单列表
  54. * @param $params
  55. * @param int $pageSize
  56. * @return array
  57. */
  58. public function getDataList($params, $pageSize = 15)
  59. {
  60. $model = $this->getQuery($params);
  61. // 数据
  62. $list = $model->where(function ($query) use ($params) {
  63. $status = isset($params['status']) ? $params['status'] : 0;
  64. // 进行中
  65. if ($status == 9) {
  66. $query->where('a.refund_status', '>', 0);
  67. } elseif ($status > 0 && is_array($status)) {
  68. $query->whereIn('a.status', $status)->where('a.refund_status', 0);
  69. } else if ($status == 4) {
  70. $query->where('a.status', $status)->where('a.refund_status', 0);
  71. } else if ($status > 0) {
  72. $query->where('a.status', $status)->where('a.refund_status', 0);
  73. }
  74. })->select(['a.*'])
  75. ->orderBy('a.status', 'asc')
  76. ->orderBy('a.create_time', 'desc')
  77. ->orderBy('a.id', 'desc')
  78. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  79. $list = $list ? $list->toArray() : [];
  80. if ($list) {
  81. $statusArr = [1 => '待支付', 2 => '待发货', 3 => '待收货', 4 => '确认收货'];
  82. $refundStatusArr = [1 => '已退款', 2 => '退款中', 3 => '退款审核', 4 => '退款驳回'];
  83. foreach ($list['data'] as &$item) {
  84. $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y/m/d H:i') : '';
  85. $status = isset($item['status']) ? $item['status'] : 0;
  86. $item['status_text'] = '待支付';
  87. if ($status) {
  88. $item['status_text'] = isset($statusArr[$status]) ? $statusArr[$status] : '';
  89. }
  90. if ($item['refund_status'] > 0) {
  91. $item['status_text'] = '退款/售后';
  92. }
  93. $item['goods'] = isset($item['goods']) && $item['goods'] ? $item['goods'] : [];
  94. }
  95. unset($item);
  96. }
  97. return [
  98. 'pageSize' => $pageSize,
  99. 'total' => isset($list['total']) ? $list['total'] : 0,
  100. 'list' => isset($list['data']) ? $list['data'] : []
  101. ];
  102. }
  103. /**
  104. * 查询条件
  105. * @param $params
  106. * @return mixed
  107. */
  108. public function getQuery($params)
  109. {
  110. $where = ['a.mark' => 1];
  111. return $this->model->from('orders as a')->with(['orderGoods', 'store'])
  112. ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
  113. ->where($where)
  114. ->where(function ($query) use ($params) {
  115. $userId = isset($params['user_id']) ? intval($params['user_id']) : 0;
  116. if ($userId > 0) {
  117. $query->where('a.user_id', $userId);
  118. }
  119. })
  120. ->where(function ($query) use ($params) {
  121. $keyword = isset($params['keyword']) ? $params['keyword'] : '';
  122. if ($keyword) {
  123. $query->where('a.order_no', 'like', "%{$keyword}%")
  124. ->orWhere('b.mobile', 'like', "%{$keyword}%");
  125. }
  126. });
  127. }
  128. /**
  129. * 订单详情
  130. * @param $id
  131. */
  132. public function getOrderInfo($id, $no='')
  133. {
  134. $where = ['order_no'=>$no,'a.id' => $id, 'a.mark' => 1];
  135. if($no){
  136. unset($where['id']);
  137. }else{
  138. unset($where['order_no']);
  139. }
  140. $statusArr = [1 => '待支付', 2 => '待发货', 3 => '待收货', 4 => '已完成'];
  141. $info = $this->model->from('orders as a')->with(['orderGoods','store'])
  142. ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
  143. ->where($where)
  144. ->select(['a.*'])
  145. ->first();
  146. if ($info) {
  147. $info = $info->toArray();
  148. $info['create_time'] = $info['create_time'] ? datetime($info['create_time'], 'Y-m-d H:i:s') : '';
  149. $status = isset($info['status']) ? $info['status'] : 0;
  150. $info['status_text'] = '待付款';
  151. if ($status) {
  152. $info['status_text'] = isset($statusArr[$status]) ? $statusArr[$status] : '';
  153. }
  154. }
  155. return $info;
  156. }
  157. /**
  158. * 创建订单
  159. * @param $userId 用户
  160. * @param $params 参数
  161. * @return array|false
  162. */
  163. public function createOrder($userId, $params)
  164. {
  165. $addressId = isset($params['address_id']) && $params['address_id'] ? $params['address_id'] : 0;
  166. $goods = isset($params['goods']) && $params['goods'] ? $params['goods'] : [];
  167. $ids = $goods ? array_column($goods, 'id') : [];
  168. // 参数验证
  169. if (empty($goods) || empty($ids)) {
  170. $this->error = '商品参数不为空';
  171. return false;
  172. }
  173. if ($addressId <= 0) {
  174. $this->error = '请选择收货地址';
  175. return false;
  176. }
  177. // 缓存锁
  178. $cacheLockKey = "caches:orders:submit_lock:{$userId}";
  179. if (RedisService::get($cacheLockKey)) {
  180. $this->error = '订单处理中~';
  181. return false;
  182. }
  183. // 商品数据
  184. $orderNo = get_order_num('GX');
  185. RedisService::set($cacheLockKey, ['params' => $params, 'user_id' => $userId], rand(3, 5));
  186. $result = GoodsService::make()->getOrderGoods($ids, $goods, $orderNo, $userId);
  187. if (empty($result)) {
  188. RedisService::clear($cacheLockKey);
  189. $this->error = GoodsService::make()->getError();
  190. return false;
  191. }
  192. $orderGoods = isset($result['goods']) ? $result['goods'] : [];
  193. $orderTotal = isset($result['total']) ? $result['total'] : 0;
  194. $orderCount = isset($result['count']) ? $result['count'] : 0;
  195. $storeId = isset($result['store_id']) ? $result['store_id'] : 0;
  196. if (empty($orderGoods)) {
  197. RedisService::clear($cacheLockKey);
  198. $this->error = '获取订单商品错误~';
  199. return false;
  200. }
  201. if ($orderTotal <= 0) {
  202. RedisService::clear($cacheLockKey);
  203. $this->error = '订单金额错误~';
  204. return false;
  205. }
  206. if ($orderCount <= 0) {
  207. RedisService::clear($cacheLockKey);
  208. $this->error = '订单商品数量错误~';
  209. return false;
  210. }
  211. // 用户信息
  212. $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
  213. ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
  214. ->first();
  215. $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
  216. $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
  217. if (empty($userInfo) || $status != 1) {
  218. $this->error = 1045;
  219. RedisService::clear($cacheLockKey);
  220. return false;
  221. }
  222. if (empty($openid)) {
  223. $this->error = '用户微信未授权,请重新授权登录';
  224. RedisService::clear($cacheLockKey);
  225. return false;
  226. }
  227. // 收货地址信息
  228. $addressInfo = MemberAddressService::make()->getBindInfo($userId, $addressId);
  229. $realname = isset($addressInfo['realname']) ? $addressInfo['realname'] : '';
  230. $mobile = isset($addressInfo['mobile']) ? $addressInfo['mobile'] : '';
  231. $area = isset($addressInfo['area']) ? $addressInfo['area'] : '';
  232. $address = isset($addressInfo['address']) ? $addressInfo['address'] : '';
  233. if (empty($addressInfo) || empty($realname) || empty($mobile) || empty($area) || empty($address)) {
  234. RedisService::clear($cacheLockKey);
  235. $this->error = '收货地址信息错误,请核对后重试~';
  236. return false;
  237. }
  238. // 商家佣金
  239. $storeInfo = StoreModel::where(['id' => $storeId])->first();
  240. $bonusRate = isset($storeInfo['bonus_rate']) ? floatval($storeInfo['bonus_rate']) : 0;
  241. $storeBonusRate = ConfigService::make()->getConfigByCode('store_bonus_rate', 0);
  242. $storeBonusRate = $storeBonusRate > 0 && $storeBonusRate <= 100 ? $storeBonusRate : 0;
  243. $bonusRate = $bonusRate > 0 && $bonusRate <= 100 ? $bonusRate : $storeBonusRate;
  244. $bonus = moneyFormat($orderTotal * $bonusRate / 100, 2);
  245. $total = $orderTotal;
  246. if (env('PAY_DEBUG')) {
  247. $orderTotal = 0.1;
  248. }
  249. // 订单数据
  250. $order = [
  251. 'order_no' => $orderNo,
  252. 'user_id' => $userId,
  253. 'store_id' => $storeId,
  254. 'total' => $total,
  255. 'num' => $orderCount,
  256. 'pay_total' => $orderTotal,
  257. 'receiver_name' => $realname,
  258. 'receiver_mobile' => $mobile,
  259. 'receiver_area' => $area,
  260. 'receiver_address' => $address,
  261. 'bonus' => $bonus,
  262. 'create_time' => time(),
  263. 'update_time' => time(),
  264. 'status' => 1,
  265. 'mark' => 1,
  266. ];
  267. // 订单处理
  268. DB::beginTransaction();
  269. if (!$orderId = $this->model->insertGetId($order)) {
  270. DB::rollBack();
  271. $this->error = '创建订单失败';
  272. RedisService::clear($cacheLockKey);
  273. return false;
  274. }
  275. // 订单商品
  276. if ($orderGoods && !OrderGoodsModel::insert($orderGoods)) {
  277. DB::rollBack();
  278. $this->error = '处理订单商品错误';
  279. RedisService::clear($cacheLockKey);
  280. return false;
  281. }
  282. // 获取支付参数
  283. /* TODO 支付处理 */
  284. $payOrder = [
  285. 'type' => 1,
  286. 'order_no' => $orderNo,
  287. 'pay_money' => $orderTotal,
  288. 'body' => '购物消费',
  289. 'openid' => $openid
  290. ];
  291. // 调起支付
  292. $payment = PaymentService::make()->minPay($userInfo, $payOrder, 'store');
  293. if (empty($payment)) {
  294. DB::rollBack();
  295. RedisService::clear($cacheLockKey);
  296. $this->error = PaymentService::make()->getError();
  297. return false;
  298. }
  299. // 用户操作记录
  300. DB::commit();
  301. $this->error = '订单创建成功,请前往支付~';
  302. RedisService::clear($cacheLockKey);
  303. return [
  304. 'order_id' => $orderId,
  305. 'payment' => $payment,
  306. 'total' => $payOrder['pay_money'],
  307. 'pay_type' => 10,
  308. ];
  309. }
  310. /**
  311. * 订单支付
  312. * @param $userId
  313. * @param $id
  314. * @return array|false
  315. */
  316. public function pay($userId, $id)
  317. {
  318. if ($id <= 0) {
  319. $this->error = '请选择支付订单';
  320. return false;
  321. }
  322. // 缓存锁
  323. $cacheLockKey = "caches:orders:pay_lock:{$userId}_{$id}";
  324. if (RedisService::get($cacheLockKey)) {
  325. $this->error = '订单处理中~';
  326. return false;
  327. }
  328. // 商品数据
  329. RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
  330. // 用户信息
  331. $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
  332. ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
  333. ->first();
  334. $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
  335. $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
  336. if (empty($userInfo) || $status != 1) {
  337. $this->error = 1045;
  338. RedisService::clear($cacheLockKey);
  339. return false;
  340. }
  341. if (empty($openid)) {
  342. $this->error = '用户微信未授权,请重新授权登录';
  343. RedisService::clear($cacheLockKey);
  344. return false;
  345. }
  346. // 订单信息
  347. $info = $this->model->where(['id' => $id, 'mark' => 1])
  348. ->select(['id', 'order_no', 'pay_total', 'status'])
  349. ->first();
  350. $orderTotal = isset($info['pay_total']) ? $info['pay_total'] : 0;
  351. $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
  352. $status = isset($info['status']) ? $info['status'] : 0;
  353. if (empty($info) || empty($orderNo)) {
  354. $this->error = '订单信息不存在';
  355. RedisService::clear($cacheLockKey);
  356. return false;
  357. }
  358. if ($status != 1) {
  359. $this->error = '订单已支付';
  360. RedisService::clear($cacheLockKey);
  361. return false;
  362. }
  363. // 获取支付参数
  364. /* TODO 支付处理 */
  365. $payOrder = [
  366. 'type' => 1,
  367. 'order_no' => $orderNo,
  368. 'pay_money' => $orderTotal,
  369. 'body' => '购物消费',
  370. 'openid' => $openid
  371. ];
  372. // 调起支付
  373. $payment = PaymentService::make()->minPay($userInfo, $payOrder, 'store');
  374. if (empty($payment)) {
  375. DB::rollBack();
  376. RedisService::clear($cacheLockKey);
  377. $this->error = PaymentService::make()->getError();
  378. return false;
  379. }
  380. // 用户操作记录
  381. DB::commit();
  382. $this->error = '支付请求成功,请前往支付~';
  383. RedisService::clear($cacheLockKey);
  384. return [
  385. 'order_id' => $id,
  386. 'payment' => $payment,
  387. 'total' => $payOrder['pay_money'],
  388. 'pay_type' => 10,
  389. ];
  390. }
  391. /**
  392. * 订单取消
  393. * @param $userId
  394. * @param $id
  395. * @return array|false
  396. */
  397. public function cancel($userId, $id)
  398. {
  399. if ($id <= 0) {
  400. $this->error = '请选择订单';
  401. return false;
  402. }
  403. // 缓存锁
  404. $cacheLockKey = "caches:orders:cancel_lock:{$userId}_{$id}";
  405. if (RedisService::get($cacheLockKey)) {
  406. $this->error = '订单处理中~';
  407. return false;
  408. }
  409. // 商品数据
  410. RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
  411. // 用户信息
  412. $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
  413. ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
  414. ->first();
  415. $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
  416. if (empty($userInfo) || $status != 1) {
  417. $this->error = 1045;
  418. RedisService::clear($cacheLockKey);
  419. return false;
  420. }
  421. // 订单信息
  422. $info = $this->model->where(['id' => $id, 'mark' => 1])
  423. ->select(['id', 'order_no', 'pay_total', 'status'])
  424. ->first();
  425. $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
  426. $status = isset($info['status']) ? $info['status'] : 0;
  427. if (empty($info) || empty($orderNo)) {
  428. $this->error = '订单信息不存在';
  429. RedisService::clear($cacheLockKey);
  430. return false;
  431. }
  432. if ($status != 1) {
  433. $this->error = '订单已支付';
  434. RedisService::clear($cacheLockKey);
  435. return false;
  436. }
  437. $this->error = '取消订单成功';
  438. $this->model->where(['user_id' => $userId, 'mark' => 0])->where('update_time', '<=', time() - 300)->delete();
  439. $this->model->where(['id' => $id])->update(['mark' => 0, 'update_time' => time()]);
  440. return ['id' => $id];
  441. }
  442. /**
  443. * 订单完成
  444. * @param $userId 订单用户ID
  445. * @param $id 订单ID
  446. * @return array|false
  447. */
  448. public function complete($userId, $id)
  449. {
  450. if ($id <= 0) {
  451. $this->error = '请选择订单';
  452. return false;
  453. }
  454. // 缓存锁
  455. $cacheLockKey = "caches:orders:complete_lock:{$userId}_{$id}";
  456. if (RedisService::get($cacheLockKey)) {
  457. $this->error = '订单处理中~';
  458. return false;
  459. }
  460. // 商品数据
  461. RedisService::set($cacheLockKey, ['order_id' => $id, 'user_id' => $userId], rand(3, 5));
  462. // 用户信息
  463. $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
  464. ->select(['id', 'openid', 'mobile', 'parent_id', 'nickname', 'realname', 'balance', 'status'])
  465. ->first();
  466. $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
  467. $parentId = isset($userInfo['parent_id']) ? $userInfo['parent_id'] : 0;
  468. if (empty($userInfo) || $status != 1) {
  469. $this->error = 1045;
  470. RedisService::clear($cacheLockKey);
  471. return false;
  472. }
  473. // 订单信息
  474. $info = $this->model->with(['orderGoods'])->where(['id' => $id, 'mark' => 1])
  475. ->select(['id', 'order_no', 'store_id', 'pay_total', 'bonus', 'delivery_no', 'delivery_company', 'delivery_code', 'status'])
  476. ->first();
  477. $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
  478. $deliveryNo = isset($info['delivery_no']) ? $info['delivery_no'] : '';
  479. $deliverCompany = isset($info['delivery_company']) ? $info['delivery_company'] : '';
  480. $deliverCode = isset($info['delivery_code']) ? $info['delivery_code'] : '';
  481. $storeId = isset($info['store_id']) ? $info['store_id'] : 0;
  482. $orderTotal = isset($info['pay_total']) ? $info['pay_total'] : 0;
  483. $bonus = isset($info['bonus']) ? $info['bonus'] : 0;
  484. $status = isset($info['status']) ? $info['status'] : 0;
  485. $orderGoods = isset($info['order_goods']) ? $info['order_goods'] : [];
  486. if (empty($info) || empty($orderNo)) {
  487. $this->error = '订单信息不存在';
  488. RedisService::clear($cacheLockKey);
  489. return false;
  490. }
  491. if ($status != 3) {
  492. $this->error = '订单未发货';
  493. RedisService::clear($cacheLockKey);
  494. return false;
  495. }
  496. if ((empty($deliveryNo) || empty($deliverCompany) || empty($deliverCode))) {
  497. $this->error = '订单发货信息错误';
  498. RedisService::clear($cacheLockKey);
  499. return false;
  500. }
  501. if (empty($deliveryNo) || empty($deliverCompany) || empty($deliverCode)) {
  502. $this->error = '订单发货信息错误,请联系客服';
  503. RedisService::clear($cacheLockKey);
  504. return false;
  505. }
  506. DB::beginTransaction();
  507. $this->model->where(['id' => $id])->update(['status' => '4', 'update_time' => time()]);
  508. // 商家订单数据统计
  509. $updateData = ['order_count' => DB::raw('order_count+1'), 'order_total' => DB::raw("order_total + {$orderTotal}")];
  510. StoreModel::where(['id' => $storeId])->update($updateData);
  511. // 商品销量数据
  512. if ($orderGoods) {
  513. $counts = [];
  514. foreach ($orderGoods as $item) {
  515. $counts[$item['goods_id']] = isset($counts[$item['goods_id']]) ? $counts[$item['goods_id']] : 0;
  516. $counts[$item['goods_id']] += $item['num'];
  517. }
  518. if ($counts) {
  519. foreach ($counts as $id => $v) {
  520. GoodsModel::where(['id' => $id])->update(['sales' => DB::raw("sales + {$v}"), 'update_time' => time()]);
  521. }
  522. }
  523. }
  524. // 结算商家收益
  525. if (SettleService::make()->storeBonus($storeId, $bonus, $info) < 0) {
  526. DB::rollBack();
  527. $this->error = SettleService::make()->getError();
  528. RedisService::clear($cacheLockKey);
  529. return false;
  530. }
  531. // 代理佣金结算
  532. if (SettleService::make()->agentBonus($userId, $orderTotal, $info, $parentId) < 0) {
  533. DB::rollBack();
  534. $this->error = SettleService::make()->getError();
  535. RedisService::clear($cacheLockKey);
  536. return false;
  537. }
  538. DB::commit();
  539. $this->error = '确认收货成功';
  540. return ['id' => $id];
  541. }
  542. /**
  543. * 售后或退款
  544. * @param $userId
  545. * @param $params
  546. * @return array|false
  547. */
  548. public function after($userId, $params)
  549. {
  550. $id = isset($params['id']) ? $params['id'] : 0;
  551. $afterType = isset($params['after_type']) ? $params['after_type'] : 1;
  552. if ($id <= 0) {
  553. $this->error = '请选择订单';
  554. return false;
  555. }
  556. // 缓存锁
  557. $cacheLockKey = "caches:orders:after_lock:{$userId}_{$id}";
  558. if (RedisService::get($cacheLockKey)) {
  559. $this->error = '订单处理中~';
  560. return false;
  561. }
  562. // 商品数据
  563. RedisService::set($cacheLockKey, ['params' => $params, 'user_id' => $userId], rand(3, 5));
  564. // 用户信息
  565. $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])
  566. ->select(['id', 'openid', 'mobile', 'nickname', 'realname', 'balance', 'status'])
  567. ->first();
  568. $status = isset($userInfo['status']) ? $userInfo['status'] : 0;
  569. if (empty($userInfo) || $status != 1) {
  570. $this->error = 1045;
  571. RedisService::clear($cacheLockKey);
  572. return false;
  573. }
  574. // 订单信息
  575. $info = $this->model->where(['id' => $id, 'mark' => 1])
  576. ->select(['id', 'order_no', 'after_type', 'refund_status', 'pay_total', 'status'])
  577. ->first();
  578. $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
  579. $status = isset($info['status']) ? $info['status'] : 0;
  580. $refundStatus = isset($info['refund_status']) ? $info['refund_status'] : 0;
  581. if (empty($info) || empty($orderNo)) {
  582. $this->error = '订单信息不存在';
  583. RedisService::clear($cacheLockKey);
  584. return false;
  585. }
  586. if ($status == 1) {
  587. $this->error = '订单未支付';
  588. RedisService::clear($cacheLockKey);
  589. return false;
  590. }
  591. if ($status == 4 && $afterType==2) {
  592. $this->error = '订单已完成';
  593. RedisService::clear($cacheLockKey);
  594. return false;
  595. }
  596. if ($refundStatus > 0 && $refundStatus != 4) {
  597. $this->error = '订单售后处理中';
  598. RedisService::clear($cacheLockKey);
  599. return false;
  600. }
  601. $afterRealname = isset($params['after_realname']) ? $params['after_realname'] : '';
  602. $afterPhone = isset($params['after_phone']) ? $params['after_phone'] : '';
  603. $afterRemark = isset($params['after_remark']) ? $params['after_remark'] : '';
  604. if ($afterType == 1) {
  605. if (empty($afterRealname) || empty($afterPhone) || empty($afterRemark)) {
  606. $this->error = '请填写售后信息';
  607. RedisService::clear($cacheLockKey);
  608. return false;
  609. }
  610. }
  611. $data = [
  612. 'after_type' => $afterType,
  613. 'after_realname' => $afterRealname,
  614. 'after_phone' => $afterPhone,
  615. 'after_remark' => $afterRemark,
  616. 'refund_remark' => isset($params['refund_remark']) ? $params['refund_remark'] : '',
  617. 'refund_status' => 3,
  618. 'update_time' => time()
  619. ];
  620. $this->model->where(['id' => $id])->update($data);
  621. $this->error = '订单申请售后成功';
  622. return ['id' => $id];
  623. }
  624. /**
  625. * 今日数量统计数据
  626. * @param $userId
  627. * @param int $type
  628. * @return array|mixed
  629. */
  630. public function getCountByDay($userId, $status = 3)
  631. {
  632. $cacheKey = "caches:orders:count_day_{$userId}_{$status}";
  633. $data = RedisService::get($cacheKey);
  634. if ($data) {
  635. return $data;
  636. }
  637. $data = $this->model->where(['user_id' => $userId, 'status' => $status, 'mark' => 1])
  638. ->where('create_time', '>=', strtotime(date('Y-m-d')))
  639. ->count('id');
  640. if ($data) {
  641. RedisService::set($cacheKey, $data, rand(5, 10));
  642. }
  643. return $data;
  644. }
  645. /**
  646. * 订单数
  647. * @param $userId
  648. * @param int $status
  649. * @return array|mixed
  650. */
  651. public function getCountByStatus($userId, $status = 3)
  652. {
  653. $cacheKey = "caches:orders:count_status_{$userId}_{$status}";
  654. $data = RedisService::get($cacheKey);
  655. if ($data) {
  656. return $data;
  657. }
  658. $data = $this->model->where(['user_id' => $userId, 'status' => $status, 'mark' => 1])
  659. ->count('id');
  660. if ($data) {
  661. RedisService::set($cacheKey, $data, rand(5, 10));
  662. }
  663. return $data;
  664. }
  665. /**
  666. * 获取订单审核状态
  667. * @param $userId
  668. * @return array|mixed
  669. */
  670. public function checkOrderStatus($userId)
  671. {
  672. $cacheKey = "caches:orders:checkOrder:{$userId}";
  673. $data = RedisService::get($cacheKey);
  674. if ($data) {
  675. return $data;
  676. }
  677. $data = $this->model->with(['confirm'])->where(function ($query) {
  678. $query->where(function ($query) {
  679. $query->where('status', 2)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 3600));
  680. })->orWhere(function ($query) {
  681. $query->where('status', 9)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 600));
  682. })->orWhere(function ($query) {
  683. $query->where('status', 3)->where('confirm_at', '>=', date('Y-m-d H:i:s', time() - 600));
  684. })->orWhere('status', 1);
  685. })
  686. ->where(['user_id' => $userId, 'mark' => 1])
  687. ->select(['id', 'order_no', 'user_id', 'goods_id', 'status'])
  688. ->orderBy('id', 'desc')
  689. ->first();
  690. $data = $data ? $data->toArray() : [];
  691. $result = [];
  692. if ($data) {
  693. $orderId = isset($data['id']) ? $data['id'] : 0;
  694. $status = isset($data['status']) ? $data['status'] : 0;
  695. $goodsId = isset($data['goods_id']) ? $data['goods_id'] : 0;
  696. $confirmOrder = isset($data['confirm']) ? $data['confirm'] : [];
  697. $confirmOrderId = isset($confirmOrder['id']) ? $confirmOrder['id'] : 0;
  698. $confirmOrderUser = isset($confirmOrder['user']) ? $confirmOrder['user'] : [];
  699. $realname = isset($confirmOrderUser['realname']) ? $confirmOrderUser['realname'] : '';
  700. if ($status == 9) {
  701. $message = "抱歉,订单已被其他师傅接走";
  702. } else if ($status == 2) {
  703. $message = "恭喜您,抢单成功,请前往完成订单!";
  704. } else if ($status == 3) {
  705. $message = "恭喜您,订单已经完成!";
  706. } else {
  707. $pickerCount = $this->model->where(['goods_id' => $goodsId, 'mark' => 1])->whereIn('status', [1, 2])->count('id');
  708. $pickerCount = $pickerCount <= 3 ? 3 : $pickerCount;
  709. $message = "<p style='padding: 5px 0;'>正在抢单</p><p>({$pickerCount}位师傅正在抢单中)</p>";
  710. }
  711. $result = ['order_id' => $orderId, 'goods_id' => $goodsId, 'confirm_order_id' => $confirmOrderId, 'status' => $status, 'message' => $message];
  712. RedisService::set($cacheKey, $result, rand(10, 20));
  713. }
  714. return $result;
  715. }
  716. /**
  717. * 物流查询
  718. * @param $id
  719. * @return array|false|mixed
  720. */
  721. public function getDelivery($id)
  722. {
  723. $info = $this->model->where(['id' => $id, 'mark' => 1])->first();
  724. $deliveryNo = isset($info['delivery_no']) ? $info['delivery_no'] : '';
  725. $deliveryCode = isset($info['delivery_code']) ? $info['delivery_code'] : '';
  726. $mobile = isset($info['receiver_mobile']) ? $info['receiver_mobile'] : '';
  727. if (empty($info)) {
  728. $this->error = '请选择订单';
  729. return false;
  730. }
  731. $cacheKey = "caches:kd100_{$id}";
  732. $data = RedisService::get($cacheKey);
  733. $data = [
  734. [
  735. "time" => "2025-12-24 11:29:23",
  736. "context" => "您的快件已投递,收件人在[沙岗镇绕城路天猫1号店妈妈驿站]取件(凭取件码签收),如有疑问请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!",
  737. "ftime" => "2025-12-24 11:29:23",
  738. "areaCode" => "CN450521000000",
  739. "areaName" => "广西,北海市,合浦县",
  740. "status" => "签收",
  741. ],
  742. [
  743. "time" => "2025-12-22 17:29:40",
  744. "context" => "您的快件已到达[妈妈驿站]沙岗镇绕城路1号天猫店,请您及时取件,如有取件码问题或找不到包裹等问题,请联系站点:13086796129,快递员电话:13086796129,投诉电话:15278929512。感谢使用圆通速递,期待再次为您服务!",
  745. "ftime" => "2025-12-22 17:29:40",
  746. "areaCode" => "CN450521000000",
  747. "areaName" => "广西,北海市,合浦县",
  748. "status" => "派件",
  749. ],[
  750. "time" => "2025-12-22 17:28:40",
  751. "context" => "【广西北海市合浦县沙岗镇】的莫业琨(13086796129)正在派件,(有事先呼我,勿找平台,少一次投诉,多一份感恩)!如有疑问请联系网点:15278929512,投诉电话:15278929512。[95161和18521号段的上海号码为圆通快递员专属号码,请放心接听]",
  752. "ftime" => "2025-12-22 17:28:40",
  753. "areaCode" => "CN450521100000",
  754. "areaName" => "广西,北海市,合浦县,廉州镇",
  755. "status" => "派件",
  756. ],[
  757. "time" => "2025-12-22 02:44:12",
  758. "context" => "您的快件离开【南宁转运中心】,已发往【广西北海市合浦】",
  759. "ftime" => "2025-12-22 02:44:12",
  760. "areaCode" => "CN450108000000",
  761. "areaName" => "广西,南宁市,良庆区",
  762. "status" => "在途",
  763. ],[
  764. "time" => "2025-12-22 02:21:21",
  765. "context" => "您的快件已经到达【南宁转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】",
  766. "ftime" => "2025-12-22 02:21:21",
  767. "areaCode" => "CN450108000000",
  768. "areaName" => "广西,南宁市,良庆区",
  769. "status" => "在途",
  770. ],[
  771. "time" => "2025-12-20 23:47:58",
  772. "context" => "您的快件离开【临海转运中心】,已发往【南宁转运中心】。预计【12月22日】到达【南宁市】,因运输距离较远,预计将在【22日晚上】为您更新快件状态,请您放心!",
  773. "ftime" => "2025-12-20 23:47:58",
  774. "areaCode" => "CN331082000000",
  775. "areaName" => "浙江,台州市,临海市",
  776. "status" => "在途",
  777. ],[
  778. "time" => "2025-12-20 23:45:58",
  779. "context" => "您的快件已经到达【临海转运中心】【物流问题无需找商家或平台,请致电(专属热线:95554)更快解决】",
  780. "ftime" => "2025-12-20 23:45:58",
  781. "areaCode" => "CN331082000000",
  782. "areaName" => "浙江,台州市,临海市",
  783. "status" => "在途",
  784. ]
  785. ];
  786. if ($data) {
  787. return $data;
  788. }
  789. $result = Kd100Service::make()->query($deliveryNo, $mobile, $deliveryCode);
  790. $status = isset($result['status'])?$result['status']:0;
  791. $data = isset($result['data'])?$result['data']:[];
  792. if ($data && $status==200) {
  793. RedisService::set($cacheKey, $data, 300);
  794. }
  795. return $data;
  796. }
  797. }