store_id; // 预约订单 $ret = (new OrderService())->page($this->mall_id, $params); if (!empty($ret['list'])) { $order_nos = array_column($ret['list'], 'order_no'); // 平台的ID // 门店的订单ID $store_order_nos = StoreOrder::lists([ 'where' => [ ['order_no' => $order_nos] ], 'select' => 'order_no, id', 'index' => 'order_no' ]); if (!empty($store_order_nos)) { $store_order_ids = array_unique(array_column($store_order_nos, 'id')); if (!empty($store_order_ids)) { $orders = StoreOrderReserve::lists([ 'where' => [ ['order_id' => $store_order_ids] ], 'index' => 'order_id' ]); foreach ($ret['list'] as &$item) { $item['reserveOrder'] = $orders[$store_order_nos[$item['order_no']]['id']] ?? []; } } } } return $ret; } public function detail(int $id) { // 预约订单详情 return (new OrderService())->getDetailByCodeOrId($this->mall_id, 0, '', $id, $this->store_id); } /** * 完成 * @param int $id * @return ReservationServiceOrder|string */ public function underwriter(int $id) { // 预约订单核销 return (new OrderService())->underwriter($this->mall_id, $id, $this->user_id, $this->store_id); } /** * 完成 * @param int $id * @return ReservationServiceOrder|string */ public function acceptance(int $id) { // 预约订单核销 return (new OrderService())->acceptance($this->mall_id, $id, $this->user_id, $this->store_id); } /** * 执行预约 * @param int $order_id * @param int $tech_id * @param string $select_time * @return string|true */ public function reserve(int $order_id, int $tech_id, string $select_time) { try { $reserveOrder = StoreOrderReserve::findOne(['order_id' => $order_id]); if (empty($reserveOrder)) throw new \Exception('订单未找到'); if ($reserveOrder->reserve_type != StatusEnum::ENABLED) { throw new \Exception('当前订单不可进行预约'); } if ($reserveOrder->reserve_status != 0) { throw new \Exception('当前订单不可进行预约.'); } if ($reserveOrder->order_status != OrderStatusEnum::SHIPMENTS) { throw new \Exception('当前订单不可进行预约!'); } // 数据校验 if (!MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_RESERVATION_SERVICE)) { throw new \Exception('您还未安装当前插件'); } $time = strtotime($select_time); if ($time <= time()) throw new \Exception('选择时间错误'); //检测技师 $orderDetail = StoreOrderDetail::findOne(['order_id' => $reserveOrder->order_id]); $check = TechniciansService::checkCanOrder($this->mall_id, $tech_id, $select_time, $orderDetail->goods_id, $orderDetail->goods_attr_id, $reserveOrder->lat, $reserveOrder->lng); if (!$check) throw new \Exception(TechniciansService::getStaticError()); // 开始处理 $t = Yii::$app->db->beginTransaction(); try { // 处理数据 $reserveOrder->tech_id = $tech_id; $reserveOrder->reserve_date_time = $select_time; $reserveOrder->reserve_time_range_type = 2; if (!$reserveOrder->save()) throw new \Exception($reserveOrder->getErrorMessage()); $order = StoreOrder::findOne(['id' => $reserveOrder->order_id]); $start_at = strtotime($select_time); $sku = StoreGoodsReserveSku::findOne(['id' => $orderDetail->goods_attr_id]); (new OrderService())->save([ 'mall_id' => $this->mall_id, 'user_id' => $reserveOrder->user_id, 'tech_id' => $tech_id, 'order_id' => $order_id, 'order_no' => $order->order_no, 'service_start_at' => $start_at, 'service_end_at' => $start_at + ($sku->service_min * 60), 'remark' => '', 'commission' => 0, 'order_detail_id' => $orderDetail->id, 'goods_id' => $orderDetail->goods_id, 'lng' => $reserveOrder->lng, 'lat' => $reserveOrder->lat, 'goods_price' => $orderDetail->goods_price, 'store_id' => $this->store_id ]); $t->commit(); } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } } catch (\Exception $e) { return $e->getMessage(); } return true; } public function getEditData($params) { $goods_list = StoreGoods::lists([ 'where' => [ ['store_id' => $this->store_id], ['status' => StatusEnum::ENABLED], ['check_status' => StatusEnum::ENABLED], ['is_on_sale' => StatusEnum::ENABLED], ['goods_type' => GoodsTypeEnum::GoodsTypeReserved], ], 'select' => 'id,goods_name', 'with' => ['reserve' => function ($q) { $q->select('id,goods_id,service_min'); }], ]); $store_reserve_setting = StoreReserveSetting::getOne([['store_id' => $this->store_id]]); $setting = []; if ($store_reserve_setting) { $setting = json_decode($store_reserve_setting['setting'], true); } $ret['goods_list'] = $goods_list; $ret['range_start'] = $setting['range_start'] ?? 1; $ret['range_end'] = $setting['range_end'] ?? 1; $order = []; $goods_name = ''; $service_type_arr = []; if (!empty($params['id'])) { $order = ReservationServiceOrder::getOne([ ['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id] ], true ); $user = User::findOne(['id' => $order['user_id']]); $order['mobile'] = $user['mobile']; $order['nickname'] = !empty($user['nickname']) ? $user['nickname'] : $user['mobile']; $order['at_date'] = date('Y-m-d', $order['service_start_at']); $order['at_time'] = date('H:i', $order['service_start_at']); $params['goods_id'] = $order['goods_id']; $params['sku_id'] = $order['goods_reserve_sku_id']; $order['sku_id'] = $order['goods_reserve_sku_id']; if (empty($order['staff_user_id'])) { $order['staff_user_id'] = ''; } if (empty($order['secondary_card_id'])) { $sku = StoreGoodsReserveSku::findOne(['id' => $order['sku_id']]); if (empty($sku['name'])) { $store_goods = StoreGoods::findOne(['id' => $order['goods_id']]); $goods_name = $store_goods['goods_name']; } else { $goods_name = $sku['name']; } $ret['staff_user_list'] = $this->getStaffUserList($params); $order['master'] = [ ['sku_id' => $order['sku_id'], 'staff_user_id' => $order['staff_user_id'], 'service_min' => $sku['service_min'] ?? 0] ]; } else { $params['secondary_card_id'] = $order['secondary_card_id']; $secondary_card = SecondaryCard::getOne([['id' => $order['secondary_card_id']]]); $goods_name = $secondary_card['name'] ?? ''; $ret['staff_user_list'] = $this->getStaffUserListBySecondaryCard($params); $order['master'] = [ ['sku_id' => $order['secondary_card_id'], 'staff_user_id' => $order['staff_user_id'], 'service_min' => $secondary_card['appointment_interval_duration'] ?? 0] ]; switch ($secondary_card['reservation_service_type']) { case 1: $service_type_arr[] = ['value' => 1, 'label' => '上门服务']; break; case 2: $service_type_arr[] = ['value' => 2, 'label' => '到店服务']; break; case 3: $service_type_arr[] = ['value' => 1, 'label' => '上门服务']; $service_type_arr[] = ['value' => 2, 'label' => '到店服务']; break; } } } $ret['service_type_arr'] = $service_type_arr; $ret['reserve_order'] = $order; $ret['goods_name'] = $goods_name; $store = $params['store']; $business_time_start = strtotime(date('Y-m-d') . ' ' . $store['business_time_start'] . ':00'); $business_time_end = strtotime(date('Y-m-d') . ' ' . $store['business_time_end'] . ':00'); $H = date('H', $business_time_start); $start_time = $H * 60; $H = date('H', $business_time_end); $minute = date('i', $business_time_end); $end_time = $H * 60 + $minute; $ret['start_time'] = $start_time; $ret['end_time'] = $end_time; return $ret; } /** * 后台添加预约 * @param $params * @return array * @throws \yii\base\Exception * @throws \yii\db\Exception */ public function setEditData($params) { $t = Yii::$app->db->beginTransaction(); try { $user = User::findOne(['mobile' => $params['mobile'], 'mall_id' => $this->mall_id]); $this->store = $params['store']; if (!empty($user)) { if ($user['status'] != StatusEnum::ENABLED) { throw new \Exception('用户状态异常'); } else { $params['user_id'] = $user['id']; } } else { //注册用户 $user = $this->setUser($params); $params['user_id'] = $user['id']; } $update_order = []; if ($params['service_type'] == ReserveServiceEnum::DOOR_TO_DOOR) {//上门 if (!empty($params['secondary_card_id'])) { // 因为只有次卡是没有选择服务地址的所以只修改次卡 $user_address = UserAddress::find()->where(['user_id' => $params['user_id'], 'status' => StatusEnum::ENABLED]) ->orderBy('is_default DESC, id DESC')->one(); // 获取会员默认地址:当前会员没有默认地址时,默认取第一个地址 if (empty($user_address)) { throw new \Exception('该会员没有设置默认地址'); } $update_order['province'] = $user_address['province_id']; $update_order['city'] = $user_address['city_id']; $update_order['area'] = $user_address['district_id']; $update_order['address'] = $user_address['detail']; $update_order['receiver_name'] = $user_address['name']; $update_order['mobile'] = $user_address['mobile']; } } else { $update_order['province'] = $this->store['province_id']; $update_order['city'] = $this->store['city_id']; $update_order['area'] = $this->store['district_id']; $update_order['address'] = $this->store['address']; $update_order['receiver_name'] = $this->store['store_name']; $update_order['mobile'] = $this->store['shop_mobile']; } $add_user_data = [ 'mall_id' => $this->mall_id, 'user_id' => $params['user_id'], 'store_id' => $this->store_id, ]; $res = StoreUser:: setData($add_user_data); $service_start_at = strtotime(date('Y-m-d', strtotime($params['at_date'])) . ' ' . $params['at_time'] . ':00'); $obj = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id])); $store_reserve_setting = $obj->detail(); $store_goods = $store_goods_reserve_sku = []; if (!empty($params['id'])) { $model = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]); if (empty($model)) { throw new \Exception('数据不存在'); } $params['secondary_card_id'] = $model['secondary_card_id']; } $params['staff_user_id'] = !empty($params['master'][0]['staff_user_id']) ? $params['master'][0]['staff_user_id'] : 0; if (empty($params['secondary_card_id'])) { $params['sku_id'] = $params['master'][0]['sku_id'];; $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]); if (empty($store_goods_reserve_sku)) { throw new \Exception('预约商品规格不存在'); } $store_goods = StoreGoods::findOne(['id' => $store_goods_reserve_sku['goods_id']]); $service_min = $obj->getServiceMin($store_reserve_setting['appointment_interval'], $store_goods_reserve_sku['service_min'] ?? 0); $goods_id = $store_goods_reserve_sku['goods_id']; } else { $secondary_card = SecondaryCard::getOne([['id' => $params['secondary_card_id']]]); $service_min = $obj->getServiceMin($store_reserve_setting['appointment_interval'], $secondary_card['appointment_interval_duration'] ?? 0); $goods_id = 0; $params['sku_id'] = 0; } $service_end_at = $service_start_at + $service_min * 60; $this->checkEdit($params['staff_user_id'], $service_start_at, $service_end_at); $create_type = null; if (!empty($params['create_type'])) { $update['create_type'] = $params['create_type']; $create_type = $params['create_type']; } if (!empty($params['id'])) { $reservation_service_order_id = $params['id']; if ($params['staff_user_id'] != $model['staff_user_id']) { $staff = ReservationServiceUser::findOne(['user_id' => $params['staff_user_id'], 'status' => StatusEnum::ENABLED]); } } else { $reservation_service_user = ReservationServiceUser::findOne(['user_id' => $params['staff_user_id'], 'status' => StatusEnum::ENABLED]); $this->user_id = $params['user_id']; $main_order_detail_id = 0; $order = $this->createOrder($store_goods, $store_goods_reserve_sku, $service_start_at, $create_type, $reservation_service_user['id'] ?? 0, $main_order_detail_id); $model = new ReservationServiceOrder(); $model->loadDefaultValues(); $model->mall_id = $this->mall_id; $model->store_id = $this->store_id; $reservation_service_order_id = null; $model->order_no = $order['order_no']; $model->order_id = $order['id']; $model->order_detail_id = $main_order_detail_id; $model->service_status = ReservationServiceEnum::ALREADY_BOOKED; $model->server_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING; } $model->user_id = $params['user_id']; $model->staff_user_id = $params['staff_user_id']; $model->goods_id = $goods_id; $model->service_start_at = $service_start_at; $model->service_end_at = $service_end_at; $model->reservation_model = $params['reservation_model']; $model->goods_reserve_sku_id = $params['sku_id']; if (!empty($params['create_type'])) { $model->create_type = $params['create_type']; } if (!empty($params['service_type'])) { $model->service_type = $params['service_type']; } $res = $model->save(); $reserve_date_time = date('Y-m-d H:i', $model->service_start_at) . ',' . date('Y-m-d H:i', $model->service_end_at); $update['reserve_date_time'] = $reserve_date_time; $update['service_start_at'] = $model->service_start_at; $update['service_end_at'] = $model->service_end_at; $update['service_type'] = $model->service_type; $update['reservation_service_order_id'] = $model['id']; if (isset($staff)) { $update['tech_id'] = $staff['id']; } StoreOrderReserve::updateAll($update, ['main_order_id' => $model['order_id']]); unset($update['create_type']); OrderReserve::updateAll($update, ['order_id' => $model['order_id']]); if (!empty($update_order)) { Order::updateAll($update_order, ['id' => $model['order_id']]); StoreOrder::updateAll($update_order, ['order_no' => $model['order_no']]); } if ($res == false) { throw new \Exception($model->getErrorMessage()); } $t->commit(); return ['id' => $model['id']]; } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } } public function createOrder($goods, $sku, $select_time, $create_type, $tech_id, &$main_order_detail_id) { $store_order_detail = $order_detail = null; $store_order = $this->createStoreOrder($goods, $sku, $store_order_detail); $main_order = $this->createMallOrder($store_order['order_no'], $store_order['clerk_code'], $goods, $sku, $order_detail); $store_order_detail->main_order_detail_id = $order_detail['id']; $main_order_detail_id = $order_detail['id']; $store_order_detail->save(); $form = [ 'data' => [ 'time_id' => 0, 'service_type' => 2, 'latitude' => 0, 'longitude' => 0, 'time_spec_id' => 0, 'tech_id' => $tech_id, 'create_type' => $create_type, 'select_time' => date('Y-m-d H:i', $select_time), ] ]; $res = StoreOrderReserve::create($store_order, $form, $main_order['id'] ?? 0); if ($res == false) throw new \Exception(StoreOrderReserve::getStaticError()); $res->reserve_code = $store_order['clerk_code']; $res->save(); return $main_order; } public function createStoreOrder($goods, $store_goods_reserve_sku, &$store_order_detail) { $order = new StoreOrder(); $order->loadDefaultValues(); $order->mall_id = $this->mall_id; $order->user_id = $this->user_id; $order->store_id = $this->store_id; $order->order_no = \common\helpers\StringHelper::generateOrderNo('st'); $order->out_trade_no = ''; $order->province = $this->store['province_id']; $order->city = $this->store['city_id']; $order->area = $this->store['district_id']; $order->address = $this->store['address']; $order->region_name = ""; $order->receiver_name = $this->store['store_name']; $order->mobile = $this->store['shop_mobile']; $order->remark = ''; $order->shipping_type = null; $order->shipping_money = 0; $order->pay_money = 0; $order->goods_price = 0; $order->original_goods_price = 0; $order->order_status = OrderStatusEnum::SHIPMENTS; $order->marketing_id = 0; $order->marketing_type = 'Store'; $order->pay_status = OrderStatusEnum::PAY; $order->extra_info = []; $order->payment_type = 0; $order->pay_time = time(); $order->shipping_time = time(); $order->order_source = 'Reserve'; $order->create_type = 2; $order->clerk_code = OrderReserve::getClerkCode($this->mall_id, ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE); $res = $order->save(); if ($res == false) throw new \Exception($order->getErrorMessage()); $store_order_detail = $this->createStoreOrderDetail($order, $goods, $store_goods_reserve_sku); return $order; } protected function createStoreOrderDetail($order, $goods, $store_goods_reserve_sku) { // 订单详情 $order_detail = new StoreOrderDetail(); $order_detail->loadDefaultValues(); $order_detail->user_id = $this->user_id; $order_detail->mall_id = $this->mall_id; $order_detail->store_id = $this->store_id; $order_detail->order_id = $order->id; $order_detail->goods_id = $goods['id']; $order_detail->goods_attr_id = $store_goods_reserve_sku['id']; $order_detail->goods_name = $goods->goods_name; $order_detail->goods_attr_name = $store_goods_reserve_sku['name']; $order_detail->sign_id = $store_goods_reserve_sku['sign_id']; $order_detail->price = $store_goods_reserve_sku->price; $order_detail->cost_price = $store_goods_reserve_sku->cost_price; $order_detail->original_goods_price = $store_goods_reserve_sku->original_price; $order_detail->pic_url = $store_goods_reserve_sku->pic_url ? $store_goods_reserve_sku->pic_url : $goods->cover_pic; $order_detail->goods_price = 0; $order_detail->num = 1; $order_detail->order_type = 1; $order_detail->marketing_id = $order->id; $order_detail->marketing_type = 'Store'; $order_detail->order_status = OrderStatusEnum::PAY; $order_detail->remark = ''; $res = $order_detail->save(); if ($res == false) throw new \Exception('生成订单详情失败'); return $order_detail; } public function createMallOrder($order_no, $clerk_code, $goods, $store_goods_reserve_sku, &$order_detail) { $order = new Order(); $order->loadDefaultValues(); $order->mall_id = $this->mall_id; $order->user_id = $this->user_id; $order->store_id = $this->store_id; $order->order_no = $order_no; $order->out_trade_no = ''; $order->province = $this->store['province_id']; $order->city = $this->store['city_id']; $order->area = $this->store['district_id']; $order->address = $this->store['address']; $order->region_name = ""; $order->receiver_name = $this->store['store_name']; $order->mobile = $this->store['shop_mobile']; $order->clerk_code = $clerk_code; $order->remark = ''; $order->shipping_type = null; $order->shipping_money = 0; $order->pay_money = 0; $order->goods_price = 0; $order->original_goods_price = 0; $order->order_status = OrderStatusEnum::SHIPMENTS; $order->marketing_id = 0; $order->marketing_type = 'Store'; $order->pay_status = OrderStatusEnum::PAY; $order->extra_info = []; $order->payment_type = 0; $order->pay_time = time(); $order->shipping_time = time(); $order->clerk_code = $clerk_code; $order->order_source = 'ReserveRe'; $res = $order->save(); if ($res == false) throw new \Exception($order->getErrorMessage()); $order_detail = $this->createMallOrderDetail($order, $goods, $store_goods_reserve_sku); return $order; } protected function createMallOrderDetail($order, $goods, $store_goods_reserve_sku) { // 订单详情 $order_detail = new OrderDetail(); $order_detail->loadDefaultValues(); $order_detail->user_id = $this->user_id; $order_detail->mall_id = $this->mall_id; $order_detail->store_id = $this->store_id; $order_detail->order_id = $order->id; $order_detail->goods_id = $goods['id']; $order_detail->goods_attr_id = $store_goods_reserve_sku['id']; $order_detail->goods_name = $goods->goods_name; $order_detail->goods_attr_name = $store_goods_reserve_sku['name']; $order_detail->sign_id = $store_goods_reserve_sku['sign_id']; $order_detail->price = $store_goods_reserve_sku->price; $order_detail->cost_price = $store_goods_reserve_sku->cost_price; $order_detail->original_goods_price = $store_goods_reserve_sku->original_price; $order_detail->pic_url = $store_goods_reserve_sku->pic_url ? $store_goods_reserve_sku->pic_url : $goods->cover_pic; $order_detail->goods_price = 0; $order_detail->num = 1; $order_detail->order_type = 1; $order_detail->marketing_id = $order->id; $order_detail->marketing_type = 'Store'; $order_detail->order_status = OrderStatusEnum::PAY; $order_detail->remark = ''; $res = $order_detail->save(); if ($res == false) throw new \Exception('生成订单详情失败'); return $order_detail; } /** * 注册用户 * @param $params * @return bool|User * @throws \yii\base\Exception * @throws \yii\db\Exception */ protected function setUser($params) { $password = substr($params['mobile'], -6, 6); $params['mall_id'] = $this->mall_id; if (empty($params['username'])) { $params['username'] = $params['mobile']; } $store = Store::findOne(['id' => $this->store_id]); $params['parent_id'] = $store['user_id']; $params['level'] = 0; $params['source'] = User::SOURCE_ADD_PLATFORM; $params['platform'] = User::TYPE_MANUAL; $params['password'] = Yii::$app->getSecurity()->generatePasswordHash($password); return User::setData($params); } /** * 检查该时间段是否被预约或者被占用 * @param $staff_user_id * @param $service_start_at * @param $service_end_at * @param $reservation_service_order_id * @return void * @throws \Exception */ protected function checkEdit($staff_user_id, $service_start_at, $service_end_at, $reservation_service_order_id = null, $create_type = 2) { // if ($create_type != ReservationServiceEnum::SYSTEM_CREATION) { // $where = [ // ['staff_user_id' => $staff_user_id], // ['staff_user_id' => $staff_user_id], // ['!=', 'server_status', ReservationServiceEnum::CANCELED], // [ // 'or', // [ // 'and', // ['>=', 'service_start_at', $service_start_at], // ['<=', 'service_start_at', $service_end_at], // ], // [ // 'and', // ['>=', 'service_end_at', $service_start_at], // ['<=', 'service_end_at', $service_end_at], // ], // ] // ]; // if (isset($reservation_service_order_id)) { // $where[] = ['!=', 'id', $reservation_service_order_id]; // } // $res = ReservationServiceOrder::lists([ // 'where' => $where // ]); // if ($res) { // throw new \Exception('该时间段已被预约'); // } // } $list = ReservationServiceOccupy::lists([ 'where' => [ ['staff_user_id' => $staff_user_id], ['status' => StatusEnum::ENABLED], ] ]); foreach ($list as $item) { if ($service_start_at >= $item['start_at'] && $service_start_at < $item['end_at']) { throw new \Exception('该时间段已被占用'); } if ($service_end_at >= $item['start_at'] && $service_end_at < $item['end_at']) { throw new \Exception('该时间段已被占用'); } } } public function getStaffUserList($params) { if (empty($params['goods_id'])) { $sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]); $goods_id = $sku['goods_id']; } else { $goods_id = $params['goods_id']; } $reservation_ervice_store_goods_list = ReservationServiceStoreGoods::lists(['where' => [ ['goods_id' => $goods_id], ['status' => StatusEnum::ENABLED], ['store_id' => $this->store_id] ]]); $user_ids = array_column($reservation_ervice_store_goods_list, 'user_id'); $list = ReservationServiceUser::lists([ 'where' => [ ['store_id' => $this->store_id], ['user_id' => $user_ids], ['status' => StatusEnum::ENABLED] ], 'select' => 'user_id,name' ]); return $list; } public function getStaffUserListBySecondaryCard($params) { $reservation_service_store_secondary_card_list = ReservationServiceStoreSecondaryCard::lists(['where' => [ ['secondary_card_id' => $params['secondary_card_id']], ['status' => StatusEnum::ENABLED], ['store_id' => $this->store_id] ]]); $user_ids = array_column($reservation_service_store_secondary_card_list, 'user_id'); $list = ReservationServiceUser::lists([ 'where' => [ ['store_id' => $this->store_id], ['user_id' => $user_ids], ['status' => StatusEnum::ENABLED] ], 'select' => 'user_id,name' ]); return $list; } public function getReserveTime($params) { $step = '00:01'; $store = Store::findOne(['id' => $this->store_id]); $picker_options_time = [ 'start' => $store['business_time_start'], 'end' => $store['business_time_end'], 'step' => $step, ]; return ['picker_options_time' => $picker_options_time]; } /** * 后台添加预约/预约看板添加预约,获取可以预约的时间段 * @param $params * @return array */ public function getReserveTimes($params) { $date_time = strtotime($params['date']); $staff_user_id = $params['staff_user_id'] ?? 0; if (!empty($params['staff_user_id'])) { $scheduling = StoreReserveTechnicianScheduling::getOne([ ['user_id' => $staff_user_id], ['date_time' => $date_time], ['status' => StatusEnum::ENABLED] ], true, ['schedulingTime']); if (empty($scheduling)) { return []; } } $buff = []; $sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]); $date_day = date('Y-m-d', strtotime($params['date'])); $time = time(); $service_min = $sku['service_min']; $obj = new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]); $store_reserve_setting = $obj->detail(); if (strtotime(date('Y-m-d')) == $date_time) { $range_start_time = $obj->getRangeStartTime($store_reserve_setting['range_start']); $time += $range_start_time; } $reservation_service_order_list = ReservationServiceOrder::lists([ 'where' => [ ['mall_id' => $this->mall_id], ['store_id' => $this->store_id], ['staff_user_id' => $staff_user_id], ['>=', 'service_start_at', strtotime($date_day . ' 00:00:00')], ['<=', 'service_end_at', strtotime($date_day . ' 23:59:59')], ['!=', 'server_status', ReservationServiceEnum::CANCELED] ] ]);//已预约 $reservation_service_order_arr = []; foreach ($reservation_service_order_list as $value) { $reservation_service_order_arr[$value['service_start_at']] = $value; } $occupy_list = ReservationServiceOccupy::lists([ 'where' => [ ['mall_id' => $this->mall_id], ['store_id' => $this->store_id], ['staff_user_id' => $staff_user_id], ['status' => StatusEnum::ENABLED] ] ] );//已占用时间 if (!empty($staff_user_id)) { if (!empty($scheduling['is_all_day'])) { //全天 $store = Store::findOne(['id' => $this->store_id]); $time1 = $date_day . " " . $store['business_time_start'] . ":00"; $time2 = $date_day . " " . $store['business_time_end'] . ":59"; $start = strtotime($time1); $end = strtotime($time2); $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff); } else { if (!empty($scheduling['schedulingTime'])) { foreach ($scheduling['schedulingTime'] as $val) { $start = $val['start_time']; $end = $val['end_time']; $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff); } } } } else { $store = Store::findOne(['id' => $this->store_id]); $time1 = $date_day . " " . $store['business_time_start'] . ":00"; $time2 = $date_day . " " . $store['business_time_end'] . ":59"; $start = strtotime($time1); $end = strtotime($time2); $this->getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, $buff); } return $buff; } /** * @param $start //开始时间 * @param $end //结束时间 * @param $service_min //服务时长 * @param $reservation_service_order_arr //已预约数组 * @param $occupy_list //已占用数组 * @param $time //当前时间 * @param $buff //返回数组 * @return void */ protected function getBuff($start, $end, $service_min, $reservation_service_order_arr, $occupy_list, $time, &$buff) { for ($i = $start; $i <= $end; $i = $i + 60 * $service_min) { if ($i < $time) { continue; } if (isset($reservation_service_order_arr[$i])) { continue; } $is_true = false; foreach ($occupy_list as $occupy) { if ($i >= $occupy['start_at'] && $i <= $occupy['end_at']) { $is_true = true; break; } } if ($is_true) { continue; } $buff[] = ['time' => date("H:i", $i)]; } } public function getReserveDay($params) { $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail(); $range_end = $store_reserve_setting['range_end']; $range_end_arr = ReserveServiceEnum::RANGE_END_ARR_MAP; $days = $range_end_arr[$range_end] ?? 7; $start_time = strtotime(date('Y-m-d', time())); $day_arr = []; $time = strtotime(date('Y-m-d', time())); $end_time = $time + $days * 24 * 3600; for ($i = $time; $i < $end_time; $i += 24 * 60 * 60) { $day_arr[] = $i * 1000;; } return ['day_arr' => $day_arr]; } public function getStaffUserWorkTime($params) { $user_times = ReservationServiceWorkTime::find()->where(['mall_id' => $this->mall_id, 'user_id' => $params['user_id'], 'status' => StatusEnum::ENABLED]) ->orderBy('week_day asc') ->select('week_day,text') ->asArray()->all(); foreach ($user_times as &$item) { $item['text'] = explode('-', $item['text']); } return $user_times; } public function confirmToStore($params) { $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]); if (empty($order)) { throw new \Exception('预约服务不存在'); } $order->server_status = ReservationServiceEnum::ARRIVED_AT_STORE; $order->at_store_time = time(); $res = $order->save(); if ($res == false) { throw new \Exception($order->getErrorMessage()); } $update = [ 'shipping_time' => time(), 'order_status' => OrderStatusEnum::SHIPMENTS, ]; StoreOrder::updateAll($update, ['order_no' => $order['order_no']]); Order::updateAll($update, ['order_no' => $order['order_no']]); return ['id' => $order['id']]; } public function cancel($params) { $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]); if (empty($order)) { throw new \Exception('预约服务不存在'); } if ($order['create_type'] == ReservationServiceEnum::SYSTEM_CREATION) { Order::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]); StoreOrder::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]); StoreOrderReserve::updateAll(['order_status' => -4], ['main_order_id' => $order['order_id']]); } else { if (!empty($order['secondary_card_id'])) { $this->cancelSecondaryCardReserve($order); } else { //退款 //{ // "shipping_status": "0", // "order_detail_id": "52686", // "reason": "不想要了", // "refund_price": 50, // "remark": "455565656", // "type": "1", // "pic_list": "[]" //} //申请退款 try { $order_detail = OrderDetail::findOne(['id' => $order['order_detail_id']]); $params['user_id'] = $order['user_id']; $params['mall_id'] = $this->mall_id; $params['shipping_status'] = 0; unset($params['id']); $params['order_detail_id'] = $order['order_detail_id']; $params['reason'] = '后台取消'; $params['refund_price'] = $order_detail['goods_price']; $params['remark'] = $params['reason']; $params['type'] = 1; $params['pic_list'] = []; $where = [ ['=', 'order_detail_id', $order['order_detail_id']], ['=', 'user_id', $order['user_id']], ['=', 'mall_id', $this->mall_id], ['>', 'step_status', 0], ['<>', 'refund_status', RefundStatusEnum::REVOKE] ]; $order_refund_model = OrderRefund::getOne($where, true); if ($order_refund_model) { throw new Exception('该订单商品已经申请过售后'); } $order_refund_model = OrderRefund::feedback($params); if (empty($order_refund_model)) { throw new Exception(OrderRefund::getStaticError()); } } catch (Exception $e) { throw new Exception($e->getMessage()); } //同意 $data = [ 'id' => $order_refund_model['id'], 'step_status' => 6, 'address' => '', 'express' => '', 'refund_reason' => '后台取消,同意', 'operator_id' => $this->store_id, 'is_admin' => 0 ]; $data['admin_handler_refund'] = UserWalletEnum::ADMIN_HANDLER_REFUND; $logic = new OrderRefundLogic(); $logic->execute($this->mall_id, $data); Order::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]); StoreOrder::updateAll(['order_status' => -4], ['order_no' => $order['order_no']]); StoreOrderReserve::updateAll(['order_status' => -4], ['main_order_id' => $order['order_id']]); } } $order->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_CLOSED; $order->server_status = ReservationServiceEnum::CANCELED; $res = $order->save(); if ($res == false) { throw new \Exception($order->getErrorMessage()); } return ['id' => $order['id']]; } /** * 取消次卡预约 * @return void */ public function cancelSecondaryCardReserve($order) { try { $reserve_order = OrderReserve::find()->where(['reservation_service_order_id' => $order['id']])->orderBy('id desc')->one(); $reserve_order->order_status = -4; $reserve_order->save(); $store_reserveOrder = StoreOrderReserve::find()->where(['reservation_service_order_id' => $order['id']])->orderBy('id desc')->one(); $store_reserveOrder->order_status = -4; $store_reserveOrder->save(); } catch (Exception $e) { throw new Exception($e->getMessage()); } } public function checkAccept($params) { $order = ReservationServiceOrder::findOne(['id' => $params['id'], 'store_id' => $this->store_id, 'mall_id' => $this->mall_id]); if (empty($order)) { throw new \Exception('预约服务不存在'); } if (empty($order['secondary_card_id'])) { if ($order->create_type == ReservationServiceEnum::SYSTEM_CREATION) { Order::updateAll(['order_status' => 3], ['order_no' => $order['order_no']]); StoreOrder::updateAll(['order_status' => 3], ['order_no' => $order['order_no']]); $order->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER; $order->server_status = ReservationServiceEnum::COMPLETED; $order->save(); } $data['id'] = $order['order_id']; $data['mall_id'] = $this->mall_id; $data['user_id'] = $order['user_id']; $data['operator_id'] = $params['store']['user_id'] ?? ''; $data['operator_name'] = $params['store']['store_name'] ?? ''; $data['from'] = OrderSourceEnum::SOURCE_RESERVE; $res = Order::complete($data); } else { $data['id'] = $order['order_id']; $data['mall_id'] = $this->mall_id; $data['user_id'] = $order['user_id']; $data['operator_id'] = $params['store']['user_id'] ?? ''; $data['operator_name'] = $params['store']['store_name'] ?? ''; $data['from'] = OrderSourceEnum::SOURCE_RESERVE; $res = Order::completes($data); } return ['id' => $params['id']]; } public function getSkuList() { $goods_list = StoreGoods::lists([ 'where' => [ ['store_id' => $this->store_id], ['status' => StatusEnum::ENABLED], ['check_status' => StatusEnum::ENABLED], ['is_on_sale' => StatusEnum::ENABLED], ['goods_type' => GoodsTypeEnum::GoodsTypeReserved], ], 'select' => 'id,goods_name', 'index' => 'id' ]); $goods_ids = array_column($goods_list, 'id'); $sku_list = StoreGoodsReserveSku::lists([ 'where' => [ ['store_id' => $this->store_id], ['goods_id' => $goods_ids], ], 'select' => 'id,goods_id,service_min,name', ]); foreach ($sku_list as &$sku) { $sku['goods_name'] = $goods_list[$sku['goods_id']]['goods_name'] . ':' . $sku['name']; } return $sku_list; } public function getUser($params) { $user = User::findOne(['mall_id' => $this->mall_id, 'mobile' => $params['mobile'], 'status' => [StatusEnum::ENABLED]]); $name = ''; if (!empty($user)) { if (!empty($user['nickname'])) { $name = $user['nickname']; } else { $name = $user['mobile']; } } return $name; } /** * 点击确认到店进行核销 * @param $params * @return true * @throws Exception */ public function storeVerification($params) { $reserveOrder = ReservationServiceOrder::find()->where(['id' => $params['id']])->one(); if (empty($reserveOrder)) { throw new \Exception('预约服务不存在'); } // 获取核销码 $clerkCode = StoreOrderReserve::find()->where(['main_order_id' => $reserveOrder['order_id'], 'store_id' => $reserveOrder['store_id']])->select('reserve_code')->scalar(); if (empty($clerkCode)) { throw new \Exception('核销码不存在'); } // 进行核销 $res = (new OrderService())->clerk($this->mall_id, $reserveOrder['staff_user_id'], $clerkCode); if (is_string($res)) { throw new \Exception($res); } return true; } }