DeliveryOrderRepository.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\delivery;
  12. use app\common\dao\delivery\DeliveryOrderDao;
  13. use app\common\model\delivery\DeliveryStation;
  14. use app\common\model\store\order\StoreOrder;
  15. use app\common\repositories\BaseRepository;
  16. use app\common\repositories\store\order\StoreOrderRepository;
  17. use app\common\repositories\store\order\StoreOrderStatusRepository;
  18. use app\common\repositories\system\merchant\MerchantRepository;
  19. use app\common\repositories\system\serve\ServeOrderRepository;
  20. use app\common\repositories\user\UserRepository;
  21. use crmeb\services\DeliverySevices;
  22. use FormBuilder\Factory\Elm;
  23. use think\exception\ValidateException;
  24. use think\facade\Db;
  25. use think\facade\Log;
  26. use think\facade\Route;
  27. /**
  28. * 同城配送订单
  29. */
  30. class DeliveryOrderRepository extends BaseRepository
  31. {
  32. protected $statusData = [
  33. 2 => '待取货',
  34. 3 => '配送中',
  35. 4 => '已完成',
  36. -1 => '已取消',
  37. 9 => '物品返回中',
  38. 10 => '物品返回完成',
  39. 100 => '骑士到店',
  40. ];
  41. protected $message = [
  42. 2 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_WAITING,
  43. 3 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_ING,
  44. 4 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_OVER,
  45. -1 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_CANCEL,
  46. 9 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_REFUNDING,
  47. 10 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_REFUND,
  48. 100 => StoreOrderStatusRepository::ORDER_DELIVERY_CITY_ARRIVE,
  49. ];
  50. public function __construct(DeliveryOrderDao $dao)
  51. {
  52. $this->dao = $dao;
  53. }
  54. /**
  55. * 商户的同城配送订单列表
  56. * @param array $where
  57. * @param int $page
  58. * @param int $limit
  59. * @return array
  60. * @author Qinii
  61. */
  62. public function merList(array $where, int $page, int $limit)
  63. {
  64. $query = $this->dao->getSearch($where)->with(['station', 'storeOrder'])->order('create_time DESC');
  65. $count = $query->count();
  66. $list = $query->page($page, $limit)->select();
  67. return compact('count', 'list');
  68. }
  69. /**
  70. * 平台同城配送订单列表
  71. * @param array $where
  72. * @param int $page
  73. * @param int $limit
  74. * @return array
  75. * @author Qinii
  76. */
  77. public function sysList(array $where, int $page, int $limit)
  78. {
  79. $query = $this->dao->getSearch($where)->with([
  80. 'merchant' => function ($query) {
  81. $query->field('mer_id,mer_name');
  82. },
  83. 'station',
  84. 'storeOrder' => function ($query) {
  85. $query->field('order_id,order_sn');
  86. },
  87. ])->order('create_time DESC');
  88. $count = $query->count();
  89. $list = $query->page($page, $limit)->select();
  90. return compact('count', 'list');
  91. }
  92. /**
  93. * 需要配置的订单详情
  94. * @param int $id
  95. * @param int|null $merId
  96. * @return \app\common\model\BaseModel|array|mixed|\think\Model
  97. * @throws \think\db\exception\DataNotFoundException
  98. * @throws \think\db\exception\DbException
  99. * @throws \think\db\exception\ModelNotFoundException
  100. * @author wuhaotian
  101. * @email 442384644@qq.com
  102. * @date 2024/7/5
  103. */
  104. public function detail(int $id, ?int $merId)
  105. {
  106. $where[$this->dao->getPk()] = $id;
  107. if ($merId) $where['mer_id'] = $merId;
  108. $res = $this->dao->getSearch($where)->with([
  109. 'merchant' => function ($query) {
  110. $query->field('mer_id,mer_name');
  111. },
  112. 'station',
  113. ])->find();
  114. // 先检查结果是否存在
  115. if (!$res) throw new ValidateException('订单不存在');
  116. // 然后再处理订单详情
  117. try {
  118. $order = DeliverySevices::create($res['station_type'])->getOrderDetail($res);
  119. $res['data'] = [
  120. 'order_code' => $order['order_code'],
  121. 'to_address' => $order['to_address'],
  122. 'from_address' => $order['from_address'],
  123. 'state' => $order['state'],
  124. 'note' => $order['note'],
  125. 'order_price' => $order['order_price'],
  126. 'distance' => round(($order['distance'] / 1000), 2) . ' km',
  127. ];
  128. } catch (\Exception $e) {
  129. // 记录异常并返回友好提示
  130. Log::error('获取配送订单详情失败:' . $e->getMessage());
  131. throw new ValidateException('获取订单详情失败,请稍后再试');
  132. }
  133. return $res;
  134. }
  135. /**
  136. * 取消配送订单
  137. * @param $id
  138. * @return \FormBuilder\Form
  139. * @author Qinii
  140. */
  141. public function cancelForm($id)
  142. {
  143. $formData = $this->dao->get($id);
  144. if (!$formData) throw new ValidateException('订单不存在');
  145. if ($formData['status'] == -1) throw new ValidateException('订单已取消,无法操作');
  146. $form = Elm::createForm(Route::buildUrl('merchantStoreDeliveryOrderCancel', ['id' => $id])->build());
  147. $rule = [];
  148. if ($formData['station_type'] == DeliverySevices::DELIVERY_TYPE_DADA) {
  149. $options = DeliverySevices::create(DeliverySevices::DELIVERY_TYPE_DADA)->reasons();
  150. $rule[] = Elm::select('reason', '取消原因:')->placeholder('请选择取消原因')->options($options);
  151. $rule[] = Elm::text('cancel_reason', '其他原因说明:')->placeholder('请输入其它原因说明');
  152. }
  153. if ($formData['station_type'] == DeliverySevices::DELIVERY_TYPE_UU) {
  154. $rule[] = Elm::input('reason', '取消原因:')->placeholder('请输入取消原因')->required(1);
  155. }
  156. $form->setRule($rule);
  157. return $form->setTitle('取消同城配送订单', $formData);
  158. }
  159. /**
  160. * 取消表单
  161. * @param $id
  162. * @param $merId
  163. * @param $reason
  164. * @return mixed
  165. * @author Qinii
  166. */
  167. public function cancel($id, $merId, $reason)
  168. {
  169. $order = $this->dao->getWhere([$this->dao->getPk() => $id, 'mer_id' => $merId]);
  170. if (!$order) throw new ValidateException('配送订单不存在');
  171. if ($order['status'] == -1) throw new ValidateException('请勿重复操作');
  172. $data = [
  173. 'origin_id' => $order['order_sn'],
  174. 'order_code' => $order['order_code'],
  175. 'reason' => $reason['reason'],
  176. 'cancel_reason' => $reason['cancel_reason'],
  177. ];
  178. return Db::transaction(function () use ($order, $data) {
  179. $mark = $data['reason'];
  180. if ($order['station_type'] == DeliverySevices::DELIVERY_TYPE_DADA) {
  181. $options = DeliverySevices::create(DeliverySevices::DELIVERY_TYPE_DADA)->reasons();
  182. $mark = $options[$data['reason']];
  183. }
  184. if ($data['cancel_reason']) $mark .= ',' . $data['cancel_reason'];
  185. $res = DeliverySevices::create($order['station_type'])->cancelOrder($data);
  186. $deduct_fee = $res['deduct_fee'] ?? 0;
  187. $this->cancelAfter($order, $deduct_fee, $mark);
  188. //订单记录
  189. $statusRepository = app()->make(StoreOrderStatusRepository::class);
  190. $orderStatus = [
  191. 'order_id' => $order->order_id,
  192. 'order_sn' => $order->order_sn,
  193. 'type' => $statusRepository::TYPE_ORDER,
  194. 'change_message' => '同城配送订单已取消',
  195. 'change_type' => $statusRepository::ORDER_DELIVERY_CITY_CANCEL,
  196. ];
  197. $statusRepository->createAdminLog($orderStatus);
  198. });
  199. }
  200. /**
  201. * 订单取消后操作
  202. * @param $deliveryOrder
  203. * @param $deductFee
  204. * @param $mark
  205. * @return void
  206. * @author Qinii
  207. */
  208. public function cancelAfter($deliveryOrder, $deductFee, $mark)
  209. {
  210. //修改配送订单
  211. $deliveryOrder->status = -1;
  212. $deliveryOrder->reason = $mark;
  213. $deliveryOrder->deduct_fee = $deductFee;
  214. $deliveryOrder->save();
  215. //修改商城订单
  216. $res = app()->make(StoreOrderRepository::class)->get($deliveryOrder['order_id']);
  217. $res->status = 0;
  218. $res->delivery_type = 0;
  219. $res->delivery_name = '';
  220. $res->delivery_id = '';
  221. $res->save();
  222. //修改商户
  223. $merchant = app()->make(MerchantRepository::class)->get($deliveryOrder['mer_id']);
  224. $balance = bcadd(bcsub($deliveryOrder['fee'], $deductFee, 2), $merchant->delivery_balance, 2);
  225. $merchant->delivery_balance = $balance;
  226. $merchant->save();
  227. }
  228. /**
  229. * 同城配送订单信息回调
  230. * @param $data
  231. * @author Qinii
  232. * @day 2/17/22
  233. */
  234. public function notify($data)
  235. {
  236. //达达
  237. /**
  238. * 订单状态(待接单=1,待取货=2,配送中=3,已完成=4,已取消=5, 指派单=8,妥投异常之物品返回中=9, 妥投异常之物品返回完成=10, 骑士到店=100,创建达达运单失败=1000 可参考文末的状态说明)
  239. */
  240. Log::info('同城回调参数:' . var_export(['=======', $data, '======='], 1));
  241. if (isset($data['data'])) {
  242. $data = json_decode($data['data'], 1);
  243. }
  244. $reason = '';
  245. $deductFee = 0;
  246. $delivery = [];
  247. if (isset($data['order_status'])) {
  248. $order_sn = $data['order_id'];
  249. if ($data['order_status'] == 1) {
  250. $orderData = $this->dao->getSearch(['sn' => $data['order_id']])->find();
  251. if (!$orderData['finish_code']) {
  252. $orderData->finish_code = $data['finish_code'];
  253. $orderData->save();
  254. }
  255. return;
  256. } else if (in_array($data['order_status'], [2, 3, 4, 5, 9, 10, 100])) {
  257. $status = $data['order_status'];
  258. if ($data['order_status'] == 5) {
  259. $msg = [
  260. '取消:',
  261. '达达配送员取消:',
  262. '商家主动取消:',
  263. '系统或客服取消:',
  264. ];
  265. //1:达达配送员取消;2:商家主动取消;3:系统或客服取消;0:默认值
  266. $status = -1;
  267. $reason = $msg[$data['cancel_from']] . $data['cancel_reason'];
  268. }
  269. $deductFee = $data['deductFee'] ?? 0;
  270. if (isset($data['dm_name']) && $data['dm_name']) {
  271. $delivery = [
  272. 'delivery_name' => $data['dm_name'],
  273. 'delivery_id' => $data['dm_mobile'],
  274. ];
  275. }
  276. }
  277. } else if (isset($data['state'])) { //uu
  278. if (!$data['origin_id']) $deliveryOrder = $this->dao->getWhere(['order_code' => $data['order_code']]);
  279. $order_sn = $data['origin_id'] ?: $deliveryOrder['order_sn'];
  280. //当前状态 1下单成功 3跑男抢单 4已到达 5已取件 6到达目的地 10收件人已收货 -1订单取消
  281. switch ($data['state']) {
  282. case 3:
  283. $status = 2;
  284. break;
  285. case 4:
  286. $status = 100;
  287. break;
  288. case 5:
  289. $status = 3;
  290. break;
  291. case 10:
  292. $status = 4;
  293. break;
  294. case -1:
  295. $status = -1;
  296. $reason = $data['state_text'];
  297. break;
  298. default:
  299. break;
  300. }
  301. if (isset($data['driver_name']) && $data['driver_name']) {
  302. $delivery = [
  303. 'delivery_name' => $data['driver_name'],
  304. 'delivery_id' => $data['driver_mobile'],
  305. ];
  306. }
  307. }
  308. if (isset($order_sn) && isset($status)) {
  309. $res = $this->dao->getWhere(['order_sn' => $order_sn]);
  310. if ($res) {
  311. $this->notifyAfter($status, $reason, $res, $delivery, $deductFee);
  312. } else {
  313. Log::info('同城配送回调,未查询到订单:' . $order_sn);
  314. }
  315. }
  316. }
  317. /**
  318. * 同城配送回调
  319. * @param $status
  320. * @param $reason
  321. * @param $res
  322. * @param $data
  323. * @param $deductFee
  324. * @throws \think\db\exception\DataNotFoundException
  325. * @throws \think\db\exception\DbException
  326. * @throws \think\db\exception\ModelNotFoundException
  327. * @author wuhaotian
  328. * @email 442384644@qq.com
  329. * @date 2024/7/5
  330. */
  331. public function notifyAfter($status, $reason, $res, $data, $deductFee)
  332. {
  333. if (!isset($this->statusData[$status])) return;
  334. $make = app()->make(StoreOrderRepository::class);
  335. $orderData = $make->get($res['order_id']);
  336. if ($orderData['status'] != $status) {
  337. $res->status = $status;
  338. $res->reason = $reason;
  339. $res->save();
  340. //订单记录
  341. $statusRepository = app()->make(StoreOrderStatusRepository::class);
  342. $message = '订单同城配送【' . $this->statusData[$status] . '】';
  343. $orderStatus = [
  344. 'order_id' => $orderData['order_id'],
  345. 'order_sn' => $orderData['order_sn'],
  346. 'type' => $statusRepository::TYPE_ORDER,
  347. 'change_message' => $message,
  348. 'change_type' => $this->message[$status],
  349. ];
  350. $statusRepository->createSysLog($orderStatus);
  351. if ($status == 2 && !empty($data))
  352. $make->update($res['order_id'], $data);
  353. if ($status == 4) {
  354. $order = $make->get($res['order_id']);
  355. $user = app()->make(UserRepository::class)->get($order['uid']);
  356. $make->update($res['order_id'], ['status' => 2]);
  357. $make->takeAfter($order, $user);
  358. }
  359. if ($status == -1)
  360. $this->cancelAfter($res, $deductFee, $reason);
  361. }
  362. }
  363. /**
  364. * 创建配送订单
  365. * @param $id
  366. * @param $merId
  367. * @param $data
  368. * @param $order
  369. * @return bool
  370. * @author wuhaotian
  371. * @email 442384644@qq.com
  372. * @date 2024/7/5
  373. */
  374. public function create($id, $merId, $data, $order)
  375. {
  376. $type = systemConfig('delivery_type');
  377. $callback_url = rtrim(systemConfig('site_url'), '/') . '/api/notice/callback';
  378. $where = ['station_id' => $data['station_id'], 'mer_id' => $merId, 'status' => 1, 'type' => $type];
  379. $station = app()->make(DeliveryStationRepository::class)->getWhere($where);
  380. if (!$station) throw new ValidateException('门店信息不存在');
  381. if (!$station['city_name']) throw new ValidateException('门店缺少所在城市,请重新编辑门店信息');
  382. //地址转经纬度
  383. try {
  384. $addres = lbs_address($station['city_name'], $order['user_address']);
  385. if ($type == DeliverySevices::DELIVERY_TYPE_UU) {
  386. [$location['lng'], $location['lat']] = gcj02ToBd09($addres['location']['lng'], $addres['location']['lat']);
  387. } else {
  388. $location = $addres['location'];
  389. }
  390. } catch (\Exception $e) {
  391. throw new ValidateException('获取经纬度失败');
  392. }
  393. $getPriceParams = $this->getPriceParams($station, $order, $location, $type);
  394. $orderSn = $this->getOrderSn();
  395. $getPriceParams['origin_id'] = $orderSn;
  396. $getPriceParams['callback_url'] = $callback_url;
  397. $getPriceParams['cargo_weight'] = $data['cargo_weight'] ?? 0;
  398. $service = DeliverySevices::create($type);
  399. //计算价格
  400. $priceData = $service->getOrderPrice($getPriceParams);
  401. if ($type == DeliverySevices::DELIVERY_TYPE_UU) { //uu
  402. $priceData['receiver'] = $order['real_name'];
  403. $priceData['receiver_phone'] = $order['user_phone'];
  404. $priceData['note'] = $data['mark'];
  405. $priceData['callback_url'] = $callback_url;
  406. $priceData['push_type'] = 2;
  407. $priceData['special_type'] = $data['special_type'] ?? 0;
  408. }
  409. app()->make(MerchantRepository::class)->changeDeliveryBalance($merId, $priceData['fee'] ?? $priceData['need_paymoney']);
  410. //发布订单
  411. Db::startTrans();
  412. try {
  413. $res = $service->addOrder($priceData);
  414. $ret = [
  415. 'station_id' => $data['station_id'],
  416. 'order_sn' => $orderSn,
  417. 'city_code' => $station['city_name'],
  418. 'receiver_phone' => $order['user_phone'],
  419. 'user_name' => $order['real_name'],
  420. 'from_address' => $station['station_address'],
  421. 'to_address' => $order['user_address'],
  422. 'order_code' => $type == 2 ? $res['ordercode'] : $priceData['deliveryNo'],
  423. 'order_id' => $id,
  424. 'mer_id' => $merId,
  425. 'info' => $data['mark'],
  426. 'status' => $res['status'] ?? 0,
  427. 'station_type' => $type,
  428. 'to_lat' => $addres['location']['lat'],
  429. 'to_lng' => $addres['location']['lng'],
  430. 'from_lat' => $station['lat'],
  431. 'from_lng' => $station['lng'],
  432. 'distance' => $priceData['distance'],
  433. 'fee' => $priceData['fee'] ?? $priceData['need_paymoney'],
  434. 'mark' => $data['mark'],
  435. 'uid' => $order['uid'],
  436. ];
  437. //入库操作
  438. $this->dao->create($ret);
  439. Db::commit();
  440. return true;
  441. } catch (\Exception $exception) {
  442. if (isset($res['status']) && $res['status'] == 'success') {
  443. $error['origin_id'] = $orderSn;
  444. $error['reason'] = $type == 1 ? 36 : '信息错误';
  445. $error['order_code'] = $type == 2 ? $res['ordercode'] : $priceData['deliveryNo'];
  446. sleep(1);
  447. $service->cancelOrder($error);
  448. }
  449. Db::rollback();
  450. throw new ValidateException($exception->getMessage());
  451. }
  452. }
  453. /**
  454. * 获取订单价格参数
  455. * @param DeliveryStation $deliveryStation
  456. * @param StoreOrder $order
  457. * @param array $addres
  458. * @param int $type
  459. * @return array
  460. * @author wuhaotian
  461. * @email 442384644@qq.com
  462. * @date 2024/7/5
  463. */
  464. public function getPriceParams(DeliveryStation $deliveryStation, StoreOrder $order, array $addres, int $type)
  465. {
  466. $data = [];
  467. $type = (int)$type;
  468. switch ($type) {
  469. case 1:
  470. $city = DeliverySevices::create(DeliverySevices::DELIVERY_TYPE_DADA)->getCity([]);
  471. $res = [];
  472. foreach ($city as $item) {
  473. $res[$item['label']] = $item['key'];
  474. }
  475. $data = [
  476. 'shop_no' => $deliveryStation['origin_shop_id'],
  477. 'city_code' => $res[$deliveryStation['city_name']],
  478. 'cargo_price' => $order['pay_price'],
  479. 'is_prepay' => 0,
  480. 'receiver_name' => $order['real_name'],
  481. 'receiver_address' => $order['user_address'],
  482. 'cargo_weight' => 0,
  483. 'receiver_phone' => $order['user_phone'],
  484. 'is_finish_code_needed' => 1,
  485. ];
  486. break;
  487. case 2:
  488. $data = [
  489. 'from_address' => $deliveryStation['station_address'],
  490. 'to_address' => $order['user_address'],
  491. 'city_name' => $deliveryStation['city_name'],
  492. 'goods_type' => $deliveryStation['business']['label'],
  493. 'send_type' => '0',
  494. 'to_lat' => $addres['lat'],
  495. 'to_lng' => $addres['lng'],
  496. 'from_lat' => $deliveryStation['lat'],
  497. 'from_lng' => $deliveryStation['lng'],
  498. ];
  499. break;
  500. }
  501. return $data;
  502. }
  503. public function getTitle()
  504. {
  505. $query = app()->make(MerchantRepository::class)->getSearch(['is_del' => 0]);
  506. $merchant = $query->count();
  507. $price = app()->make(ServeOrderRepository::class)
  508. ->getSearch(['type' => 10, 'status' => 1])->sum('pay_price');
  509. $balance = $query->sum('delivery_balance');
  510. return [
  511. [
  512. 'className' => 'el-icon-s-order',
  513. 'count' => $merchant,
  514. 'field' => '个',
  515. 'name' => '商户数'
  516. ],
  517. [
  518. 'className' => 'el-icon-s-order',
  519. 'count' => $price,
  520. 'field' => '元',
  521. 'name' => '商户充值总金额'
  522. ],
  523. [
  524. 'className' => 'el-icon-s-order',
  525. 'count' => $balance,
  526. 'field' => '元',
  527. 'name' => '商户当前余额'
  528. ],
  529. ];
  530. }
  531. /**
  532. * 销毁订单。
  533. * 本函数用于根据给定的订单ID和商家ID删除订单。首先,它会验证订单是否存在,如果不存在,则抛出一个异常;
  534. * 如果存在,则执行删除操作。
  535. *
  536. * @param int $id 订单ID。这是主键,用于唯一标识一个订单。
  537. * @param int $merId 商家ID。用于确定订单所属的商家。
  538. * @return bool 返回删除操作的结果。如果删除成功,返回true;否则,返回false。
  539. * @throws ValidateException 如果订单不存在,则抛出此异常。
  540. */
  541. public function destory($id, $merId)
  542. {
  543. // 根据订单ID和商家ID构建查询条件
  544. $where = [
  545. $this->dao->getPk() => $id, // 使用主键作为查询条件之一
  546. 'mer_id' => $merId, // 商家ID作为查询条件之一
  547. ];
  548. // 根据查询条件查找订单
  549. $res = $this->dao->getSearch($where)->find();
  550. // 如果查询结果为空,即订单不存在,则抛出异常
  551. if (!$res) throw new ValidateException('订单不存在');
  552. // 删除订单,并返回删除结果
  553. return $this->dao->delete($id);
  554. }
  555. /**
  556. * 生成订单编号
  557. *
  558. * 本函数用于生成唯一的订单编号。编号由时间戳和随机数组成,确保了编号的唯一性和可追踪性。
  559. * 时间戳部分精确到毫秒,增加了编号的唯一性,随机数部分进一步确保了即使在毫秒级别内有多个订单生成,也能得到不同的编号。
  560. *
  561. * @return string 返回生成的订单编号
  562. */
  563. public function getOrderSn()
  564. {
  565. // 获取当前时间的微秒和秒部分
  566. list($msec, $sec) = explode(' ', microtime());
  567. // 将微秒和秒转换为毫秒,并格式化为整数,用于订单编号的时间戳部分
  568. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  569. // 生成订单编号:前缀 + 毫秒时间戳 + 随机数
  570. // 使用'dc'作为前缀,表示订单编号的来源或类型
  571. // 随机数生成范围确保大于毫秒时间戳转换的整数,避免重复,并且预设了一个最小值98369,以保持编号的一定长度和特征
  572. $orderId = 'dc' . $msectime . random_int(10000, max(intval($msec * 10000) + 10000, 98369));
  573. return $orderId;
  574. }
  575. /**
  576. * 根据订单ID和用户ID查询订单信息
  577. *
  578. * 本函数用于通过给定的订单ID和用户ID,从数据库中检索相应的订单信息。
  579. * 如果找不到匹配的订单,将抛出一个验证异常,指出订单不存在。
  580. * 这是对前端接口的封装,确保了只有合法的订单才能被查询和访问。
  581. *
  582. * @param int $id 订单ID
  583. * @param int $uid 用户ID
  584. * @return array 查询到的订单信息
  585. * @throws ValidateException 如果订单不存在则抛出异常
  586. */
  587. public function show(int $id, int $uid)
  588. {
  589. // 构建查询条件
  590. $where['order_id'] = $id;
  591. $where['uid'] = $uid;
  592. // 执行查询,同时加载订单状态和订单详情
  593. $res = $this->dao->getSearch($where)->with(['storeOrderStatus', 'storeOrder'])->find();
  594. // 如果查询结果为空,则抛出异常提示订单不存在
  595. if (!$res) throw new ValidateException('订单不存在');
  596. // 返回查询结果
  597. return $res;
  598. }
  599. }