From 9672a12ae9df946cca47af65155801ff22d189ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B2=A9=E4=BB=9488?= <>
Date: Thu, 12 Mar 2026 09:38:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=97=B6=E4=BB=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../YeWu/DepartmentResourceController.php | 6 +-
.../API/Admin/YeWu/PlanListController-旧.php | 629 ++++++++++++++++++
.../API/Admin/YeWu/PlanListController.php | 172 +----
.../API/Admin/YeWu/PlanModelController.php | 159 +++--
.../app/Services/Admin/YeWu/RosterService.php | 258 +++++++
.../src/views/AppointmentMngr/PlanModel.vue | 333 +++++++++-
6 files changed, 1333 insertions(+), 224 deletions(-)
create mode 100644 Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController-旧.php
create mode 100644 Laravel/app/Services/Admin/YeWu/RosterService.php
diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/DepartmentResourceController.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/DepartmentResourceController.php
index 343070e..f124744 100644
--- a/Laravel/app/Http/Controllers/API/Admin/YeWu/DepartmentResourceController.php
+++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/DepartmentResourceController.php
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\Admin\YeWu\DepartmentResourceService;
use Illuminate\Support\Facades\DB;
+use function Symfony\Component\Translation\t;
class DepartmentResourceController extends Controller
{
@@ -34,7 +35,10 @@ class DepartmentResourceController extends Controller
}
if(isset($userInfo->department_id)) $department_id=$userInfo->department_id;
if(isset($res_department_id)) $department_id=$res_department_id;
- $resource=DB::table('s_department_resources')->where(['department_id'=>$department_id,'department_resources_status'=>1,'is_del'=>0])->get();
+ $resource=DB::table('s_department_resources')->where(['department_id'=>$department_id,'department_resources_status'=>1,'is_del'=>0])->orderBy('id')->get();
+ foreach($resource as $k=>$v){
+ $v->time_range=json_decode($v->time_range,true);
+ }
if(count($resource)>0){
return \Yz::Return(true, '操作成功',$resource);
}else{
diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController-旧.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController-旧.php
new file mode 100644
index 0000000..b39a83a
--- /dev/null
+++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController-旧.php
@@ -0,0 +1,629 @@
+get('userid');//中间件产生的参数
+ $userInfo = DB::table('users')->where(['id' => $userid])->get();
+ $department_id = $userInfo[0]->department_id;
+ $dateRange = request('dateRange');
+ $planModelIds = request('ids');
+ $HolidayEnable = request('HolidayEnable');
+ $date_type = request('date_type');
+ //循环日期和勾选的模板创建明细
+ if (count($dateRange) == 2 && count($planModelIds) > 0) {
+ $models = DB::table('s_source_roster')->whereIn('id', $planModelIds)->get();
+ //检查是否有异常状态模板
+ foreach ($models as $model) {
+ if ($model->status != 1 || $model->is_del != 0) {
+ return \Yz::echoError1('模板状态异常,请重新选择!异常模板Id:' . $model->id);
+ }
+ }
+ $start_date = new DateTime($dateRange[0]);
+ $end_date = new DateTime($dateRange[1]);
+
+ //查询是否有重复插入
+ $checkList = DB::table('s_source_roster_detail')
+ ->where('department_id', $department_id)
+ ->whereIn('roster_id', $planModelIds)
+ ->where('date', '>=', $start_date->format('Y-m-d'))
+ ->where('date', '<=', $end_date->format('Y-m-d'))
+ ->where('is_del', 0)
+ ->get();
+ $msg = '当前选中的';
+ $msglist = '';
+ $msgIds = '';
+ if (count($checkList) > 0) {
+ foreach ($models as $model) {
+ foreach ($checkList as $item) {
+ if ($item->roster_id == $model->id) {
+ $msglist .= $item->date . ' ';
+ $msgIds .= $item->id . ' ';
+ $msg .= " " . $model->weekname . $model->begin_time . '-' . $model->end_time . " ";
+ }
+ }
+
+ }
+ return \Yz::Return(false, '已有重复的计划明细,禁止创建!' . $msg . '已存在相同记录,存在于:' . $msglist . '对应记录Id为:' . $msgIds . '请先删除后再操作', $checkList);
+ }
+ //查询勾选的时间范围内所有的节假日
+ $holiday_list=DB::table('s_holiday')->whereBetween('date',$dateRange)->where(['type'=>2])->pluck('date')->toArray();
+
+ // 循环日期并判断星期
+ $current_date = clone $start_date;
+ DB::beginTransaction();
+ $success_count = 0;//成功创建的数量
+ while ($current_date <= $end_date) {
+ //如果是节假日模板,则判断当前日期是否是节假日,不是则跳过
+ if ($date_type == 2) {
+ if (!in_array($current_date->format('Y-m-d'),$holiday_list)){
+ // 将当前日期增加一天
+ $current_date->modify('+1 day');
+ continue;
+ }
+ }
+ //如果选择节假日不可用,并且当前日期是节假日,则跳过
+ if($HolidayEnable==0 and in_array($current_date->format('Y-m-d'),$holiday_list)){
+ // 将当前日期增加一天
+ $current_date->modify('+1 day');
+ continue;
+ }
+
+ // 获取当前日期的星期几(0表示星期日,1表示星期一,以此类推)
+ $weekday = $current_date->format('w');
+ $weekname = '';
+ switch ($weekday) {
+ case 0:
+ $weekname = '星期日';
+ break;
+ case 1:
+ $weekname = '星期一';
+ break;
+ case 2:
+ $weekname = '星期二';
+ break;
+ case 3:
+ $weekname = '星期三';
+ break;
+ case 4:
+ $weekname = '星期四';
+ break;
+ case 5:
+ $weekname = '星期五';
+ break;
+ case 6:
+ $weekname = '星期六';
+ break;
+ }
+ foreach ($models as $model) {
+ if ($date_type == 1 and $model->date_type==1) {
+ if ($model->weekname <> $weekname) continue;
+ }
+
+ // 插入明细表
+ $data = [
+ 'roster_id' => $model->id,
+ 'date' => $current_date,
+ 'weekname' => $weekname,
+ 'department_id' => $model->department_id,
+ 'resources_id' => $model->resources_id,
+ 'device_id' => $model->device_id,
+ 'period_id' => $model->period_id,
+ 'patient_type' => $model->patient_type,
+ 'begin_time' => $model->begin_time,
+ 'end_time' => $model->end_time,
+ 'end_reservation_time' => $model->end_reservation_time,
+ 'time_unit' => $model->time_unit,
+ 'status' => 1,
+ 'adduser' => $userid,
+ 'is_del' => 0,
+ ];
+
+
+ $plan_id = DB::table('s_source_roster_detail')->insertGetId($data);
+ if ($plan_id) {
+ $success_count++;
+ }
+ // 插入数量表
+ $model_count_info = DB::table('s_source_roster_count')->where(['roster_id' => $model->id])->get();
+ if (count($model_count_info) > 0) {
+ foreach ($model_count_info as $info) {
+ $i_c = DB::table('s_source_roster_detail_count')->insert([
+ 'roster_detail_id' => $plan_id,
+ 'appointment_type_id' => $info->appointment_type_id,
+ 'count' => $info->count,
+ 'max_total' => $info->max_total,
+ ]);
+ if (!$i_c) {
+ DB::rollBack();
+ return \Yz::echoError1('渠道数量创建失败');
+ }
+ }
+ } else {
+ DB::rollBack();
+ return \Yz::echoError1('模板数量信息异常,请重新选择!异常模板Id:' . $model->id);
+ }
+ if (isset($model->device_id)) {
+ $device_ids = explode(",", $model->device_id);
+ foreach ($device_ids as $dv_key => $dv_value) {
+ $i_dev = DB::table('s_source_roster_detail_device')->insert([
+ 'roster_detail_id' => $plan_id,
+ 'device_id' => $dv_value,
+ ]);
+ if (!$i_dev) {
+ DB::rollBack();
+ return \Yz::echoError1('设备关联创建失败');
+ }
+ }
+
+ } else {
+ DB::rollBack();
+ return \Yz::echoError1('模板未关联设备,请重新选择!异常模板Id:' . $model->id);
+ }
+
+
+ }
+ // 将当前日期增加一天
+ $current_date->modify('+1 day');
+
+ }
+ DB::commit();
+ return \Yz::Return(true, '执行完成,范围:' . $dateRange[0] . '-' . $dateRange[1] . ',共计生成计划 ' . $success_count . ' 条', ['dateRange' => $dateRange, 'success_count' => $success_count]);
+ }
+ }
+
+ public function GetList(Request $request)
+ {
+ $userid = $request->get('userid');//中间件产生的参数
+ $group = $request->get('role');//中间件产生的参数
+ $searchInfo = request('searchInfo');
+ $page = request('page');
+ $pageSize = request('pageSize');
+ $department_id = 0;
+ $department_info=false;
+ $list = DB::table('s_source_roster_detail')
+ ->leftJoin('s_department_resources', 's_source_roster_detail.resources_id', '=', 's_department_resources.id')
+ // ->leftJoin('s_devices', 's_source_roster_detail.device_id', '=', 's_devices.id')
+ ->leftJoin('s_period', 's_source_roster_detail.period_id', '=', 's_period.id')
+ ->select('s_source_roster_detail.*', 's_department_resources.department_resources_name', 's_period.period_name')
+ ->where(['s_source_roster_detail.is_del' => 0]);
+ if (!empty($searchInfo['department_id'])) {//以前判断的是管理员group==1 改为 (任何角色都能查看了)
+ if (!empty($searchInfo['department_id'])) {
+ $department_info=DB::table('s_department')->where(['id' => $searchInfo['department_id']])->first();
+ $list = $list->where('s_source_roster_detail.department_id', $searchInfo['department_id']);
+ }
+
+ } else {
+ $userInfo = DB::table('users')->where(['id' => $userid])->get();
+ $department_id = $userInfo[0]->department_id;
+ $department_info=DB::table('s_department')->where(['id' => $department_id])->first();
+ $list = $list->where(['s_source_roster_detail.department_id' => $department_id]);
+ }
+ if (!empty($searchInfo['resources_id'])) {
+ $list = $list->where('s_source_roster_detail.resources_id', $searchInfo['resources_id']);
+ }
+ if (!empty($searchInfo['device_id'])) {
+ //$list = $list->where('s_source_roster_detail.device_id', 'like','%,'.$searchInfo['device_id'].',%' );
+ $list = $list->whereRaw("FIND_IN_SET({$searchInfo['device_id']}, s_source_roster_detail.device_id)");
+ }
+ if (!empty($searchInfo['xingqi'])) {
+ $list = $list->where('s_source_roster_detail.weekname', $searchInfo['xingqi']);
+ }
+ if (isset($searchInfo['status'])) {
+ $list = $list->where('s_source_roster_detail.status', $searchInfo['status']);
+ }
+ if (count($searchInfo['dateRange']) == 2) {
+ $list = $list->whereBetween('s_source_roster_detail.date', $searchInfo['dateRange']);
+ }
+
+ $count = $list;
+ $count = $count->count();
+ $list = $list->orderBy('id', 'desc')->limit($pageSize)->skip(($page - 1) * $pageSize) // 跳过前9999条记录
+ ->take($pageSize)->get();
+ $ids = [];
+ foreach ($list as $key => $value) {
+ $list[$key]->department_name = !!$department_info?$department_info->department_name:'' ;
+ $list[$key]->countsInfo = [];
+ $ids[] = $value->id;
+ }
+ //匹配渠道数量
+ $countsInfo = DB::table('s_source_roster_detail_count')
+ ->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
+ ->select('s_source_roster_detail_count.*', 's_appointment_type.name','s_appointment_type.jiancheng')
+ ->whereIn('roster_detail_id', $ids)->get();
+
+ if (count($countsInfo) > 0) {
+ foreach ($list as $key => $value) {
+ foreach ($countsInfo as $k => $v) {
+ if ($value->id == $v->roster_detail_id) {
+ $list[$key]->countsInfo[] = $v;
+ }
+ }
+ }
+ }
+ //匹配设备(服务组)
+ $devices = DB::table('s_devices')->get();
+ foreach ($list as $key => $value) {
+ $list[$key]->devices = [];
+ $array_device_id = explode(",", $value->device_id);
+ foreach ($devices as $k => $v) {
+ if (in_array($v->id, $array_device_id)) {
+ $list[$key]->devices[] = $v;
+ }
+ }
+ }
+
+ return \Yz::Return(true, '获取成功', ['list' => $list, 'count' => $count]);
+ }
+
+ public function GetDetail()
+ {
+ $id = request('id');
+ $info = DB::table('s_source_roster_detail')->where(['id' => $id, 'is_del' => 0])->first();
+ $info->patientType = explode(',', $info->patient_type);
+ $info->department_name = DB::table('s_department')->where('id', $info->department_id)->first()->department_name;
+ $info->resources_name = DB::table('s_department_resources')->where('id', $info->resources_id)->first()->department_resources_name;
+ $info->devices = DB::table('s_devices')->whereIn('id', explode(',', $info->device_id))->get();
+ $info->coutsInfo = DB::table('s_source_roster_detail_count')
+ ->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
+ ->leftJoin('s_appointment_type_ratio', 's_appointment_type.id', '=', 's_appointment_type_ratio.appointment_type_id')
+ ->select('s_source_roster_detail_count.*', 's_appointment_type.name', 's_appointment_type_ratio.ratio')
+ ->where(['s_source_roster_detail_count.roster_detail_id' => $id, 's_appointment_type_ratio.department_id' => $info->department_id])->get();
+ $info->max_total = 0;
+ if (count($info->coutsInfo) > 0) {
+ $info->max_total = $info->coutsInfo[0]->max_total;
+ }
+ return \Yz::Return(true, '获取成功', $info);
+ }
+
+ public function ChangeInfo(Request $request)
+ {
+ $userid = $request->get('userid');//中间件产生的参数
+ $group = $request->get('role');//中间件产生的参数
+ $PlanDetaiInfo = request('PlanDetaiInfo');
+ $userInfo = DB::table('users')->where(['id' => $userid])->get();
+ $department_id = $userInfo[0]->department_id;
+ $check = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])
+ ->where('department_id', $department_id)
+ ->where('is_del', 0)
+ ->first();
+ if (!$check) return \Yz::echoError1('没有权限');
+ $u1 = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
+ 'status' => $PlanDetaiInfo['status']
+ ]);
+ $i = 0;
+ foreach ($PlanDetaiInfo['coutsInfo'] as $key => $value) {
+ $u2 = DB::table('s_source_roster_detail_count')->where(['id' => $value['id']])->update([
+ 'count' => $value['count']==null?0:$value['count'],
+ 'max_total' => $value['max_total'],
+ ]);
+ if ($u2) $i++;
+ }
+ if ($u1 or $i > 0) {
+ return \Yz::Return(true, '保存成功', []);
+ } else {
+ return \Yz::echoError1('没有数据更新');
+ }
+ }
+
+ public function Del(Request $request)
+ {
+ $userid = $request->get('userid');//中间件产生的参数
+ $userInfo = DB::table('users')->where(['id' => $userid])->get();
+ $department_id = $userInfo[0]->department_id;
+ $ids = request('ids');
+ $u1 = DB::table('s_source_roster_detail')->where(['department_id' => $department_id])->whereIn('id', $ids)->update([
+ 'is_del' => 1
+ ]);
+ if ($u1) {
+ return \Yz::Return(true, '删除成功', []);
+ } else {
+ return \Yz::echoError1('删除失败');
+ }
+ }
+
+ //获取可用的计划,用于计划占用
+ public function GetEnablePlan()
+ {
+ $regnum = request('regnum');
+ $entrustid = request('entrustid');
+ $episodeid = request('episodeid');
+ $appointment_type = request('appointment_type'); //预约类型
+ $appointment_date = request('date'); //预约日期
+ $service = new PlanListService();
+ return $service->GetEnablePlan($regnum, $entrustid, $episodeid, $appointment_type, $appointment_date);
+ }
+
+ //获取最近可用的,计划 日期
+ public function NearestEnablePlanDate()
+ {
+ $dateRange=config('app.globals.可用号源查询范围');
+ $regnum = request('regnum');
+ $entrustids = request('entrustid');
+ $episodeid = request('episodeid');
+ $appointment_type = request('appointment_type'); //预约类型
+ $appointment_date = request('date'); //预约日期
+ $service = new PlanListService();
+
+ $date_arr = [];
+
+
+ $startDate = new DateTime();
+ // 设定结束日期为当前日期加7天
+ $endDate = new DateTime();
+ $endDate->modify('+' . $dateRange . ' day');
+ // 循环遍历每一天
+ $currentDate = $startDate;
+ while ($currentDate <= $endDate) {
+ $nowdate = $currentDate->format('Y-m-d');
+ $s = $service->GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_type, $nowdate);
+ if ($s['status']) {
+ $list = $s['data']['plan_list'];
+ if (count($list) > 0) {
+ $date_arr[] = $s['data']['appointment_date'];
+ }
+ }
+ if (count($date_arr) >= 2) {
+ break;
+ }
+ // 每次循环增加一天
+ $currentDate->modify('+1 day');
+ }
+ return \Yz::Return(true, '查询完成', ['list' => $date_arr]);
+
+
+ }
+
+ //开始预约占用名额
+ public function YuYue()
+ {
+ date_default_timezone_set('PRC');
+ $nowdatetime = date("Y-m-d H:i:s");
+ $do_userid=request('do_user');
+ $is_emergency = request('is_emergency');//是否加急
+ $planid = request('planid');
+ $appointment_type = request('appointment_type');//渠道id
+ $mainlistid = request('mainlistid');//主表id
+ $do_type = request('dotype');//操作类型,1预约,2改约
+ if (!isset($do_type)) return \Yz::echoError1('参数:操作类型 不能为空');
+
+ $service = new PlanListService();
+ return $service->YuYue($planid, $appointment_type, $mainlistid, $do_type,$is_emergency,$do_userid);
+ }
+ //自动预约
+ public function AutoYuYue()
+ {
+ $dateRange=config('app.globals.可用号源查询范围');
+ $regnum = request('regnum');
+ $entrustids = request('entrustid');
+ $episodeid = request('episodeid');
+ $appointment_type = request('appointment_type'); //预约类型
+ $TodayDateTime = date("Y-m-d H:i:s");
+ $service = new PlanListService();
+
+ $startDate = new DateTime();
+ // 设定结束日期为当前日期加7天
+ $endDate = new DateTime();
+ $endDate->modify('+' . $dateRange . ' day');
+ // 循环遍历每一天
+ $currentDate = $startDate;
+ $enable_plan=false;
+ while ($currentDate <= $endDate) {
+ $nowdate = $currentDate->format('Y-m-d');
+ $s = $service->GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_type, $nowdate);
+ if ($s['status']) {
+ $list = $s['data']['plan_list'];
+ if (count($list) > 0) {
+ foreach ($list as $k => $v) {
+ if($v->count-$v->used_count>0 and $TodayDateTime< $v->date.' '.$v->end_reservation_time){
+ $enable_plan=$v;
+ break;
+ }
+ }
+ if(!!$enable_plan){
+ break;
+ }
+ }
+ }
+
+ // 每次循环增加一天
+ $currentDate->modify('+1 day');
+ }
+ if(!!$enable_plan){
+ $mainlistids=DB::table('s_list')->whereIn('entrust_id',$entrustids)->pluck('id')->toArray();
+ $service = new PlanListService();
+ return $service->YuYue($enable_plan->id, $appointment_type, $mainlistids, 1);
+ }else{
+ return \Yz::echoError1('最近'.$dateRange.'日无可用号源');
+ }
+ }
+
+ public function CancelYuYue(Request $request)
+ {
+ $MainListId = request('MainListId');
+ $reg_num = request('reg_num');
+ $password = request('password');
+ $userid = $request->get('userid');//中间件产生的参数
+ $do_userid=request('do_user');
+ $query = DB::table('users')->where(['id' => $userid])->get();
+ if (password_verify($password, $query[0]->pwd)) {
+ $service = new PlanListService();
+ return $service->CancelYuYue($MainListId, $reg_num,$do_userid);
+ } else {
+ return \Yz::echoError1('密码不正确');
+ }
+ }
+
+ //查询已预约明细
+ public function GetUsedList()
+ {
+ $planid = request('planid');
+ $qudaoid = request('qudaoid');
+ $list = DB::table('s_list')
+ ->leftJoin('s_department_resources', 's_list.reservation_sources', '=', 's_department_resources.id')
+ ->select('s_list.*', 's_department_resources.department_resources_name')
+ ->where(['s_list.roster_id' => $planid, 's_list.is_del' => 0, 's_list.is_nullify' => 0])->whereIn('s_list.list_status', [1, 2, 3]);
+ if (!empty($qudaoid)) {
+ $list = $list->where(['s_list.appointment_type_id' => $qudaoid]);
+ }
+ $list = $list->get();
+ $qudao = DB::table('s_appointment_type')->get();
+ foreach ($list as $key => $item) {
+ foreach ($qudao as $q) {
+ if ($q->id == $item->appointment_type_id) {
+ $item->qudao_name = $q->name;
+ }
+ }
+
+ }
+ return \Yz::Return(true, '查询完成', $list);
+ }
+ public function TongJi()
+ {
+ $SearchInfo = request('SearchInfo');
+ $canshu=[];
+ $sql=' ';
+ if(!empty($SearchInfo['dateRange'])){
+ $canshu[] = $SearchInfo['dateRange'][0]; // 开始日期
+ $canshu[] = $SearchInfo['dateRange'][1]; // 结束日期
+ $sql.=" and a.date >= ? and a.date <= ?";
+ }
+ $planCount = DB::select("SELECT
+ aa.department_name,
+ sum(bb.count) as count,
+ sum(bb.used_count) as used_count
+FROM
+ (
+ SELECT
+ b.department_name,
+ a.*
+ FROM
+ s_source_roster_detail AS a
+ LEFT JOIN s_department AS b ON a.department_id = b.id
+ WHERE
+ a.is_del = 0 ".$sql."
+ ) AS aa
+ LEFT JOIN (
+ select roster_detail_id, sum(count) as count,sum(used_count) as used_count from s_source_roster_detail_count group by roster_detail_id
+ ) AS bb ON aa.id = bb.roster_detail_id group by aa.department_name",$canshu);
+
+ $allCount=0;
+ $allUsedCount=0;
+ foreach ($planCount as $key => $item) {
+ $allCount+=$item->count;
+ $allUsedCount+=$item->used_count;
+ $item->used_rate=number_format(($item->used_count/$item->count)*100,2).'%';
+ }
+ $planInfo=[
+ 'list'=>$planCount,
+ 'allCount'=>$allCount,
+ 'allUsedCount'=>$allUsedCount,
+
+ ];
+ return \Yz::Return(true, '查询完成', $planInfo);
+ }
+
+ // 保存占位数量
+ public function SaveLockedCount(Request $request)
+ {
+ $userid = $request->get('userid');
+ $roster_detail_id = request('roster_detail_id');
+ $locked_counts = request('locked_counts');
+
+ if (empty($roster_detail_id)) {
+ return \Yz::echoError1('计划明细ID不能为空');
+ }
+
+ if (empty($locked_counts) || !is_array($locked_counts)) {
+ return \Yz::echoError1('占位数量不能为空');
+ }
+
+ DB::beginTransaction();
+
+ try {
+ $changes = []; // 记录有变更的渠道
+
+ foreach ($locked_counts as $item) {
+ $appointment_type_id = $item['appointment_type_id'];
+ $locked_count = $item['locked_count'];
+
+ // 查询对应的记录
+ $countRecord = DB::table('s_source_roster_detail_count')
+ ->where([
+ 'roster_detail_id' => $roster_detail_id,
+ 'appointment_type_id' => $appointment_type_id
+ ])
+ ->first();
+
+ if (!$countRecord) {
+ DB::rollBack();
+ return \Yz::echoError1('未找到对应的渠道数量记录');
+ }
+
+ // 验证占位数量不能超过剩余可用数量
+ $remaining = $countRecord->count - $countRecord->used_count;
+ if ($locked_count > $remaining) {
+ DB::rollBack();
+ return \Yz::echoError1('占位数量不能大于剩余可用数量');
+ }
+
+ if ($locked_count < 0) {
+ DB::rollBack();
+ return \Yz::echoError1('占位数量不能为负数');
+ }
+
+ // 记录变更前的值
+ $old_locked_count = $countRecord->locked_count;
+
+ // 只有值有变化时才记录
+ if ($old_locked_count != $locked_count) {
+ $changes[] = [
+ 'appointment_type_id' => $appointment_type_id,
+ 'old_locked_count' => $old_locked_count,
+ 'new_locked_count' => $locked_count
+ ];
+
+ // 更新占位数量
+ DB::table('s_source_roster_detail_count')
+ ->where([
+ 'roster_detail_id' => $roster_detail_id,
+ 'appointment_type_id' => $appointment_type_id
+ ])
+ ->update([
+ 'locked_count' => $locked_count,
+ 'updated_at' => date('Y-m-d H:i:s')
+ ]);
+ }
+ }
+
+ // 有变更时记录日志
+ if (!empty($changes)) {
+ DB::table('s_source_roster_detail_log')->insert([
+ 'roster_detail_id' => $roster_detail_id,
+ 'type' => '修改占位数量',
+ 'content' => json_encode($changes, JSON_UNESCAPED_UNICODE),
+ 'userid' => $userid
+ ]);
+ }
+
+ DB::commit();
+ return \Yz::Return(true, '保存成功', []);
+
+ } catch (\Exception $e) {
+ DB::rollBack();
+ return \Yz::echoError1('保存失败:' . $e->getMessage());
+ }
+ }
+}
diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController.php
index b39a83a..482bbe1 100644
--- a/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController.php
+++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanListController.php
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\API\Admin\YeWu;
use App\Http\Controllers\Controller;
use App\Services\Admin\YeWu\PlanListService;
+use App\Services\Admin\YeWu\RosterService;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -13,7 +14,7 @@ use Tools;
class PlanListController extends Controller
{
//生成计划明细
- public function Create(Request $request)
+ public function Create(Request $request,RosterService $rosterService)
{
$userid = $request->get('userid');//中间件产生的参数
$userInfo = DB::table('users')->where(['id' => $userid])->get();
@@ -22,165 +23,22 @@ class PlanListController extends Controller
$planModelIds = request('ids');
$HolidayEnable = request('HolidayEnable');
$date_type = request('date_type');
- //循环日期和勾选的模板创建明细
- if (count($dateRange) == 2 && count($planModelIds) > 0) {
- $models = DB::table('s_source_roster')->whereIn('id', $planModelIds)->get();
- //检查是否有异常状态模板
- foreach ($models as $model) {
- if ($model->status != 1 || $model->is_del != 0) {
- return \Yz::echoError1('模板状态异常,请重新选择!异常模板Id:' . $model->id);
- }
- }
- $start_date = new DateTime($dateRange[0]);
- $end_date = new DateTime($dateRange[1]);
-
- //查询是否有重复插入
- $checkList = DB::table('s_source_roster_detail')
- ->where('department_id', $department_id)
- ->whereIn('roster_id', $planModelIds)
- ->where('date', '>=', $start_date->format('Y-m-d'))
- ->where('date', '<=', $end_date->format('Y-m-d'))
- ->where('is_del', 0)
- ->get();
- $msg = '当前选中的';
- $msglist = '';
- $msgIds = '';
- if (count($checkList) > 0) {
- foreach ($models as $model) {
- foreach ($checkList as $item) {
- if ($item->roster_id == $model->id) {
- $msglist .= $item->date . ' ';
- $msgIds .= $item->id . ' ';
- $msg .= " " . $model->weekname . $model->begin_time . '-' . $model->end_time . " ";
- }
- }
-
- }
- return \Yz::Return(false, '已有重复的计划明细,禁止创建!' . $msg . '已存在相同记录,存在于:' . $msglist . '对应记录Id为:' . $msgIds . '请先删除后再操作', $checkList);
- }
- //查询勾选的时间范围内所有的节假日
- $holiday_list=DB::table('s_holiday')->whereBetween('date',$dateRange)->where(['type'=>2])->pluck('date')->toArray();
-
- // 循环日期并判断星期
- $current_date = clone $start_date;
- DB::beginTransaction();
- $success_count = 0;//成功创建的数量
- while ($current_date <= $end_date) {
- //如果是节假日模板,则判断当前日期是否是节假日,不是则跳过
- if ($date_type == 2) {
- if (!in_array($current_date->format('Y-m-d'),$holiday_list)){
- // 将当前日期增加一天
- $current_date->modify('+1 day');
- continue;
- }
- }
- //如果选择节假日不可用,并且当前日期是节假日,则跳过
- if($HolidayEnable==0 and in_array($current_date->format('Y-m-d'),$holiday_list)){
- // 将当前日期增加一天
- $current_date->modify('+1 day');
- continue;
- }
-
- // 获取当前日期的星期几(0表示星期日,1表示星期一,以此类推)
- $weekday = $current_date->format('w');
- $weekname = '';
- switch ($weekday) {
- case 0:
- $weekname = '星期日';
- break;
- case 1:
- $weekname = '星期一';
- break;
- case 2:
- $weekname = '星期二';
- break;
- case 3:
- $weekname = '星期三';
- break;
- case 4:
- $weekname = '星期四';
- break;
- case 5:
- $weekname = '星期五';
- break;
- case 6:
- $weekname = '星期六';
- break;
- }
- foreach ($models as $model) {
- if ($date_type == 1 and $model->date_type==1) {
- if ($model->weekname <> $weekname) continue;
- }
-
- // 插入明细表
- $data = [
- 'roster_id' => $model->id,
- 'date' => $current_date,
- 'weekname' => $weekname,
- 'department_id' => $model->department_id,
- 'resources_id' => $model->resources_id,
- 'device_id' => $model->device_id,
- 'period_id' => $model->period_id,
- 'patient_type' => $model->patient_type,
- 'begin_time' => $model->begin_time,
- 'end_time' => $model->end_time,
- 'end_reservation_time' => $model->end_reservation_time,
- 'time_unit' => $model->time_unit,
- 'status' => 1,
- 'adduser' => $userid,
- 'is_del' => 0,
- ];
-
-
- $plan_id = DB::table('s_source_roster_detail')->insertGetId($data);
- if ($plan_id) {
- $success_count++;
- }
- // 插入数量表
- $model_count_info = DB::table('s_source_roster_count')->where(['roster_id' => $model->id])->get();
- if (count($model_count_info) > 0) {
- foreach ($model_count_info as $info) {
- $i_c = DB::table('s_source_roster_detail_count')->insert([
- 'roster_detail_id' => $plan_id,
- 'appointment_type_id' => $info->appointment_type_id,
- 'count' => $info->count,
- 'max_total' => $info->max_total,
- ]);
- if (!$i_c) {
- DB::rollBack();
- return \Yz::echoError1('渠道数量创建失败');
- }
- }
- } else {
- DB::rollBack();
- return \Yz::echoError1('模板数量信息异常,请重新选择!异常模板Id:' . $model->id);
- }
- if (isset($model->device_id)) {
- $device_ids = explode(",", $model->device_id);
- foreach ($device_ids as $dv_key => $dv_value) {
- $i_dev = DB::table('s_source_roster_detail_device')->insert([
- 'roster_detail_id' => $plan_id,
- 'device_id' => $dv_value,
- ]);
- if (!$i_dev) {
- DB::rollBack();
- return \Yz::echoError1('设备关联创建失败');
- }
- }
-
- } else {
- DB::rollBack();
- return \Yz::echoError1('模板未关联设备,请重新选择!异常模板Id:' . $model->id);
- }
+ try {
+ // 调用服务层
+ $result = $rosterService->generatePlans(
+ $dateRange,
+ $planModelIds,
+ $userid,
+ $date_type,
+ $HolidayEnable
+ );
- }
- // 将当前日期增加一天
- $current_date->modify('+1 day');
+ return \Yz::Return(true, '执行完成,共计生成计划 ' . $result['count'] . ' 条', $result);
- }
- DB::commit();
- return \Yz::Return(true, '执行完成,范围:' . $dateRange[0] . '-' . $dateRange[1] . ',共计生成计划 ' . $success_count . ' 条', ['dateRange' => $dateRange, 'success_count' => $success_count]);
+ } catch (\Exception $e) {
+ // 捕获服务层抛出的异常,格式化返回给前端
+ return \Yz::echoError1($e->getMessage());
}
}
diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanModelController.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanModelController.php
index f488dc0..e15a085 100644
--- a/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanModelController.php
+++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/PlanModelController.php
@@ -10,70 +10,140 @@ class PlanModelController extends Controller
{
public function GetList(Request $request)
{
- $userid = $request->get('userid');//中间件产生的参数
- $group = $request->get('role');//中间件产生的参数
+ $userid = $request->get('userid');
+ $group = $request->get('role');
$searchInfo = request('searchInfo');
$page = request('page');
$pageSize = request('pageSize');
- $searchInfo['date_type']=$searchInfo['date_type']?$searchInfo['date_type']:1;
+
+ $searchInfo['date_type'] = $searchInfo['date_type'] ?? 1;
+
$department_id = 0;
- $list = DB::table('s_source_roster')
+
+ // 1. 确定 department_id
+ if ($group == 1) {
+ if (!empty($searchInfo['department_id'])) {
+ $department_id = $searchInfo['department_id'];
+ }
+ } else {
+ $userInfo = DB::table('users')->where(['id' => $userid])->get();
+ if ($userInfo->isNotEmpty()) {
+ $department_id = $userInfo[0]->department_id;
+ }
+ }
+
+ // 2. 构建主查询
+ // 注意:这里必须保留 leftJoin 's_department_resources',因为我们需要用它里面的 time_mode 字段做条件判断
+ $listQuery = DB::table('s_source_roster')
->leftJoin('s_department_resources', 's_source_roster.resources_id', '=', 's_department_resources.id')
- // ->leftJoin('s_devices', 's_source_roster.device_id', '=', 's_devices.id')
->leftJoin('s_period', 's_source_roster.period_id', '=', 's_period.id')
- ->select('s_source_roster.*', 's_department_resources.department_resources_name', 's_period.period_name')
- ->where(['s_source_roster.is_del' => 0,'s_source_roster.date_type' => $searchInfo['date_type']]);
- if ($group == 1) {//如果是管理员
- if (!empty($searchInfo['department_id'])) {
- $list = $list->where('s_source_roster.department_id', $searchInfo['department_id']);
+ ->select(
+ 's_source_roster.*',
+ 's_department_resources.department_resources_name',
+ 's_department_resources.time_mode',
+ 's_department_resources.time_range',
+ 's_period.period_name'
+ )
+ ->where([
+ 's_source_roster.is_del' => 0,
+ 's_source_roster.date_type' => $searchInfo['date_type']
+ ]);
+
+ // 限制科室 ID (如果 department_id 为 0,通常意味着没权限或无数据,可根据业务决定是否跳过此 where)
+ if ($department_id > 0) {
+ $listQuery->where('s_source_roster.department_id', $department_id);
+ } else {
+ // 如果 department_id 为 0 且不是管理员模式,可能查不到数据,这里保持原逻辑或直接返回空
+ // 如果业务允许查全库,可注释掉上面的 if,但通常这里有权限控制
+ if ($group != 1) {
+ return \Yz::Return(true, '操作成功', ['list' => [], 'count' => 0]);
}
+ }
+
+ if ($searchInfo['date_type'] == 2) {
+ // 规则 A: date_type = 2 时,无论 time_mode 是多少,强制只查 type = 0
+ $listQuery->where('s_source_roster.type', 0);
} else {
- $userInfo = DB::table('users')->where(['id' => $userid])->get();
- $department_id = $userInfo[0]->department_id;
- $list = $list->where(['s_source_roster.department_id' => $department_id]);
+ // 规则 B: date_type != 2 (例如 1) 时,根据 time_mode 动态匹配
+ $listQuery->where(function ($query) {
+ // 情况 1: time_mode = 1 -> 允许 type 1 或 2
+ $query->where(function ($sub) {
+ $sub->where('s_department_resources.time_mode', 1)
+ ->whereIn('s_source_roster.type', [1, 2]);
+ })
+ // 情况 2: time_mode = 0 -> 只允许 type 0
+ ->orWhere(function ($sub) {
+ $sub->where('s_department_resources.time_mode', 0)
+ ->where('s_source_roster.type', 0);
+ });
+
+ // 可选:如果 time_mode 为 NULL (资源未关联到),是否要显示?
+ // 通常如果不匹配任何规则则不显示,上述逻辑已自然过滤掉 NULL 情况。
+ // 如果需要显示未关联资源的 type=0 数据,可以追加:
+ // ->orWhere(function($sub) { $sub->whereNull('s_department_resources.time_mode')->where('s_source_roster.type', 0); })
+ });
}
+
+ // 4. 其他筛选条件
if (!empty($searchInfo['resources_id'])) {
- $list = $list->where('s_source_roster.resources_id', $searchInfo['resources_id']);
+ $listQuery = $listQuery->where('s_source_roster.resources_id', $searchInfo['resources_id']);
+ }
+ if (isset($searchInfo['type'])) {
+ $listQuery = $listQuery->where('s_source_roster.type', $searchInfo['type']);
}
+
if (!empty($searchInfo['device_id'])) {
- //$list = $list->where('s_source_roster.device_id', 'like','%,'.$searchInfo['device_id'].',%' );
- $list = $list->whereRaw("FIND_IN_SET({$searchInfo['device_id']}, s_source_roster.device_id)");
+ // 修复 SQL 注入风险,使用参数绑定
+ $listQuery = $listQuery->whereRaw("FIND_IN_SET(?, s_source_roster.device_id)", [$searchInfo['device_id']]);
}
+
if (!empty($searchInfo['xingqi'])) {
- $list = $list->where('s_source_roster.weekname', $searchInfo['xingqi']);
+ $listQuery = $listQuery->where('s_source_roster.weekname', $searchInfo['xingqi']);
}
- if (isset($searchInfo['status'])) {
- $list = $list->where('s_source_roster.status', $searchInfo['status']);
+ if (isset($searchInfo['status'])) {
+ $listQuery = $listQuery->where('s_source_roster.status', $searchInfo['status']);
}
- $count = $list;
- $count = $count->count();
- //按诊室排序
- $list = $list->orderBy('s_source_roster.resources_id');
- //按星期排序
- $list=$list->orderByRaw(DB::raw(
- "FIELD(`weekname`, '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日') ASC"
- ));
+ // 5. 统计总数
+ $count = $listQuery->count();
+
+ // 6. 排序
+ $listQuery = $listQuery->orderBy('s_source_roster.resources_id');
+ $listQuery = $listQuery->orderByRaw("FIELD(`weekname`, '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日') ASC");
+ $listQuery = $listQuery->orderBy('s_source_roster.begin_time');
+
+ // 7. 获取数据
+ //dd($listQuery->toSql());
+ $list = $listQuery->get();
+
- $list = $list->orderBy('s_source_roster.begin_time')->get();
$ids = [];
foreach ($list as $key => $value) {
- $patient_arr = explode(',', $value->patient_type);
- $p_type=config('app.globals.患者类型');
+ // 处理患者类型标签
+ $patient_arr = explode(',', $value->patient_type ?? '');
+ $p_type = config('app.globals.患者类型');
$type_label = array_map(function($key) use ($p_type) {
- return $p_type[$key] ?? null; // 如果 key 不存在,返回 null
+ return $p_type[$key] ?? null;
}, $patient_arr);
$list[$key]->patient_type_label = $type_label;
+
$list[$key]->countsInfo = [];
$ids[] = $value->id;
+
+ $list[$key]->time_range = json_decode($value->time_range ?? '[]', true);
+ }
+
+ // 9. 匹配渠道数量
+ $countsInfo = [];
+ if (!empty($ids)) {
+ $countsInfo = DB::table('s_source_roster_count')
+ ->leftJoin('s_appointment_type', 's_source_roster_count.appointment_type_id', '=', 's_appointment_type.id')
+ ->select('s_source_roster_count.*', 's_appointment_type.name', 's_appointment_type.jiancheng')
+ ->whereIn('roster_id', $ids)
+ ->get();
}
- //匹配渠道数量
- $countsInfo = DB::table('s_source_roster_count')
- ->leftJoin('s_appointment_type', 's_source_roster_count.appointment_type_id', '=', 's_appointment_type.id')
- ->select('s_source_roster_count.*', 's_appointment_type.name','s_appointment_type.jiancheng')
- ->whereIn('roster_id', $ids)->get();
if (count($countsInfo) > 0) {
foreach ($list as $key => $value) {
@@ -84,14 +154,19 @@ class PlanModelController extends Controller
}
}
}
- //匹配设备(服务组)
- $devices = DB::table('s_devices')->get();
+
+ // 10. 匹配设备(服务组)
+ $allDevices = DB::table('s_devices')->get()->keyBy('id');
+
foreach ($list as $key => $value) {
$list[$key]->devices = [];
- $array_device_id = explode(",", $value->device_id);
- foreach ($devices as $k => $v) {
- if (in_array($v->id, $array_device_id)) {
- $list[$key]->devices[] = $v;
+ if (!empty($value->device_id)) {
+ $array_device_id = explode(",", $value->device_id);
+ foreach ($array_device_id as $devId) {
+ $devId = trim($devId);
+ if (isset($allDevices[$devId])) {
+ $list[$key]->devices[] = $allDevices[$devId];
+ }
}
}
}
diff --git a/Laravel/app/Services/Admin/YeWu/RosterService.php b/Laravel/app/Services/Admin/YeWu/RosterService.php
new file mode 100644
index 0000000..8315df8
--- /dev/null
+++ b/Laravel/app/Services/Admin/YeWu/RosterService.php
@@ -0,0 +1,258 @@
+whereIn('id', $planModelIds)
+ ->get();
+
+ if ($models->isEmpty()) {
+ throw new Exception('未找到有效的排班模板');
+ }
+
+ foreach ($models as $model) {
+ if ($model->status != 1 || $model->is_del != 0) {
+ throw new Exception("模板状态异常,请重新选择!异常模板Id: {$model->id}");
+ }
+ }
+
+ // 获取部门ID (用于查重,取第一个模板的部门ID,假设批量操作通常针对同一部门)
+ // 如果业务允许跨部门混合勾选,这里可能需要调整查重逻辑(按部门分组查)
+ $department_id = $models->first()->department_id;
+
+ $start_date = new DateTime($dateRange[0]);
+ $end_date = new DateTime($dateRange[1]);
+
+ // ==========================================
+ // 【核心】3. 重复性检测 (在事务外执行,提高性能)
+ // ==========================================
+ $this->checkDuplicateRecords(
+ $department_id,
+ $planModelIds,
+ $start_date,
+ $end_date,
+ $models
+ );
+ // 如果上面没抛异常,说明没有重复,继续往下执行
+
+ // 4. 获取节假日列表
+ $holiday_list = DB::table('s_holiday')
+ ->whereBetween('date', $dateRange)
+ ->where(['type' => 2])
+ ->pluck('date')
+ ->toArray();
+
+ $success_count = 0;
+
+ // 5. 开启事务
+ DB::beginTransaction();
+ try {
+ $current_date = clone $start_date;
+
+ while ($current_date <= $end_date) {
+ $current_date_str = $current_date->format('Y-m-d');
+
+ // --- 逻辑判断:节假日过滤 ---
+
+ // 如果是“仅节假日”模式 (date_type == 2),且当天不是节假日 -> 跳过
+ if ($dateType == 2 && !in_array($current_date_str, $holiday_list)) {
+ $current_date->modify('+1 day');
+ continue;
+ }
+
+ // 如果“节假日不可用” (HolidayEnable == 0),且当天是节假日 -> 跳过
+ if ($holidayEnable == 0 && in_array($current_date_str, $holiday_list)) {
+ $current_date->modify('+1 day');
+ continue;
+ }
+
+ // --- 获取星期 ---
+ $weekday = (int)$current_date->format('w');
+ $weekname = $this->getWeekName($weekday);
+
+ foreach ($models as $model) {
+ // --- 逻辑判断:星期匹配 ---
+ // 如果是“按星期”模式 (date_type == 1) 且模板也是按星期定义的,必须星期一致
+ if ($dateType == 1 && isset($model->date_type) && $model->date_type == 1) {
+ if ($model->weekname !== $weekname) {
+ continue;
+ }
+ }
+
+ // --- 构造插入数据 ---
+ $data = [
+ 'roster_id' => $model->id,
+ 'date' => $current_date_str,
+ 'weekname' => $weekname,
+ 'department_id' => $model->department_id,
+ 'resources_id' => $model->resources_id ?? null,
+ 'device_id' => $model->device_id ?? null,
+ 'period_id' => $model->period_id ?? null,
+ 'patient_type' => $model->patient_type ?? null,
+ 'begin_time' => $model->begin_time,
+ 'end_time' => $model->end_time,
+ 'end_reservation_time' => $model->end_reservation_time ?? null,
+ 'time_unit' => $model->time_unit ?? null,
+ 'status' => 1,
+ 'adduser' => $userId,
+ 'is_del' => 0,
+ 'created_at' => date('Y-m-d H:i:s'),
+ 'updated_at' => date('Y-m-d H:i:s'),
+ ];
+
+ // --- 插入主表 ---
+ $plan_id = DB::table('s_source_roster_detail')->insertGetId($data);
+
+ if (!$plan_id) {
+ throw new Exception("号源明细插入失败,日期:{$current_date_str}, 模板ID:{$model->id}");
+ }
+ $success_count++;
+
+ // --- 插入关联表:数量配置 ---
+ $this->insertCountInfo($plan_id, $model->id);
+
+ // --- 插入关联表:设备配置 ---
+ // 注意:原逻辑如果 device_id 为空会报错,这里保持原逻辑
+ $this->insertDeviceInfo($plan_id, $model->device_id, $model->id);
+ }
+
+ $current_date->modify('+1 day');
+ }
+
+ // 6. 提交事务
+ DB::commit();
+
+ return ['success' => true, 'count' => $success_count];
+
+ } catch (Exception $e) {
+ // 7. 异常回滚
+ DB::rollBack();
+ // 记录日志
+ Log::error('Roster Generation Failed: ' . $e->getMessage(), [
+ 'dateRange' => $dateRange,
+ 'user_id' => $userId
+ ]);
+ // 重新抛出,让 Controller 处理
+ throw $e;
+ }
+ }
+
+ /**
+ * 独立的重复检测方法
+ * 如果发现重复,直接抛出包含详细信息的异常
+ */
+ private function checkDuplicateRecords($department_id, $planModelIds, $startDate, $endDate, $models)
+ {
+ $startStr = $startDate->format('Y-m-d');
+ $endStr = $endDate->format('Y-m-d');
+
+ // 查询已存在的记录
+ $checkList = DB::table('s_source_roster_detail')
+ ->where('department_id', $department_id)
+ ->whereIn('roster_id', $planModelIds)
+ ->where('date', '>=', $startStr)
+ ->where('date', '<=', $endStr)
+ ->where('is_del', 0)
+ ->get();
+
+ if ($checkList->isNotEmpty()) {
+ // 构造详细的错误提示信息 (完全还原你原代码的逻辑)
+ $msg = '已有重复的计划明细,禁止创建!当前选中的';
+ $msglist = '';
+ $msgIds = '';
+
+ // 优化:将检查结果转为映射数组,避免双重循环 O(N*M)
+ // key: roster_id, value: array of items
+ $checkMap = [];
+ foreach ($checkList as $item) {
+ if (!isset($checkMap[$item->roster_id])) {
+ $checkMap[$item->roster_id] = [];
+ }
+ $checkMap[$item->roster_id][] = $item;
+ }
+
+ foreach ($models as $model) {
+ if (isset($checkMap[$model->id])) {
+ foreach ($checkMap[$model->id] as $item) {
+ $msglist .= $item->date . ' ';
+ $msgIds .= $item->id . ' ';
+ // 拼接模板信息
+ $msg .= " " . $model->weekname . $model->begin_time . '-' . $model->end_time . " ";
+ }
+ }
+ }
+
+ $fullErrorMessage = $msg . '已存在相同记录,存在于:' . $msglist . '对应记录Id为:' . $msgIds . '请先删除后再操作';
+
+ // 抛出异常,中断流程
+ throw new Exception($fullErrorMessage);
+ }
+ }
+
+ private function getWeekName($weekday) {
+ $map = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
+ return $map[$weekday] ?? '';
+ }
+
+ private function insertCountInfo($detailId, $rosterId) {
+ $model_count_info = DB::table('s_source_roster_count')->where(['roster_id' => $rosterId])->get();
+
+ if ($model_count_info->isEmpty()) {
+ throw new Exception("模板数量信息异常,请重新选择!异常模板Id: {$rosterId}");
+ }
+
+ foreach ($model_count_info as $info) {
+ $success = DB::table('s_source_roster_detail_count')->insert([
+ 'roster_detail_id' => $detailId,
+ 'appointment_type_id' => $info->appointment_type_id,
+ 'count' => $info->count,
+ 'max_total' => $info->max_total,
+ 'created_at' => date('Y-m-d H:i:s'),
+ 'updated_at' => date('Y-m-d H:i:s'),
+ ]);
+ if (!$success) {
+ throw new Exception("渠道数量创建失败");
+ }
+ }
+ }
+
+ private function insertDeviceInfo($detailId, $deviceIdStr, $modelId) {
+ // 保持原逻辑:如果模板没配设备,视为异常
+ if (empty($deviceIdStr)) {
+ throw new Exception("模板未关联设备,请重新选择!异常模板Id: {$modelId}");
+ }
+
+ $device_ids = explode(",", $deviceIdStr);
+ foreach ($device_ids as $dv_value) {
+ $dv_value = trim($dv_value);
+ if ($dv_value === '') continue;
+
+ $success = DB::table('s_source_roster_detail_device')->insert([
+ 'roster_detail_id' => $detailId,
+ 'device_id' => $dv_value,
+ 'created_at' => date('Y-m-d H:i:s'),
+ 'updated_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ if (!$success) {
+ throw new Exception("设备关联创建失败");
+ }
+ }
+ }
+}
diff --git a/YiJi-admin/src/views/AppointmentMngr/PlanModel.vue b/YiJi-admin/src/views/AppointmentMngr/PlanModel.vue
index b1a1e58..eb8718c 100644
--- a/YiJi-admin/src/views/AppointmentMngr/PlanModel.vue
+++ b/YiJi-admin/src/views/AppointmentMngr/PlanModel.vue
@@ -48,11 +48,15 @@