| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924 |
- <?php
- namespace addons\Store\common\services;
- use addons\ReservationService\common\enums\ReservationServiceEnum;
- use addons\ReservationService\common\models\ReservationServiceOccupy;
- use addons\ReservationService\common\models\ReservationServiceOrder;
- use addons\ReservationService\common\models\ReservationServiceStoreGoods;
- use addons\ReservationService\common\models\ReservationServiceUser;
- use addons\Store\common\enums\ReserveServiceEnum;
- use addons\Store\common\models\Store;
- use addons\Store\common\models\StoreGoodsReserveSku;
- use addons\Store\common\models\StoreOrderReserve;
- use addons\Store\common\models\StoreReserveSetting;
- use addons\Store\common\models\StoreReserveTechnicianScheduling;
- use addons\Store\common\models\StoreReserveTechnicianSchedulingTime;
- use common\enums\StatusEnum;
- use common\helpers\ArrayHelper;
- use common\models\goods\GoodsReserveTime;
- use common\models\order\OrderReserveComments;
- class StoreReserveSettingService extends BaseService
- {
- public function edit($params)
- {
- $params['store_id'] = $this->store_id;
- $params['mall_id'] = $this->mall_id;
- $model = StoreReserveSetting::setData($params);
- return ['id' => $model['id']];
- }
- public function detail()
- {
- $model = StoreReserveSetting::findOne(['store_id' => $this->store_id, 'status' => StatusEnum::ENABLED]);
- $setting = [];
- if ($model) {
- $setting = json_decode($model['setting'], true);
- }
- return $setting;
- }
- public function list($store_ids)
- {
- $list = StoreReserveSetting::lists(['where' => [
- ['store_id' => $store_ids, 'status' => StatusEnum::ENABLED]
- ]]);
- $setting = [];
- foreach ($list as $item) {
- $temp = json_decode($item['setting'], true);
- if (!empty($temp)) {
- $setting[$item['store_id']] = $temp;
- }
- }
- return $setting;
- }
- /**
- * 门店可预约时间列表
- * @param $params
- * @return array
- * @throws \Exception
- */
- public function storeReservationTimeList($params)
- {
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail();
- $range_start = $store_reserve_setting['range_start'];
- $range_end = $store_reserve_setting['range_end'];
- $store = Store::findOne(['id' => $this->store_id]);
- $business_time_start = $store['business_time_start'];
- $business_time_end = $store['business_time_end'];
- $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
- $service_min = $this->getServiceMin($store_reserve_setting['appointment_interval'], $store_goods_reserve_sku['service_min'] ?? 0);
- if (empty($service_min)) {
- throw new \Exception('该商品没有设置服务时长');
- }
- $range_end_arr = ReserveServiceEnum::RANGE_END_ARR_MAP;
- $days = $range_end_arr[$range_end] ?? 7;
- $range_start_time = $this->getRangeStartTime($range_start);
- $time1 = date("Y-m-d {$business_time_start}:00");
- $time2 = date("Y-m-d {$business_time_end}:59");
- $buff = [];
- $start = strtotime($time1);
- $end = strtotime($time2);
- for ($i = $start; $i <= $end; $i = $i + 60 * $service_min) {
- $buff[] = ['time' => date("H:i", $i), 'is_reserve' => 1];
- }
- //切割时间
- $today = false;
- $today_day = date('Y-m-d', time());
- $today_time = strtotime($today_day . ' 00:00:00');
- if (!empty($params['start'])) {
- $time = strtotime($params['start'] . ' 00:00:00');
- if ($today_time == $time) {
- $today = true;
- }
- } else {
- $time = $today_time;
- $today = true;
- }
- $date_list = [];
- $end_time = $time + $days * 24 * 3600;
- for ($i = $time; $i < $end_time; $i += 24 * 60 * 60) {
- $is_reserve = 1;
- $time_list = $buff;
- $date = date('Y-m-d', $i);
- if ($today) {//今天
- foreach ($time_list as $key => $val) {
- $te_time = strtotime(date('Y-m-d ' . $val['time']));
- if ($date == $today_day && $te_time < (time() + $range_start_time)) {
- unset($time_list[$key]);
- }
- }
- $time_list = array_values($time_list);
- }
- $arr = ['date' => $date, 'week_day' => GoodsReserveTime::getWeekDay($date), 'time_list' => $time_list, 'is_reserve' => $is_reserve];
- $date_list[] = $arr;
- }
- return ['date_list' => $date_list, 'service_min' => $service_min];
- }
- /**
- * h5端-预约时间列表-到店分配/技师不选项
- * @param $params
- * @return array
- * @throws \Exception
- */
- public function toStoreReservationTimeList($params)
- {
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail();
- $range_start = $store_reserve_setting['range_start'];
- $range_end = $store_reserve_setting['range_end'];
- $store = Store::findOne(['id' => $this->store_id]);
- $business_time_start = $store['business_time_start'];
- $business_time_end = $store['business_time_end'];
- $store_goods_reserve_sku = StoreGoodsReserveSku::getOne([
- ['id' => $params['sku_id']]
- ], true, ['reserve']);
- if (empty($store_goods_reserve_sku)) {
- throw new \Exception('商品不存在');
- }
- $service_min = $this->getServiceMin($store_reserve_setting['appointment_interval'] ?? 1, $store_goods_reserve_sku['service_min'] ?? 0);
- if (empty($service_min)) {
- throw new \Exception('该商品没有设置服务时长');
- }
- $date = $params['date'];
- $appointments_number = $store_goods_reserve_sku['reserve']['appointments_number'] ?? 0;
- if (!empty($appointments_number)) {
- $reservation_service_order_list = StoreOrderReserve::lists([
- 'where' => [
- ['mall_id' => $this->mall_id],
- ['store_id' => $this->store_id],
- ['goods_id' => $store_goods_reserve_sku['goods_id']],
- ['>=', 'service_start_at', strtotime($date . ' 00:00:00')],
- ['<=', 'service_end_at', strtotime($date . ' 23:59:59')],
- ['!=', 'order_status', -4],
- ['create_type' => 1],
- ],
- 'group' => 'service_start_at',
- 'select' => 'count(*) as counts,service_start_at',
- 'index' => 'service_start_at'
- ]);
- }
- $start_time = $this->getRangeStartTime($range_start);
- $time1 = "{$date} {$business_time_start}:00";
- $time2 = "{$date} {$business_time_end}:59";
- $buff = [];
- $time = time();
- $start = strtotime($time1);
- $end = strtotime($time2);
- //切割时间
- for ($i = $start; $i <= $end; $i = $i + 60 * $service_min) {
- $is_reserve = 1;
- $hour_minute = date("H:i", $i);
- $buff[] = ['time' => $hour_minute, 'is_reserve' => $is_reserve];
- }
- $range_end_arr = ReserveServiceEnum::RANGE_END_ARR_MAP;
- $days = $range_end_arr[$range_end] ?? 7;
- $date_list = [];
- $today_time = strtotime(date('Y-m-d', $time) . ' 00:00:00');
- if (!empty($params['date'])) {
- $time = strtotime($params['date'] . ' 00:00:00');
- } else {
- $time = $today_time;
- }
- $end_time = $time + $days * 24 * 3600;
- for ($i = $time; $i < $end_time; $i += 24 * 60 * 60) {
- $is_reserve = 1;
- $time_list = $buff;
- $date = date('Y-m-d', $i);
- $new_time_list = [];
- foreach ($time_list as &$item) {
- $temp_time_start = strtotime("{$date} " . $item['time'] . ":00");
- if (!empty($appointments_number)) {
- if (isset($reservation_service_order_list[$temp_time_start]) && $reservation_service_order_list[$temp_time_start]['counts'] >= $appointments_number) {
- $item['is_reserve'] = 0;
- }
- }
- $te_time = strtotime($date . ' ' . $item['time'] . ':00');
- if ($te_time < time()) {
- continue;
- }
- if ((time() + $start_time) > $te_time) {
- continue;
- }
- $new_time_list[] = $item;
- }
- $arr = ['date' => $date, 'week_day' => GoodsReserveTime::getWeekDay($date), 'time_list' => $new_time_list, 'is_reserve' => $is_reserve];
- $date_list[] = $arr;
- }
- return $date_list;
- }
- /**
- * 技师可预约时间列表
- * @param $params
- * @return array
- * @throws \Exception
- */
- public function techniciansReservationTimeList($params)
- {
- $reservation_service_user = ReservationServiceUser::findOne(['id' => $params['technicians_id']]);
- if (empty($reservation_service_user)) {
- throw new \Exception('技师不存在');
- }
- $list = $this->storeReservationTimeList($params);
- $date_list = $list['date_list'];
- $service_min = $list['service_min'];
- $date_time_arr = [];
- foreach ($date_list as $value) {
- $date_time_arr[] = strtotime($value['date']);
- }
- $scheduling_list = StoreReserveTechnicianScheduling::lists([
- 'where' => [
- ['user_id' => $reservation_service_user['user_id']],
- ['date_time' => $date_time_arr],
- ['status' => StatusEnum::ENABLED]
- ],
- 'with' => [
- 'schedulingTime' => function ($q) {
- $q->where(['status' => StatusEnum::ENABLED]);
- }
- ],
- 'index' => 'date_time'
- ]);
- $reservation_service_order_list = ReservationServiceOrder::lists([
- 'where' => [
- ['mall_id' => $reservation_service_user['mall_id']],
- ['store_id' => $params['store_id']],
- ['staff_user_id' => $reservation_service_user['user_id']],
- ['>=', 'service_start_at', strtotime($params['date'] . ' 00:00:00')],
- ['<=', 'service_end_at', strtotime($params['date'] . ' 23:59:59')],
- ['!=', 'server_status', ReservationServiceEnum::CANCELED]
- ]
- ]);
- $scheduled_time_arr = [];//已预约时间
- foreach ($list as $value) {
- $scheduled_time_arr[date("H:i", $value['service_start_at'])] = 1;
- }
- $occupy_list = ReservationServiceOccupy::lists([
- 'where' => [
- ['mall_id' => $reservation_service_user['mall_id']],
- ['store_id' => $params['store_id']],
- ['staff_user_id' => $reservation_service_user['user_id']],
- ['status' => StatusEnum::ENABLED]
- ]
- ]
- );//已占用时间
- foreach ($date_list as &$item) {
- $date_time = strtotime($item['date']);
- if (isset($scheduling_list[$date_time]) && empty($scheduling_list[$date_time]['is_all_day'])) {
- $scheduling = $scheduling_list[$date_time];
- foreach ($item['time_list'] as $k => &$v) {
- $v['is_reserve'] = 0;
- $temp_time = strtotime("{$item['date']} {$v['time']}:00") + $service_min * 60;
- foreach ($scheduling['schedulingTime'] as $scheduling_time) {
- if ($temp_time >= $scheduling_time['start_time'] && $temp_time <= $scheduling_time['end_time']) {
- $v['is_reserve'] = 1;
- }
- }
- }
- }
- foreach ($item['time_list'] as $k => &$v) {
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- if (empty($v['is_reserve'])) {
- continue;
- }
- foreach ($reservation_service_order_list as $value) {
- if ($temp_time >= $value['service_start_at'] && $temp_time <= $value['service_end_at']) {
- $v['is_reserve'] = 0;
- break;
- }
- }
- }
- foreach ($item['time_list'] as $k => &$v) {
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- if (empty($v['is_reserve'])) {
- continue;
- }
- foreach ($occupy_list as $occupy) {
- if ($temp_time >= $occupy['start_at'] && $temp_time <= $occupy['end_at']) {
- $v['is_reserve'] = 0;
- break;
- }
- }
- }
- }
- return $date_list;
- }
- public function serviceTimeList($params)
- {
- $reservation_service_user = ReservationServiceUser::findOne(['user_id' => $params['id'], 'status' => StatusEnum::ENABLED]);
- if (empty($reservation_service_user)) {
- throw new \Exception('技师不存在');
- }
- $params['start'] = date('Y-m-d', time());
- $list = $this->storeReservationTimeList($params);
- $date_list = $list['date_list'];
- $service_min = $list['service_min'];
- $date_time_arr = [];
- foreach ($date_list as $value) {
- $date_time_arr[] = strtotime($value['date']);
- }
- $scheduling_list = StoreReserveTechnicianScheduling::lists([
- 'where' => [
- ['user_id' => $reservation_service_user['user_id']],
- ['date_time' => $date_time_arr],
- ['status' => StatusEnum::ENABLED]
- ],
- 'with' => [
- 'schedulingTime' => function ($q) {
- $q->where(['status' => StatusEnum::ENABLED]);
- }
- ],
- 'index' => 'date_time'
- ]);
- $reservation_service_order_list = StoreOrderReserve::find()->where([
- 'tech_id' => $reservation_service_user['id'],
- 'store_id' => $params['store_id'],
- 'mall_id' => $reservation_service_user['mall_id'],
- ])->andWhere(['!=', 'order_status', -4])
- ->andWhere(['>=', 'service_start_at', time()])
- ->asArray()
- ->all();
- $scheduled_time_arr = [];//已预约时间
- foreach ($reservation_service_order_list as $value) {
- $scheduled_time_arr[date("H:i", $value['service_start_at'])] = 1;
- }
- $store_goods_reserve_sku = StoreGoodsReserveSku::getOne([
- ['id' => $params['sku_id']]
- ], true, ['reserve']);
- if (empty($store_goods_reserve_sku)) {
- throw new \Exception('商品不存在');
- }
- $appointments_number = $store_goods_reserve_sku['reserve']['appointments_number'] ?? 0;
- $occupy_list = ReservationServiceOccupy::lists([
- 'where' => [
- ['mall_id' => $reservation_service_user['mall_id']],
- ['store_id' => $params['store_id']],
- ['staff_user_id' => $reservation_service_user['user_id']],
- ['status' => StatusEnum::ENABLED]
- ]
- ]
- );//已占用时间
- if (!empty($appointments_number)) {
- $store_order_reserve_list = StoreOrderReserve::lists([
- 'where' => [
- ['mall_id' => $this->mall_id],
- ['store_id' => $this->store_id],
- ['goods_id' => $store_goods_reserve_sku['goods_id']],
- ['!=', 'order_status', -4],
- ['create_type' => 1],
- ],
- 'group' => 'service_start_at',
- 'select' => 'count(*) as counts,service_start_at',
- 'index' => 'service_start_at'
- ]);
- foreach ($store_order_reserve_list as &$temp) {
- $temp['service_start_at_date'] = date('Y-m-d H:i', $temp['service_start_at']);
- }
- }
- foreach ($date_list as $k => &$item) {
- $date_time = strtotime($item['date']);
- if (!isset($scheduling_list[$date_time])) {
- $item['is_reserve'] = 0;
- foreach ($item['time_list'] as &$v) {
- $v['is_reserve'] = 0;
- }
- continue;
- }
- if (isset($scheduling_list[$date_time]) && empty($scheduling_list[$date_time]['is_all_day'])) {
- $scheduling = $scheduling_list[$date_time];
- foreach ($item['time_list'] as $k => &$v) {
- $v['is_reserve'] = 0;
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- foreach ($scheduling['schedulingTime'] as $scheduling_time) {
- if ($temp_time >= $scheduling_time['start_time'] && $temp_time <= $scheduling_time['end_time']) {
- $v['is_reserve'] = 1;
- }
- }
- }
- }
- foreach ($item['time_list'] as $k => &$v) {
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- if (!empty($appointments_number) && isset($store_order_reserve_list) && $store_order_reserve_list[$temp_time]['counts'] >= $appointments_number) {
- $v['is_reserve'] = 0;
- }
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- if (empty($v['is_reserve'])) {
- continue;
- }
- foreach ($reservation_service_order_list as $value) {
- if ($temp_time >= $value['service_start_at'] && $temp_time < $value['service_end_at']) {
- $v['is_reserve'] = 0;
- break;
- }
- }
- }
- foreach ($item['time_list'] as $k => &$v) {
- $temp_time = strtotime("{$item['date']} {$v['time']}:00");
- if (empty($v['is_reserve'])) {
- continue;
- }
- foreach ($occupy_list as $occupy) {
- $temp_time_end = $temp_time + $service_min * 60;
- if ($temp_time >= $occupy['start_at'] && $temp_time <= $occupy['end_at'] && $temp_time_end <= $occupy['end_at']) {
- $v['is_reserve'] = 0;
- break;
- }
- }
- }
- $date_is_reserve = 0;
- foreach ($item['time_list'] as $val) {
- if ($val['is_reserve']) {
- $date_is_reserve = 1;
- break;
- }
- }
- $item['is_reserve'] = $date_is_reserve;
- }
- return array_values($date_list);
- }
- public function search($params)
- {
- $date = $params['date'] . ' ' . $params['time'] . ':00';
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail();
- $employee_selection = $store_reserve_setting['employee_selection'] ?? 1;
- if ($employee_selection == 3) {
- $list_page['list'] = [];
- $list_page['page'] = 0;
- $list_page['page_size'] = 10;
- $list_page['count'] = 0;
- $list_page['page_count'] = 0;
- $list_page['error_msg'] = '技师不可选';
- return $list_page;
- }
- $service_min = 0;
- $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
- switch ($store_reserve_setting['appointment_interval']) {
- case 1:
- $service_min = $store_goods_reserve_sku['service_min'] ?? 0;
- break;
- }
- $appointments_number = $store_goods_reserve_sku['reserve']['appointments_number'] ?? 0;
- $start_time = strtotime($date);
- $end_time = $start_time + $service_min * 60;
- if (!empty($appointments_number)) {
- $store_order_reserve_list = StoreOrderReserve::lists([
- 'where' => [
- ['mall_id' => $this->mall_id],
- ['store_id' => $this->store_id],
- ['goods_id' => $store_goods_reserve_sku['goods_id']],
- ['>=', 'service_start_at', $start_time],
- ['<=', 'service_end_at', $end_time],
- ['!=', 'order_status', -4],
- ['create_type' => 1],
- ],
- 'group' => 'service_start_at',
- 'select' => 'count(*) as counts,service_start_at',
- 'index' => 'service_start_at'
- ]);
- $is_false = 0;
- if (isset($store_order_reserve_list) && $store_order_reserve_list[$start_time]['counts'] >= $appointments_number) {
- $is_false = 1;
- }
- if ($is_false) {
- $list_page['list'] = [];
- $list_page['page'] = 0;
- $list_page['page_size'] = 10;
- $list_page['count'] = 0;
- $list_page['page_count'] = 0;
- $list_page['is_full'] = 1;
- return $list_page;
- }
- }
- $day_start_time = strtotime($params['date'] . ' 00:00:00');
- $user_ids = ReservationServiceStoreGoods::find()->where(['store_id' => $params['store_id'], 'goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED])
- ->select('user_id')->column();
- $new_user_ids = [];
- $user_ids_all = StoreReserveTechnicianScheduling::find()->where(['user_id' => $user_ids, 'is_all_day' => 1, 'date_time' => $day_start_time, 'status' => StatusEnum::ENABLED])
- ->select('user_id')->column();
- $new_user_ids = array_merge($new_user_ids, $user_ids_all);
- $scheduling_list = StoreReserveTechnicianScheduling::find()->where(['user_id' => $user_ids, 'is_all_day' => 0, 'date_time' => $day_start_time, 'status' => StatusEnum::ENABLED])
- ->with(['schedulingTime'])->all();
- foreach ($scheduling_list as $val) {
- foreach ($val['schedulingTime'] as $v) {
- if (($v['start_time'] <= $start_time && $start_time <= $v['end_time']) && ($v['start_time'] <= $end_time)) {
- $new_user_ids[] = $val['user_id'];
- break;
- }
- }
- }
- $store_order_reserve_list = StoreOrderReserve::find()->where([
- 'store_id' => $params['store_id'],
- ])->andWhere(['!=', 'order_status', -4])
- ->andWhere(['>=', 'created_at', time() - 30 * 24 * 3600])
- ->all();
- $date_time = strtotime($date);
- $tech_id_ids = [];
- foreach ($store_order_reserve_list as $value) {
- if ($value['service_start_at'] <= $date_time && $value['service_end_at'] > $date_time) {
- $tech_id_ids[] = $value['tech_id'];
- }
- }
- $reserve_user_ids = ReservationServiceUser::find()->where(['id' => $tech_id_ids])->select('user_id')->column();
- $occupy_list = ReservationServiceOccupy::lists([
- 'where' => [
- ['mall_id' => $this->mall_id],
- ['store_id' => $params['store_id']],
- ['status' => StatusEnum::ENABLED],
- ]
- ]
- );//已占用时间
- $staff_user_ids = [];
- foreach ($occupy_list as $val) {
- if ($start_time >= $val['start_at'] && $start_time <= $val['end_at'] && $end_time <= $val['end_at']) {
- $staff_user_ids[] = $val['staff_user_id'];
- }
- }
- $user_ids = array_diff($new_user_ids, $reserve_user_ids, $staff_user_ids);
- $where = [
- ['store_id' => $params['store_id']],
- ['user_id' => $user_ids],
- ['status' => StatusEnum::ENABLED],
- ['store_status' => StatusEnum::ENABLED]
- ];
- if (!empty($params['name'])) {
- $where[] = ['like', 'name', trim($params['name'])];
- }
- if (!empty($params['min_age'])) {
- $where[] = ['>=', 'age', $params['min_age']];
- }
- if (!empty($params['max_age'])) {
- $where[] = ['<=', 'age', $params['max_age']];
- }
- if (!empty($params['gender'])) {
- $where[] = ['gender' => $params['gender']];
- }
- $orderBy = 'id desc';
- if (!empty($user_ids)) {
- $user_ids = join(',', $user_ids);
- $orderBy = ["field(user_id,{$user_ids})" => []]; //1-距离
- }
- if (isset($params['sort']) && $params['sort'] > 1) {
- //1-距离,2-订单量 order_num ,3-好评 service_rating
- if ($params['sort'] == 1) {
- $orderBy = 'distance asc'; //1-距离
- } else {
- $orderBy = $params['sort'] == 2 ? 'order_num desc' : 'service_rating desc';
- }
- }
- $params['order'] = $orderBy;
- $params['where'] = $where;
- $list = ReservationServiceUser::listPage($params);
- $default_jishi = [];
- if (!empty($list['list'])) {
- $store_ids = array_column($list['list'], 'store_id');
- $store_ids = array_unique($store_ids);
- $store_list = Store::lists([
- 'where' => [
- ['id' => $store_ids]
- ],
- 'select' => 'id,store_name',
- 'index' => 'id'
- ]);
- $comments = OrderReserveComments::lists([
- 'where' => [
- ['tech_user_id' => array_column($list['list'], 'user_id')],
- ['reserve_type' => StatusEnum::ENABLED],
- ['store_id' => $store_ids]
- ],
- 'select' => 'COUNT(*) as total, tech_user_id',
- 'group' => 'tech_user_id',
- 'index' => 'tech_user_id'
- ]);
- $default_jishi = $list['list'][0];
- foreach ($list['list'] as &$item) {
- $item['store_name'] = $store_list[$item['store_id']]['store_name'] ?? '';
- $item['commentNum'] = $comments[$item['user_id']]['total'] ?? 0;
- $item['comment_num'] = $item['commentNum'];
- $item['serviceNum'] = $item['order_num'];
- $item['detail'] = $item['desc'];
- }
- }
- if (!empty($params['is_default_jishi']) && !empty($default_jishi)) {
- $params['technicians_id'] = $default_jishi['id'];
- $date_list = $this->techniciansReservationTimeList($params);
- $lately_time_arr = [];
- if (!empty($date_list)) {
- $time = '';
- foreach ($date_list[0]['time_list'] as $k => $v) {
- if ($v['is_reserve']) {
- $time = $v['time'];
- break;
- }
- }
- $lately_time_arr = [
- 'date' => $date_list[0]['date'],
- 'time' => $time,
- 'week_day' => $date_list[0]['week_day'],
- ];
- }
- $default_jishi['lately_time_arr'] = $lately_time_arr;
- $list['default_jishi'] = $default_jishi;
- }
- return $list;
- }
- //门店-预约商品详情-前四个技师
- public function topFourth($params)
- {
- $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
- if (empty($store_goods_reserve_sku)) {
- throw new \Exception('预约商品不存在');
- }
- $this->store_id = $store_goods_reserve_sku['store_id'];
- $params['store_id'] = $store_goods_reserve_sku['store_id'];
- $params['goods_id'] = $store_goods_reserve_sku['goods_id'];
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $params['store_id']]))->detail();
- $service_min = $this->getServiceMin($store_reserve_setting['appointment_interval'], $store_goods_reserve_sku['service_min'] ?? 0);
- $range_start_time = $this->getRangeStartTime($store_reserve_setting['range_start']);
- if (empty($params['id'])) {
- $user_ids = ReservationServiceStoreGoods::find()->where(['store_id' => $params['store_id'], 'goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED])
- ->select('user_id')->column();
- } else {
- $user_ids = $params['id'];
- }
- $time = time();
- $service_user_list = ReservationServiceUser::lists(['where' => [
- ['user_id' => $user_ids],
- ['store_id' => $this->store_id],
- ['status' => StatusEnum::ENABLED]
- ]]);
- $user_ids = array_column($service_user_list, 'user_id');
- //排班列表
- $scheduling_list = StoreReserveTechnicianScheduling::lists([
- 'where' => [
- ['user_id' => $user_ids],
- ['status' => StatusEnum::ENABLED],
- ['>=', 'date_time', strtotime(date('Y-m-d', $time) . ' 00:00:00')]
- ],
- 'order' => 'date_time asc,is_all_day desc',
- 'with' => ['schedulingTime']
- ]);
- $store = Store::findOne(['id' => $params['store_id']]);
- $top_fourth_list = [];
- $params['user_ids'] = $user_ids;
- $params['time'] = $time;
- $params['service_min'] = $service_min;
- foreach ($scheduling_list as $scheduling) {
- $params['staff_user_id'] = $scheduling['user_id'];
- if ($scheduling['is_all_day'] == 1) { //全天上班
- $date = date('Y-m-d', $scheduling['date_time']);
- $start_time = strtotime($date . ' ' . $store['business_time_start'] . ':00');
- $end_time = strtotime($date . ' ' . $store['business_time_end'] . ':59');
- if ($end_time < $time) {
- continue;
- }
- $params['start_time'] = $start_time - $range_start_time;
- $params['end_time'] = $end_time;
- if (isset($top_fourth_list[$scheduling['user_id']])) {
- continue;
- }
- $top_three_item = $this->getTopThreeItem($params);
- if (empty($top_three_item)) {
- continue;
- }
- $top_fourth_list[$top_three_item['user_id']] = $top_three_item;
- } else {
- foreach ($scheduling['schedulingTime'] as $scheduling_time) {
- $start_time = $scheduling_time['start_time'];
- $end_time = $scheduling_time['end_time'];
- if ($end_time < $time) {
- continue;
- }
- $params['start_time'] = $start_time + $range_start_time;
- $params['end_time'] = $end_time;
- if (isset($top_fourth_list[$scheduling['user_id']])) {
- continue;
- }
- $top_three_item = $this->getTopThreeItem($params);
- if (empty($top_three_item)) {
- continue;
- }
- $top_fourth_list[$top_three_item['user_id']] = $top_three_item;
- }
- }
- }
- $new_top_fourth_list = [];
- $top_fourth_list = ArrayHelper::arraySort($top_fourth_list, 'time_stamp', 'asc');
- foreach ($top_fourth_list as $value) {
- if (count($new_top_fourth_list) >= 4) {
- break;
- }
- $new_top_fourth_list[] = $value;
- }
- $user_ids = array_column($new_top_fourth_list, 'user_id');
- $reservation_service_user_list = ReservationServiceUser::lists([
- 'where' => [
- ['user_id' => $user_ids],
- ['status' => StatusEnum::ENABLED],
- ['store_status' => StatusEnum::ENABLED]
- ],
- 'index' => 'user_id',
- 'select' => 'id,user_id,name,avatar'
- ]);
- foreach ($new_top_fourth_list as $k => &$top_three) {
- $top_three['name'] = $top_three['avatar'] = $top_three['tech_id'] = '';
- if ($reservation_service_user_list[$top_three['user_id']]) {
- $top_three['tech_id'] = $reservation_service_user_list[$top_three['user_id']]['id'];
- $top_three['name'] = $reservation_service_user_list[$top_three['user_id']]['name'];
- $top_three['avatar'] = $reservation_service_user_list[$top_three['user_id']]['avatar'];
- } else {
- unset($new_top_fourth_list[$k]);
- }
- }
- $employee_selection = $store_reserve_setting['employee_selection'] ?? 1;
- if (in_array($employee_selection, [1, 3]) && count($new_top_fourth_list) == 4) {
- array_pop($new_top_fourth_list);
- }
- $store_data = [
- 'store_id' => $store['id'],
- 'store_name' => $store['store_name'],
- 'logo_img' => $store['logo_img'],
- ];
- return ['list' => array_values($new_top_fourth_list), 'store_data' => $store_data];
- }
- public function getRangeStartTime($range_start)
- {
- $range_start_time = 0;
- switch ($range_start) {
- case 2:
- $range_start_time = 30 * 60;
- break;
- case 3:
- $range_start_time = 60 * 60;
- break;
- }
- return $range_start_time;
- }
- public function getServiceMin($appointment_interval, $min)
- {
- switch ($appointment_interval) {
- case 1:
- $service_min = $min;
- break;
- default:
- $service_min = $min ?? 30;
- }
- return $service_min;
- }
- protected function getTopThreeItem($params)
- {
- $start_time = $params['start_time'];
- $end_time = $params['end_time'];
- $service_min = $params['service_min'];
- $time = $params['time'];
- $staff_user_id = $params['staff_user_id'];
- $user_ids = $params['user_ids'];
- //技师已被占用的时间段
- $reservation_service_order_list = ReservationServiceOrder::lists([
- 'where' => [
- ['store_id' => $params['store_id']],
- ['staff_user_id' => $user_ids],
- ['!=', 'server_status', ReservationServiceEnum::CANCELED],
- ],
- 'with' => ['goodsReserve']
- ]);
- $reservation_service_order_arr = [];
- foreach ($reservation_service_order_list as $item) {
- $reservation_service_order_arr[$item['staff_user_id']][] = $item;
- }
- for ($i = $start_time; $i <= $end_time; $i = $i + 60 * $service_min) {
- if ($i < $time) {
- continue;
- }
- $is_occupy = 0;//是否被占用
- if (isset($reservation_service_order_arr[$staff_user_id])) {
- foreach ($reservation_service_order_arr[$staff_user_id] as $reservation_service_order) {
- $temp_service_min = $reservation_service_order['goodsReserve']['service_min'] * 60;
- $service_start_at = $reservation_service_order['service_start_at'];
- $service_end_at = $reservation_service_order['service_start_at'] + $temp_service_min;
- if ($service_start_at == $i || ($i > $service_start_at && $i < $service_end_at)) {
- //可预约时间已被占用
- $is_occupy = 1;
- break;
- }
- }
- }
- if ($is_occupy) {
- continue;
- }
- return ['user_id' => $staff_user_id, 'time' => date("H:i", $i), 'time_stamp' => $i];
- }
- return [];
- }
- /**
- * 服务人员页面-门店-可预约日期
- * @return array[]
- * @throws \Exception
- */
- public function getDate($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 = ReservationServiceEnum::RANGE_END_ARR_MAP;
- $days = $range_end_arr[$range_end] ?? 7;
- $date_list = [];
- $time = time();
- $i = 0;
- while (true) {
- if ($i >= $days) {
- break;
- }
- $temp_time = $time + $i * 86400;
- $date = date('Y-m-d', $temp_time);
- $date_list[] = ['date' => $date, 'is_reserve' => 1, 'week_day' => GoodsReserveTime::getWeekDay($date)];
- $i++;
- }
- if (!empty($params['start'])) {
- $start_time = strtotime($params['start'] . ' 00:00:00');
- $i = 0;
- $temp_date_list = array_column($date_list, null, 'date');
- $date_list = [];
- while (true) {
- if ($i >= $days) {
- break;
- }
- $temp_time = $start_time + $i * 86400;
- $date = date('Y-m-d', $temp_time);
- $is_reserve = 0;
- if (isset($temp_date_list[$date])) {
- $is_reserve = 1;
- }
- $date_list[] = ['date' => $date, 'is_reserve' => $is_reserve, 'week_day' => GoodsReserveTime::getWeekDay($date)];
- $i++;
- }
- }
- return ['date_list' => $date_list];
- }
- /**
- * 服务人员页面-门店-获取可预约的时间段
- * @param $params
- * @return array
- * @throws \Exception
- */
- public function getTimes($params)
- {
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]))->detail();
- $range_start = $store_reserve_setting['range_start'];
- $store = Store::findOne(['id' => $this->store_id]);
- $business_time_start = $store['business_time_start'];
- $business_time_end = $store['business_time_end'];
- $store_goods_reserve_sku = StoreGoodsReserveSku::findOne(['id' => $params['sku_id']]);
- $service_min = $this->getServiceMin($store_reserve_setting['appointment_interval'], $store_goods_reserve_sku['service_min'] ?? 30);
- if (empty($service_min)) {
- throw new \Exception('该商品没有设置服务时长');
- }
- $start_time = $this->getRangeStartTime($range_start);
- $time1 = $params['date'] . ' ' . $business_time_start . ':00';
- $time2 = $params['date'] . ' ' . $business_time_end . ':59';
- $buff = [];
- $start = strtotime($time1);
- $end = strtotime($time2);
- for ($i = $start; $i <= $end; $i = $i + 60 * $service_min) {
- $buff[] = ['time' => date("H:i", $i), 'is_reserve' => 1];
- }
- //切割时间
- $time = time();
- $time_list = $buff;
- foreach ($time_list as $key => &$val) {
- if (($time + $start_time) > strtotime($params['date'] . ' ' . $val['time'] . ':00')) {
- unset($time_list[$key]);
- }
- $temp_time = strtotime($params['date'] . ' ' . $val['time'] . ':00') + $service_min * 60;
- if ($temp_time > $end) {
- $val['is_reserve'] = 0;
- }
- }
- $time_list = array_values($time_list);
- return ['time_list' => $time_list];
- }
- }
|