ReserveOrderService.php 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. <?php
  2. namespace addons\Store\common\services;
  3. use addons\ReservationService\common\enums\ReservationServiceEnum;
  4. use addons\ReservationService\common\models\ReservationServiceOccupy;
  5. use addons\ReservationService\common\models\ReservationServiceOrder;
  6. use addons\ReservationService\common\models\ReservationServiceStoreGoods;
  7. use addons\ReservationService\common\models\ReservationServiceStoreSecondaryCard;
  8. use addons\ReservationService\common\models\ReservationServiceUser;
  9. use addons\ReservationService\common\models\ReservationServiceWorkTime;
  10. use addons\ReservationService\common\services\OrderService;
  11. use addons\ReservationService\common\services\TechniciansService;
  12. use addons\SecondaryCard\common\models\SecondaryCard;
  13. use addons\Store\common\enums\ReserveServiceEnum;
  14. use addons\Store\common\models\Store;
  15. use addons\Store\common\models\StoreGoods;
  16. use addons\Store\common\models\StoreGoodsReserveSku;
  17. use addons\Store\common\models\StoreOrder;
  18. use addons\Store\common\models\StoreOrderDetail;
  19. use addons\Store\common\models\StoreOrderReserve;
  20. use addons\Store\common\models\StoreReserveSetting;
  21. use addons\Store\common\models\StoreReserveTechnicianScheduling;
  22. use addons\Store\common\models\StoreUser;
  23. use common\enums\AddonsEnum;
  24. use common\enums\ClerkEnum;
  25. use common\enums\GoodsTypeEnum;
  26. use common\enums\OrderSourceEnum;
  27. use common\enums\OrderStatusEnum;
  28. use common\enums\RefundStatusEnum;
  29. use common\enums\StatusEnum;
  30. use common\enums\UserWalletEnum;
  31. use common\helpers\LockHelper;
  32. use common\logic\order\OrderRefundLogic;
  33. use common\models\goods\GoodsReserveTime;
  34. use common\models\order\OrderDetail;
  35. use common\models\order\OrderRefund;
  36. use common\models\order\OrderReserve;
  37. use common\models\user\User;
  38. use common\models\mall\MallAddons;
  39. use common\models\user\UserAddress;
  40. use Exception;
  41. use Yii;
  42. use common\models\order\Order;
  43. /**
  44. * 当前文件没用上
  45. * 预约订单
  46. */
  47. class ReserveOrderService extends BaseService
  48. {
  49. /**
  50. * @var int
  51. */
  52. public $user_id = 0;
  53. public $store = null;
  54. public function page(array $params)
  55. {
  56. $params['store_id'] = $this->store_id;
  57. // 预约订单
  58. $ret = (new OrderService())->page($this->mall_id, $params);
  59. if (!empty($ret['list'])) {
  60. $order_nos = array_column($ret['list'], 'order_no'); // 平台的ID
  61. // 门店的订单ID
  62. $store_order_nos = StoreOrder::lists([
  63. 'where' => [
  64. ['order_no' => $order_nos]
  65. ],
  66. 'select' => 'order_no, id',
  67. 'index' => 'order_no'
  68. ]);
  69. if (!empty($store_order_nos)) {
  70. $store_order_ids = array_unique(array_column($store_order_nos, 'id'));
  71. if (!empty($store_order_ids)) {
  72. $orders = StoreOrderReserve::lists([
  73. 'where' => [
  74. ['order_id' => $store_order_ids]
  75. ],
  76. 'index' => 'order_id'
  77. ]);
  78. foreach ($ret['list'] as &$item) {
  79. $item['reserveOrder'] = $orders[$store_order_nos[$item['order_no']]['id']] ?? [];
  80. }
  81. }
  82. }
  83. }
  84. return $ret;
  85. }
  86. public function detail(int $id)
  87. {
  88. // 预约订单详情
  89. return (new OrderService())->getDetailByCodeOrId($this->mall_id, 0, '', $id, $this->store_id);
  90. }
  91. /**
  92. * 完成
  93. * @param int $id
  94. * @return ReservationServiceOrder|string
  95. */
  96. public function underwriter(int $id)
  97. {
  98. // 预约订单核销
  99. return (new OrderService())->underwriter($this->mall_id, $id, $this->user_id, $this->store_id);
  100. }
  101. /**
  102. * 完成
  103. * @param int $id
  104. * @return ReservationServiceOrder|string
  105. */
  106. public function acceptance(int $id)
  107. {
  108. // 预约订单核销
  109. return (new OrderService())->acceptance($this->mall_id, $id, $this->user_id, $this->store_id);
  110. }
  111. /**
  112. * 执行预约
  113. * @param int $order_id
  114. * @param int $tech_id
  115. * @param string $select_time
  116. * @return string|true
  117. */
  118. public function reserve(int $order_id, int $tech_id, string $select_time)
  119. {
  120. try {
  121. $reserveOrder = StoreOrderReserve::findOne(['order_id' => $order_id]);
  122. if (empty($reserveOrder)) throw new \Exception('订单未找到');
  123. if ($reserveOrder->reserve_type != StatusEnum::ENABLED) {
  124. throw new \Exception('当前订单不可进行预约');
  125. }
  126. if ($reserveOrder->reserve_status != 0) {
  127. throw new \Exception('当前订单不可进行预约.');
  128. }
  129. if ($reserveOrder->order_status != OrderStatusEnum::SHIPMENTS) {
  130. throw new \Exception('当前订单不可进行预约!');
  131. }
  132. // 数据校验
  133. if (!MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_RESERVATION_SERVICE)) {
  134. throw new \Exception('您还未安装当前插件');
  135. }
  136. $time = strtotime($select_time);
  137. if ($time <= time()) throw new \Exception('选择时间错误');
  138. //检测技师
  139. $orderDetail = StoreOrderDetail::findOne(['order_id' => $reserveOrder->order_id]);
  140. $check = TechniciansService::checkCanOrder($this->mall_id, $tech_id, $select_time, $orderDetail->goods_id,
  141. $orderDetail->goods_attr_id, $reserveOrder->lat, $reserveOrder->lng);
  142. if (!$check) throw new \Exception(TechniciansService::getStaticError());
  143. // 开始处理
  144. $t = Yii::$app->db->beginTransaction();
  145. try {
  146. // 处理数据
  147. $reserveOrder->tech_id = $tech_id;
  148. $reserveOrder->reserve_date_time = $select_time;
  149. $reserveOrder->reserve_time_range_type = 2;
  150. if (!$reserveOrder->save()) throw new \Exception($reserveOrder->getErrorMessage());
  151. $order = StoreOrder::findOne(['id' => $reserveOrder->order_id]);
  152. $start_at = strtotime($select_time);
  153. $sku = StoreGoodsReserveSku::findOne(['id' => $orderDetail->goods_attr_id]);
  154. (new OrderService())->save([
  155. 'mall_id' => $this->mall_id,
  156. 'user_id' => $reserveOrder->user_id,
  157. 'tech_id' => $tech_id,
  158. 'order_id' => $order_id,
  159. 'order_no' => $order->order_no,
  160. 'service_start_at' => $start_at,
  161. 'service_end_at' => $start_at + ($sku->service_min * 60),
  162. 'remark' => '',
  163. 'commission' => 0,
  164. 'order_detail_id' => $orderDetail->id,
  165. 'goods_id' => $orderDetail->goods_id,
  166. 'lng' => $reserveOrder->lng,
  167. 'lat' => $reserveOrder->lat,
  168. 'goods_price' => $orderDetail->goods_price,
  169. 'store_id' => $this->store_id
  170. ]);
  171. $t->commit();
  172. } catch (\Exception $e) {
  173. $t->rollBack();
  174. throw new \Exception($e->getMessage());
  175. }
  176. } catch (\Exception $e) {
  177. return $e->getMessage();
  178. }
  179. return true;
  180. }
  181. public function getEditData($params)
  182. {
  183. $goods_list = StoreGoods::lists([
  184. 'where' => [
  185. ['store_id' => $this->store_id],
  186. ['status' => StatusEnum::ENABLED],
  187. ['check_status' => StatusEnum::ENABLED],
  188. ['is_on_sale' => StatusEnum::ENABLED],
  189. ['goods_type' => GoodsTypeEnum::GoodsTypeReserved],
  190. ],
  191. 'select' => 'id,goods_name',
  192. 'with' => ['reserve' => function ($q) {
  193. $q->select('id,goods_id,service_min');
  194. }],
  195. ]);
  196. $store_reserve_setting = StoreReserveSetting::getOne([['store_id' => $this->store_id]]);
  197. $setting = [];
  198. if ($store_reserve_setting) {
  199. $setting = json_decode($store_reserve_setting['setting'], true);
  200. }
  201. $ret['goods_list'] = $goods_list;
  202. $ret['range_start'] = $setting['range_start'] ?? 1;
  203. $ret['range_end'] = $setting['range_end'] ?? 1;
  204. $order = [];
  205. $goods_name = '';
  206. $service_type_arr = [];
  207. if (!empty($params['id'])) {
  208. $order = ReservationServiceOrder::getOne([
  209. ['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]
  210. ],
  211. true
  212. );
  213. $user = User::findOne(['id' => $order['user_id']]);
  214. $order['mobile'] = $user['mobile'];
  215. $order['nickname'] = !empty($user['nickname']) ? $user['nickname'] : $user['mobile'];
  216. $order['at_date'] = date('Y-m-d', $order['service_start_at']);
  217. $order['at_time'] = date('H:i', $order['service_start_at']);
  218. $params['goods_id'] = $order['goods_id'];
  219. $params['sku_id'] = $order['goods_reserve_sku_id'];
  220. $order['sku_id'] = $order['goods_reserve_sku_id'];
  221. if (empty($order['staff_user_id'])) {
  222. $order['staff_user_id'] = '';
  223. }
  224. if (empty($order['secondary_card_id'])) {
  225. $sku = StoreGoodsReserveSku::findOne(['id' => $order['sku_id']]);
  226. if (empty($sku['name'])) {
  227. $store_goods = StoreGoods::findOne(['id' => $order['goods_id']]);
  228. $goods_name = $store_goods['goods_name'];
  229. } else {
  230. $goods_name = $sku['name'];
  231. }
  232. $ret['staff_user_list'] = $this->getStaffUserList($params);
  233. $order['master'] = [
  234. ['sku_id' => $order['sku_id'], 'staff_user_id' => $order['staff_user_id'], 'service_min' => $sku['service_min'] ?? 0]
  235. ];
  236. } else {
  237. $params['secondary_card_id'] = $order['secondary_card_id'];
  238. $secondary_card = SecondaryCard::getOne([['id' => $order['secondary_card_id']]]);
  239. $goods_name = $secondary_card['name'] ?? '';
  240. $ret['staff_user_list'] = $this->getStaffUserListBySecondaryCard($params);
  241. $order['master'] = [
  242. ['sku_id' => $order['secondary_card_id'], 'staff_user_id' => $order['staff_user_id'], 'service_min' => $secondary_card['appointment_interval_duration'] ?? 0]
  243. ];
  244. switch ($secondary_card['reservation_service_type']) {
  245. case 1:
  246. $service_type_arr[] = ['value' => 1, 'label' => '上门服务'];
  247. break;
  248. case 2:
  249. $service_type_arr[] = ['value' => 2, 'label' => '到店服务'];
  250. break;
  251. case 3:
  252. $service_type_arr[] = ['value' => 1, 'label' => '上门服务'];
  253. $service_type_arr[] = ['value' => 2, 'label' => '到店服务'];
  254. break;
  255. }
  256. }
  257. }
  258. $ret['service_type_arr'] = $service_type_arr;
  259. $ret['reserve_order'] = $order;
  260. $ret['goods_name'] = $goods_name;
  261. $store = $params['store'];
  262. $business_time_start = strtotime(date('Y-m-d') . ' ' . $store['business_time_start'] . ':00');
  263. $business_time_end = strtotime(date('Y-m-d') . ' ' . $store['business_time_end'] . ':00');
  264. $H = date('H', $business_time_start);
  265. $start_time = $H * 60;
  266. $H = date('H', $business_time_end);
  267. $minute = date('i', $business_time_end);
  268. $end_time = $H * 60 + $minute;
  269. $ret['start_time'] = $start_time;
  270. $ret['end_time'] = $end_time;
  271. return $ret;
  272. }
  273. /**
  274. * 后台添加预约
  275. * @param $params
  276. * @return array
  277. * @throws \yii\base\Exception
  278. * @throws \yii\db\Exception
  279. */
  280. public function setEditData($params)
  281. {
  282. $t = Yii::$app->db->beginTransaction();
  283. try {
  284. $user = User::findOne(['mobile' => $params['mobile'], 'mall_id' => $this->mall_id]);
  285. $this->store = $params['store'];
  286. if (!empty($user)) {
  287. if ($user['status'] != StatusEnum::ENABLED) {
  288. throw new \Exception('用户状态异常');
  289. } else {
  290. $params['user_id'] = $user['id'];
  291. }
  292. } else {
  293. //注册用户
  294. $user = $this->setUser($params);
  295. $params['user_id'] = $user['id'];
  296. }
  297. $update_order = [];
  298. if ($params['service_type'] == ReserveServiceEnum::DOOR_TO_DOOR) {//上门
  299. if (!empty($params['secondary_card_id'])) { // 因为只有次卡是没有选择服务地址的所以只修改次卡
  300. $user_address = UserAddress::find()->where(['user_id' => $params['user_id'], 'status' => StatusEnum::ENABLED])
  301. ->orderBy('is_default DESC, id DESC')->one(); // 获取会员默认地址:当前会员没有默认地址时,默认取第一个地址
  302. if (empty($user_address)) {
  303. throw new \Exception('该会员没有设置默认地址');
  304. }
  305. $update_order['province'] = $user_address['province_id'];
  306. $update_order['city'] = $user_address['city_id'];
  307. $update_order['area'] = $user_address['district_id'];
  308. $update_order['address'] = $user_address['detail'];
  309. $update_order['receiver_name'] = $user_address['name'];
  310. $update_order['mobile'] = $user_address['mobile'];
  311. }
  312. } else {
  313. $update_order['province'] = $this->store['province_id'];
  314. $update_order['city'] = $this->store['city_id'];
  315. $update_order['area'] = $this->store['district_id'];
  316. $update_order['address'] = $this->store['address'];
  317. $update_order['receiver_name'] = $this->store['store_name'];
  318. $update_order['mobile'] = $this->store['shop_mobile'];
  319. }
  320. $add_user_data = [
  321. 'mall_id' => $this->mall_id,
  322. 'user_id' => $params['user_id'],
  323. 'store_id' => $this->store_id,
  324. ];
  325. $res = StoreUser:: setData($add_user_data);
  326. $service_start_at = strtotime(date('Y-m-d', strtotime($params['at_date'])) . ' ' . $params['at_time'] . ':00');
  327. $obj = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]));
  328. $store_reserve_setting = $obj->detail();
  329. $store_goods = $store_goods_reserve_sku = [];
  330. if (!empty($params['id'])) {
  331. $model = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]);
  332. if (empty($model)) {
  333. throw new \Exception('数据不存在');
  334. }
  335. $params['secondary_card_id'] = $model['secondary_card_id'];
  336. }
  337. $params['staff_user_id'] = !empty($params['master'][0]['staff_user_id']) ? $params['master'][0]['staff_user_id'] : 0;
  338. if (empty($params['secondary_card_id'])) {
  339. $params['sku_id'] = $params['master'][0]['sku_id'];;
  340. $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
  341. if (empty($store_goods_reserve_sku)) {
  342. throw new \Exception('预约商品规格不存在');
  343. }
  344. $store_goods = StoreGoods::findOne(['id' => $store_goods_reserve_sku['goods_id']]);
  345. $service_min = $obj->getServiceMin($store_reserve_setting['appointment_interval'], $store_goods_reserve_sku['service_min'] ?? 0);
  346. $goods_id = $store_goods_reserve_sku['goods_id'];
  347. } else {
  348. $secondary_card = SecondaryCard::getOne([['id' => $params['secondary_card_id']]]);
  349. $service_min = $obj->getServiceMin($store_reserve_setting['appointment_interval'], $secondary_card['appointment_interval_duration'] ?? 0);
  350. $goods_id = 0;
  351. $params['sku_id'] = 0;
  352. }
  353. $service_end_at = $service_start_at + $service_min * 60;
  354. $this->checkEdit($params['staff_user_id'], $service_start_at, $service_end_at);
  355. $create_type = null;
  356. if (!empty($params['create_type'])) {
  357. $update['create_type'] = $params['create_type'];
  358. $create_type = $params['create_type'];
  359. }
  360. if (!empty($params['id'])) {
  361. $reservation_service_order_id = $params['id'];
  362. if ($params['staff_user_id'] != $model['staff_user_id']) {
  363. $staff = ReservationServiceUser::findOne(['user_id' => $params['staff_user_id'], 'status' => StatusEnum::ENABLED]);
  364. }
  365. } else {
  366. $reservation_service_user = ReservationServiceUser::findOne(['user_id' => $params['staff_user_id'], 'status' => StatusEnum::ENABLED]);
  367. $this->user_id = $params['user_id'];
  368. $main_order_detail_id = 0;
  369. $order = $this->createOrder($store_goods, $store_goods_reserve_sku, $service_start_at, $create_type, $reservation_service_user['id'] ?? 0, $main_order_detail_id);
  370. $model = new ReservationServiceOrder();
  371. $model->loadDefaultValues();
  372. $model->mall_id = $this->mall_id;
  373. $model->store_id = $this->store_id;
  374. $reservation_service_order_id = null;
  375. $model->order_no = $order['order_no'];
  376. $model->order_id = $order['id'];
  377. $model->order_detail_id = $main_order_detail_id;
  378. $model->service_status = ReservationServiceEnum::ALREADY_BOOKED;
  379. $model->server_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING;
  380. }
  381. $model->user_id = $params['user_id'];
  382. $model->staff_user_id = $params['staff_user_id'];
  383. $model->goods_id = $goods_id;
  384. $model->service_start_at = $service_start_at;
  385. $model->service_end_at = $service_end_at;
  386. $model->reservation_model = $params['reservation_model'];
  387. $model->goods_reserve_sku_id = $params['sku_id'];
  388. if (!empty($params['create_type'])) {
  389. $model->create_type = $params['create_type'];
  390. }
  391. if (!empty($params['service_type'])) {
  392. $model->service_type = $params['service_type'];
  393. }
  394. $res = $model->save();
  395. $reserve_date_time = date('Y-m-d H:i', $model->service_start_at) . ',' . date('Y-m-d H:i', $model->service_end_at);
  396. $update['reserve_date_time'] = $reserve_date_time;
  397. $update['service_start_at'] = $model->service_start_at;
  398. $update['service_end_at'] = $model->service_end_at;
  399. $update['service_type'] = $model->service_type;
  400. $update['reservation_service_order_id'] = $model['id'];
  401. if (isset($staff)) {
  402. $update['tech_id'] = $staff['id'];
  403. }
  404. StoreOrderReserve::updateAll($update, ['main_order_id' => $model['order_id']]);
  405. unset($update['create_type']);
  406. OrderReserve::updateAll($update, ['order_id' => $model['order_id']]);
  407. if (!empty($update_order)) {
  408. Order::updateAll($update_order, ['id' => $model['order_id']]);
  409. StoreOrder::updateAll($update_order, ['order_no' => $model['order_no']]);
  410. }
  411. if ($res == false) {
  412. throw new \Exception($model->getErrorMessage());
  413. }
  414. $t->commit();
  415. return ['id' => $model['id']];
  416. } catch (\Exception $e) {
  417. $t->rollBack();
  418. throw new \Exception($e->getMessage());
  419. }
  420. }
  421. public function createOrder($goods, $sku, $select_time, $create_type, $tech_id, &$main_order_detail_id)
  422. {
  423. $store_order_detail = $order_detail = null;
  424. $store_order = $this->createStoreOrder($goods, $sku, $store_order_detail);
  425. $main_order = $this->createMallOrder($store_order['order_no'], $store_order['clerk_code'], $goods, $sku, $order_detail);
  426. $store_order_detail->main_order_detail_id = $order_detail['id'];
  427. $main_order_detail_id = $order_detail['id'];
  428. $store_order_detail->save();
  429. $form = [
  430. 'data' => [
  431. 'time_id' => 0,
  432. 'service_type' => 2,
  433. 'latitude' => 0,
  434. 'longitude' => 0,
  435. 'time_spec_id' => 0,
  436. 'tech_id' => $tech_id,
  437. 'create_type' => $create_type,
  438. 'select_time' => date('Y-m-d H:i', $select_time),
  439. ]
  440. ];
  441. $res = StoreOrderReserve::create($store_order, $form, $main_order['id'] ?? 0);
  442. if ($res == false) throw new \Exception(StoreOrderReserve::getStaticError());
  443. $res->reserve_code = $store_order['clerk_code'];
  444. $res->save();
  445. return $main_order;
  446. }
  447. public function createStoreOrder($goods, $store_goods_reserve_sku, &$store_order_detail)
  448. {
  449. $order = new StoreOrder();
  450. $order->loadDefaultValues();
  451. $order->mall_id = $this->mall_id;
  452. $order->user_id = $this->user_id;
  453. $order->store_id = $this->store_id;
  454. $order->order_no = \common\helpers\StringHelper::generateOrderNo('st');
  455. $order->out_trade_no = '';
  456. $order->province = $this->store['province_id'];
  457. $order->city = $this->store['city_id'];
  458. $order->area = $this->store['district_id'];
  459. $order->address = $this->store['address'];
  460. $order->region_name = "";
  461. $order->receiver_name = $this->store['store_name'];
  462. $order->mobile = $this->store['shop_mobile'];
  463. $order->remark = '';
  464. $order->shipping_type = null;
  465. $order->shipping_money = 0;
  466. $order->pay_money = 0;
  467. $order->goods_price = 0;
  468. $order->original_goods_price = 0;
  469. $order->order_status = OrderStatusEnum::SHIPMENTS;
  470. $order->marketing_id = 0;
  471. $order->marketing_type = 'Store';
  472. $order->pay_status = OrderStatusEnum::PAY;
  473. $order->extra_info = [];
  474. $order->payment_type = 0;
  475. $order->pay_time = time();
  476. $order->shipping_time = time();
  477. $order->order_source = 'Reserve';
  478. $order->create_type = 2;
  479. $order->clerk_code = OrderReserve::getClerkCode($this->mall_id, ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE);
  480. $res = $order->save();
  481. if ($res == false) throw new \Exception($order->getErrorMessage());
  482. $store_order_detail = $this->createStoreOrderDetail($order, $goods, $store_goods_reserve_sku);
  483. return $order;
  484. }
  485. protected function createStoreOrderDetail($order, $goods, $store_goods_reserve_sku)
  486. {
  487. // 订单详情
  488. $order_detail = new StoreOrderDetail();
  489. $order_detail->loadDefaultValues();
  490. $order_detail->user_id = $this->user_id;
  491. $order_detail->mall_id = $this->mall_id;
  492. $order_detail->store_id = $this->store_id;
  493. $order_detail->order_id = $order->id;
  494. $order_detail->goods_id = $goods['id'];
  495. $order_detail->goods_attr_id = $store_goods_reserve_sku['id'];
  496. $order_detail->goods_name = $goods->goods_name;
  497. $order_detail->goods_attr_name = $store_goods_reserve_sku['name'];
  498. $order_detail->sign_id = $store_goods_reserve_sku['sign_id'];
  499. $order_detail->price = $store_goods_reserve_sku->price;
  500. $order_detail->cost_price = $store_goods_reserve_sku->cost_price;
  501. $order_detail->original_goods_price = $store_goods_reserve_sku->original_price;
  502. $order_detail->pic_url = $store_goods_reserve_sku->pic_url ? $store_goods_reserve_sku->pic_url : $goods->cover_pic;
  503. $order_detail->goods_price = 0;
  504. $order_detail->num = 1;
  505. $order_detail->order_type = 1;
  506. $order_detail->marketing_id = $order->id;
  507. $order_detail->marketing_type = 'Store';
  508. $order_detail->order_status = OrderStatusEnum::PAY;
  509. $order_detail->remark = '';
  510. $res = $order_detail->save();
  511. if ($res == false) throw new \Exception('生成订单详情失败');
  512. return $order_detail;
  513. }
  514. public function createMallOrder($order_no, $clerk_code, $goods, $store_goods_reserve_sku, &$order_detail)
  515. {
  516. $order = new Order();
  517. $order->loadDefaultValues();
  518. $order->mall_id = $this->mall_id;
  519. $order->user_id = $this->user_id;
  520. $order->store_id = $this->store_id;
  521. $order->order_no = $order_no;
  522. $order->out_trade_no = '';
  523. $order->province = $this->store['province_id'];
  524. $order->city = $this->store['city_id'];
  525. $order->area = $this->store['district_id'];
  526. $order->address = $this->store['address'];
  527. $order->region_name = "";
  528. $order->receiver_name = $this->store['store_name'];
  529. $order->mobile = $this->store['shop_mobile'];
  530. $order->clerk_code = $clerk_code;
  531. $order->remark = '';
  532. $order->shipping_type = null;
  533. $order->shipping_money = 0;
  534. $order->pay_money = 0;
  535. $order->goods_price = 0;
  536. $order->original_goods_price = 0;
  537. $order->order_status = OrderStatusEnum::SHIPMENTS;
  538. $order->marketing_id = 0;
  539. $order->marketing_type = 'Store';
  540. $order->pay_status = OrderStatusEnum::PAY;
  541. $order->extra_info = [];
  542. $order->payment_type = 0;
  543. $order->pay_time = time();
  544. $order->shipping_time = time();
  545. $order->clerk_code = $clerk_code;
  546. $order->order_source = 'ReserveRe';
  547. $res = $order->save();
  548. if ($res == false) throw new \Exception($order->getErrorMessage());
  549. $order_detail = $this->createMallOrderDetail($order, $goods, $store_goods_reserve_sku);
  550. return $order;
  551. }
  552. protected function createMallOrderDetail($order, $goods, $store_goods_reserve_sku)
  553. {
  554. // 订单详情
  555. $order_detail = new OrderDetail();
  556. $order_detail->loadDefaultValues();
  557. $order_detail->user_id = $this->user_id;
  558. $order_detail->mall_id = $this->mall_id;
  559. $order_detail->store_id = $this->store_id;
  560. $order_detail->order_id = $order->id;
  561. $order_detail->goods_id = $goods['id'];
  562. $order_detail->goods_attr_id = $store_goods_reserve_sku['id'];
  563. $order_detail->goods_name = $goods->goods_name;
  564. $order_detail->goods_attr_name = $store_goods_reserve_sku['name'];
  565. $order_detail->sign_id = $store_goods_reserve_sku['sign_id'];
  566. $order_detail->price = $store_goods_reserve_sku->price;
  567. $order_detail->cost_price = $store_goods_reserve_sku->cost_price;
  568. $order_detail->original_goods_price = $store_goods_reserve_sku->original_price;
  569. $order_detail->pic_url = $store_goods_reserve_sku->pic_url ? $store_goods_reserve_sku->pic_url : $goods->cover_pic;
  570. $order_detail->goods_price = 0;
  571. $order_detail->num = 1;
  572. $order_detail->order_type = 1;
  573. $order_detail->marketing_id = $order->id;
  574. $order_detail->marketing_type = 'Store';
  575. $order_detail->order_status = OrderStatusEnum::PAY;
  576. $order_detail->remark = '';
  577. $res = $order_detail->save();
  578. if ($res == false) throw new \Exception('生成订单详情失败');
  579. return $order_detail;
  580. }
  581. /**
  582. * 注册用户
  583. * @param $params
  584. * @return bool|User
  585. * @throws \yii\base\Exception
  586. * @throws \yii\db\Exception
  587. */
  588. protected function setUser($params)
  589. {
  590. $password = substr($params['mobile'], -6, 6);
  591. $params['mall_id'] = $this->mall_id;
  592. if (empty($params['username'])) {
  593. $params['username'] = $params['mobile'];
  594. }
  595. $store = Store::findOne(['id' => $this->store_id]);
  596. $params['parent_id'] = $store['user_id'];
  597. $params['level'] = 0;
  598. $params['source'] = User::SOURCE_ADD_PLATFORM;
  599. $params['platform'] = User::TYPE_MANUAL;
  600. $params['password'] = Yii::$app->getSecurity()->generatePasswordHash($password);
  601. return User::setData($params);
  602. }
  603. /**
  604. * 检查该时间段是否被预约或者被占用
  605. * @param $staff_user_id
  606. * @param $service_start_at
  607. * @param $service_end_at
  608. * @param $reservation_service_order_id
  609. * @return void
  610. * @throws \Exception
  611. */
  612. protected function checkEdit($staff_user_id, $service_start_at, $service_end_at, $reservation_service_order_id = null, $create_type = 2)
  613. {
  614. // if ($create_type != ReservationServiceEnum::SYSTEM_CREATION) {
  615. // $where = [
  616. // ['staff_user_id' => $staff_user_id],
  617. // ['staff_user_id' => $staff_user_id],
  618. // ['!=', 'server_status', ReservationServiceEnum::CANCELED],
  619. // [
  620. // 'or',
  621. // [
  622. // 'and',
  623. // ['>=', 'service_start_at', $service_start_at],
  624. // ['<=', 'service_start_at', $service_end_at],
  625. // ],
  626. // [
  627. // 'and',
  628. // ['>=', 'service_end_at', $service_start_at],
  629. // ['<=', 'service_end_at', $service_end_at],
  630. // ],
  631. // ]
  632. // ];
  633. // if (isset($reservation_service_order_id)) {
  634. // $where[] = ['!=', 'id', $reservation_service_order_id];
  635. // }
  636. // $res = ReservationServiceOrder::lists([
  637. // 'where' => $where
  638. // ]);
  639. // if ($res) {
  640. // throw new \Exception('该时间段已被预约');
  641. // }
  642. // }
  643. $list = ReservationServiceOccupy::lists([
  644. 'where' => [
  645. ['staff_user_id' => $staff_user_id],
  646. ['status' => StatusEnum::ENABLED],
  647. ]
  648. ]);
  649. foreach ($list as $item) {
  650. if ($service_start_at >= $item['start_at'] && $service_start_at < $item['end_at']) {
  651. throw new \Exception('该时间段已被占用');
  652. }
  653. if ($service_end_at >= $item['start_at'] && $service_end_at < $item['end_at']) {
  654. throw new \Exception('该时间段已被占用');
  655. }
  656. }
  657. }
  658. public function getStaffUserList($params)
  659. {
  660. if (empty($params['goods_id'])) {
  661. $sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
  662. $goods_id = $sku['goods_id'];
  663. } else {
  664. $goods_id = $params['goods_id'];
  665. }
  666. $reservation_ervice_store_goods_list = ReservationServiceStoreGoods::lists(['where' => [
  667. ['goods_id' => $goods_id],
  668. ['status' => StatusEnum::ENABLED],
  669. ['store_id' => $this->store_id]
  670. ]]);
  671. $user_ids = array_column($reservation_ervice_store_goods_list, 'user_id');
  672. $list = ReservationServiceUser::lists([
  673. 'where' => [
  674. ['store_id' => $this->store_id],
  675. ['user_id' => $user_ids],
  676. ['status' => StatusEnum::ENABLED]
  677. ],
  678. 'select' => 'user_id,name'
  679. ]);
  680. return $list;
  681. }
  682. public function getStaffUserListBySecondaryCard($params)
  683. {
  684. $reservation_service_store_secondary_card_list = ReservationServiceStoreSecondaryCard::lists(['where' => [
  685. ['secondary_card_id' => $params['secondary_card_id']],
  686. ['status' => StatusEnum::ENABLED],
  687. ['store_id' => $this->store_id]
  688. ]]);
  689. $user_ids = array_column($reservation_service_store_secondary_card_list, 'user_id');
  690. $list = ReservationServiceUser::lists([
  691. 'where' => [
  692. ['store_id' => $this->store_id],
  693. ['user_id' => $user_ids],
  694. ['status' => StatusEnum::ENABLED]
  695. ],
  696. 'select' => 'user_id,name'
  697. ]);
  698. return $list;
  699. }
  700. public function getReserveTime($params)
  701. {
  702. $step = '00:01';
  703. $store = Store::findOne(['id' => $this->store_id]);
  704. $picker_options_time = [
  705. 'start' => $store['business_time_start'],
  706. 'end' => $store['business_time_end'],
  707. 'step' => $step,
  708. ];
  709. return ['picker_options_time' => $picker_options_time];
  710. }
  711. /**
  712. * 后台添加预约/预约看板添加预约,获取可以预约的时间段
  713. * @param $params
  714. * @return array
  715. */
  716. public function getReserveTimes($params)
  717. {
  718. $date_time = strtotime($params['date']);
  719. $staff_user_id = $params['staff_user_id'] ?? 0;
  720. if (!empty($params['staff_user_id'])) {
  721. $scheduling = StoreReserveTechnicianScheduling::getOne([
  722. ['user_id' => $staff_user_id],
  723. ['date_time' => $date_time],
  724. ['status' => StatusEnum::ENABLED]
  725. ], true, ['schedulingTime']);
  726. if (empty($scheduling)) {
  727. return [];
  728. }
  729. }
  730. $buff = [];
  731. $sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
  732. $date_day = date('Y-m-d', strtotime($params['date']));
  733. $time = time();
  734. $service_min = $sku['service_min'];
  735. $obj = new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]);
  736. $store_reserve_setting = $obj->detail();
  737. if (strtotime(date('Y-m-d')) == $date_time) {
  738. $range_start_time = $obj->getRangeStartTime($store_reserve_setting['range_start']);
  739. $time += $range_start_time;
  740. }
  741. $reservation_service_order_list = ReservationServiceOrder::lists([
  742. 'where' => [
  743. ['mall_id' => $this->mall_id],
  744. ['store_id' => $this->store_id],
  745. ['staff_user_id' => $staff_user_id],
  746. ['>=', 'service_start_at', strtotime($date_day . ' 00:00:00')],
  747. ['<=', 'service_end_at', strtotime($date_day . ' 23:59:59')],
  748. ['!=', 'server_status', ReservationServiceEnum::CANCELED]
  749. ]
  750. ]);//已预约
  751. $reservation_service_order_arr = [];
  752. foreach ($reservation_service_order_list as $value) {
  753. $reservation_service_order_arr[$value['service_start_at']] = $value;
  754. }
  755. $occupy_list = ReservationServiceOccupy::lists([
  756. 'where' => [
  757. ['mall_id' => $this->mall_id],
  758. ['store_id' => $this->store_id],
  759. ['staff_user_id' => $staff_user_id],
  760. ['status' => StatusEnum::ENABLED]
  761. ]
  762. ]
  763. );//已占用时间
  764. if (!empty($staff_user_id)) {
  765. if (!empty($scheduling['is_all_day'])) {
  766. //全天
  767. $store = Store::findOne(['id' => $this->store_id]);
  768. $time1 = $date_day . " " . $store['business_time_start'] . ":00";
  769. $time2 = $date_day . " " . $store['business_time_end'] . ":59";
  770. $start = strtotime($time1);
  771. $end = strtotime($time2);
  772. $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff);
  773. } else {
  774. if (!empty($scheduling['schedulingTime'])) {
  775. foreach ($scheduling['schedulingTime'] as $val) {
  776. $start = $val['start_time'];
  777. $end = $val['end_time'];
  778. $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff);
  779. }
  780. }
  781. }
  782. } else {
  783. $store = Store::findOne(['id' => $this->store_id]);
  784. $time1 = $date_day . " " . $store['business_time_start'] . ":00";
  785. $time2 = $date_day . " " . $store['business_time_end'] . ":59";
  786. $start = strtotime($time1);
  787. $end = strtotime($time2);
  788. $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff);
  789. }
  790. return $buff;
  791. }
  792. /**
  793. * @param $start //开始时间
  794. * @param $end //结束时间
  795. * @param $service_min //服务时长
  796. * @param $reservation_service_order_arr //已预约数组
  797. * @param $occupy_list //已占用数组
  798. * @param $time //当前时间
  799. * @param $buff //返回数组
  800. * @return void
  801. */
  802. protected function getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, &$buff)
  803. {
  804. for ($i = $start; $i <= $end; $i = $i + 60 * $service_min) {
  805. if ($i < $time) {
  806. continue;
  807. }
  808. if (isset($reservation_service_order_arr[$i])) {
  809. continue;
  810. }
  811. $is_true = false;
  812. foreach ($occupy_list as $occupy) {
  813. if ($i >= $occupy['start_at'] && $i <= $occupy['end_at']) {
  814. $is_true = true;
  815. break;
  816. }
  817. }
  818. if ($is_true) {
  819. continue;
  820. }
  821. $buff[] = ['time' => date("H:i", $i)];
  822. }
  823. }
  824. public function getReserveDay($params)
  825. {
  826. $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail();
  827. $range_end = $store_reserve_setting['range_end'];
  828. $range_end_arr = ReserveServiceEnum::RANGE_END_ARR_MAP;
  829. $days = $range_end_arr[$range_end] ?? 7;
  830. $start_time = strtotime(date('Y-m-d', time()));
  831. $day_arr = [];
  832. $time = strtotime(date('Y-m-d', time()));
  833. $end_time = $time + $days * 24 * 3600;
  834. for ($i = $time; $i < $end_time; $i += 24 * 60 * 60) {
  835. $day_arr[] = $i * 1000;;
  836. }
  837. return ['day_arr' => $day_arr];
  838. }
  839. public function getStaffUserWorkTime($params)
  840. {
  841. $user_times = ReservationServiceWorkTime::find()->where(['mall_id' => $this->mall_id, 'user_id' => $params['user_id'], 'status' => StatusEnum::ENABLED])
  842. ->orderBy('week_day asc')
  843. ->select('week_day,text')
  844. ->asArray()->all();
  845. foreach ($user_times as &$item) {
  846. $item['text'] = explode('-', $item['text']);
  847. }
  848. return $user_times;
  849. }
  850. public function confirmToStore($params)
  851. {
  852. $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]);
  853. if (empty($order)) {
  854. throw new \Exception('预约服务不存在');
  855. }
  856. $order->server_status = ReservationServiceEnum::ARRIVED_AT_STORE;
  857. $order->at_store_time = time();
  858. $res = $order->save();
  859. if ($res == false) {
  860. throw new \Exception($order->getErrorMessage());
  861. }
  862. $update = [
  863. 'shipping_time' => time(),
  864. 'order_status' => OrderStatusEnum::SHIPMENTS,
  865. ];
  866. StoreOrder::updateAll($update, ['order_no' => $order['order_no']]);
  867. Order::updateAll($update, ['order_no' => $order['order_no']]);
  868. return ['id' => $order['id']];
  869. }
  870. public function cancel($params)
  871. {
  872. $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]);
  873. if (empty($order)) {
  874. throw new \Exception('预约服务不存在');
  875. }
  876. if ($order['create_type'] == ReservationServiceEnum::SYSTEM_CREATION) {
  877. Order::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]);
  878. StoreOrder::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]);
  879. StoreOrderReserve::updateAll(['order_status' => -4], ['main_order_id' => $order['order_id']]);
  880. } else {
  881. if (!empty($order['secondary_card_id'])) {
  882. $this->cancelSecondaryCardReserve($order);
  883. } else {
  884. //退款
  885. //{
  886. // "shipping_status": "0",
  887. // "order_detail_id": "52686",
  888. // "reason": "不想要了",
  889. // "refund_price": 50,
  890. // "remark": "455565656",
  891. // "type": "1",
  892. // "pic_list": "[]"
  893. //}
  894. //申请退款
  895. try {
  896. $order_detail = OrderDetail::findOne(['id' => $order['order_detail_id']]);
  897. $params['user_id'] = $order['user_id'];
  898. $params['mall_id'] = $this->mall_id;
  899. $params['shipping_status'] = 0;
  900. unset($params['id']);
  901. $params['order_detail_id'] = $order['order_detail_id'];
  902. $params['reason'] = '后台取消';
  903. $params['refund_price'] = $order_detail['goods_price'];
  904. $params['remark'] = $params['reason'];
  905. $params['type'] = 1;
  906. $params['pic_list'] = [];
  907. $where = [
  908. ['=', 'order_detail_id', $order['order_detail_id']],
  909. ['=', 'user_id', $order['user_id']],
  910. ['=', 'mall_id', $this->mall_id],
  911. ['>', 'step_status', 0],
  912. ['<>', 'refund_status', RefundStatusEnum::REVOKE]
  913. ];
  914. $order_refund_model = OrderRefund::getOne($where, true);
  915. if ($order_refund_model) {
  916. throw new Exception('该订单商品已经申请过售后');
  917. }
  918. $order_refund_model = OrderRefund::feedback($params);
  919. if (empty($order_refund_model)) {
  920. throw new Exception(OrderRefund::getStaticError());
  921. }
  922. } catch (Exception $e) {
  923. throw new Exception($e->getMessage());
  924. }
  925. //同意
  926. $data = [
  927. 'id' => $order_refund_model['id'],
  928. 'step_status' => 6,
  929. 'address' => '',
  930. 'express' => '',
  931. 'refund_reason' => '后台取消,同意',
  932. 'operator_id' => $this->store_id,
  933. 'is_admin' => 0
  934. ];
  935. $data['admin_handler_refund'] = UserWalletEnum::ADMIN_HANDLER_REFUND;
  936. $logic = new OrderRefundLogic();
  937. $logic->execute($this->mall_id, $data);
  938. Order::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]);
  939. StoreOrder::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]);
  940. StoreOrderReserve::updateAll(['order_status' => -4], ['main_order_id' => $order['order_id']]);
  941. }
  942. }
  943. $order->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_CLOSED;
  944. $order->server_status = ReservationServiceEnum::CANCELED;
  945. $res = $order->save();
  946. if ($res == false) {
  947. throw new \Exception($order->getErrorMessage());
  948. }
  949. return ['id' => $order['id']];
  950. }
  951. /**
  952. * 取消次卡预约
  953. * @return void
  954. */
  955. public function cancelSecondaryCardReserve($order)
  956. {
  957. try {
  958. $reserve_order = OrderReserve::find()->where(['reservation_service_order_id' => $order['id']])->orderBy('id desc')->one();
  959. $reserve_order->order_status = -4;
  960. $reserve_order->save();
  961. $store_reserveOrder = StoreOrderReserve::find()->where(['reservation_service_order_id' => $order['id']])->orderBy('id desc')->one();
  962. $store_reserveOrder->order_status = -4;
  963. $store_reserveOrder->save();
  964. } catch (Exception $e) {
  965. throw new Exception($e->getMessage());
  966. }
  967. }
  968. public function checkAccept($params)
  969. {
  970. $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]);
  971. if (empty($order)) {
  972. throw new \Exception('预约服务不存在');
  973. }
  974. if (empty($order['secondary_card_id'])) {
  975. if ($order->create_type == ReservationServiceEnum::SYSTEM_CREATION) {
  976. Order::updateAll(['order_status' => 3], ['order_no' => $order['order_no']]);
  977. StoreOrder::updateAll(['order_status' => 3], ['order_no' => $order['order_no']]);
  978. $order->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER;
  979. $order->server_status = ReservationServiceEnum::COMPLETED;
  980. $order->save();
  981. }
  982. $data['id'] = $order['order_id'];
  983. $data['mall_id'] = $this->mall_id;
  984. $data['user_id'] = $order['user_id'];
  985. $data['operator_id'] = $params['store']['user_id'] ?? '';
  986. $data['operator_name'] = $params['store']['store_name'] ?? '';
  987. $data['from'] = OrderSourceEnum::SOURCE_RESERVE;
  988. $res = Order::complete($data);
  989. } else {
  990. $data['id'] = $order['order_id'];
  991. $data['mall_id'] = $this->mall_id;
  992. $data['user_id'] = $order['user_id'];
  993. $data['operator_id'] = $params['store']['user_id'] ?? '';
  994. $data['operator_name'] = $params['store']['store_name'] ?? '';
  995. $data['from'] = OrderSourceEnum::SOURCE_RESERVE;
  996. $res = Order::completes($data);
  997. }
  998. return ['id' => $params['id']];
  999. }
  1000. public function getSkuList()
  1001. {
  1002. $goods_list = StoreGoods::lists([
  1003. 'where' => [
  1004. ['store_id' => $this->store_id],
  1005. ['status' => StatusEnum::ENABLED],
  1006. ['check_status' => StatusEnum::ENABLED],
  1007. ['is_on_sale' => StatusEnum::ENABLED],
  1008. ['goods_type' => GoodsTypeEnum::GoodsTypeReserved],
  1009. ],
  1010. 'select' => 'id,goods_name',
  1011. 'index' => 'id'
  1012. ]);
  1013. $goods_ids = array_column($goods_list, 'id');
  1014. $sku_list = StoreGoodsReserveSku::lists([
  1015. 'where' => [
  1016. ['store_id' => $this->store_id],
  1017. ['goods_id' => $goods_ids],
  1018. ],
  1019. 'select' => 'id,goods_id,service_min,name',
  1020. ]);
  1021. foreach ($sku_list as &$sku) {
  1022. $sku['goods_name'] = $goods_list[$sku['goods_id']]['goods_name'] . ':' . $sku['name'];
  1023. }
  1024. return $sku_list;
  1025. }
  1026. public function getUser($params)
  1027. {
  1028. $user = User::findOne(['mall_id' => $this->mall_id, 'mobile' => $params['mobile'], 'status' => [StatusEnum::ENABLED]]);
  1029. $name = '';
  1030. if (!empty($user)) {
  1031. if (!empty($user['nickname'])) {
  1032. $name = $user['nickname'];
  1033. } else {
  1034. $name = $user['mobile'];
  1035. }
  1036. }
  1037. return $name;
  1038. }
  1039. /**
  1040. * 点击确认到店进行核销
  1041. * @param $params
  1042. * @return true
  1043. * @throws Exception
  1044. */
  1045. public function storeVerification($params)
  1046. {
  1047. $reserveOrder = ReservationServiceOrder::find()->where(['id' => $params['id']])->one();
  1048. if (empty($reserveOrder)) {
  1049. throw new \Exception('预约服务不存在');
  1050. }
  1051. // 获取核销码
  1052. $clerkCode = StoreOrderReserve::find()->where(['main_order_id' => $reserveOrder['order_id'], 'store_id' => $reserveOrder['store_id']])->select('reserve_code')->scalar();
  1053. if (empty($clerkCode)) {
  1054. throw new \Exception('核销码不存在');
  1055. }
  1056. // 进行核销
  1057. $res = (new OrderService())->clerk($this->mall_id, $reserveOrder['staff_user_id'], $clerkCode);
  1058. if (is_string($res)) {
  1059. throw new \Exception($res);
  1060. }
  1061. return true;
  1062. }
  1063. }