diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/CheckItemController.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/CheckItemController.php index c74ce3a..78f8b71 100644 --- a/Laravel/app/Http/Controllers/API/Admin/YeWu/CheckItemController.php +++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/CheckItemController.php @@ -151,4 +151,21 @@ WHERE return \Yz::Return(true, '操作成功', $q); } + + public function GetRules() + { + $item_id = request('item_id'); + if (!$item_id) return \Yz::echoError1('item_id不能为空'); + $s = new CheckItemService; + return $s->GetRules($item_id); + } + + public function SaveRules() + { + $item_id = request('item_id'); + $rules = request('rules'); + if (!$item_id) return \Yz::echoError1('item_id不能为空'); + $s = new CheckItemService; + return $s->SaveRules($item_id, $rules); + } } diff --git a/Laravel/app/Services/Admin/YeWu/CheckItemService.php b/Laravel/app/Services/Admin/YeWu/CheckItemService.php index bd8771e..9fc78d7 100644 --- a/Laravel/app/Services/Admin/YeWu/CheckItemService.php +++ b/Laravel/app/Services/Admin/YeWu/CheckItemService.php @@ -93,4 +93,52 @@ class CheckItemService return \Yz::Return(false, 'id不能为空'); } } + + public function GetRules($item_id) + { + $rules = DB::table('s_check_item_rule') + ->where(['target_type' => 'ITEM', 'target_id' => $item_id, 'deleted' => 0, 'status' => 1]) + ->get(); + foreach ($rules as $rule) { + $rule->rule_value = json_decode($rule->rule_value, true); + } + return \Yz::Return(true, '查询成功', $rules); + } + + public function SaveRules($item_id, $rules) + { + DB::beginTransaction(); + try { + DB::table('s_check_item_rule') + ->where(['target_type' => 'ITEM', 'target_id' => $item_id]) + ->delete(); + + if (!empty($rules)) { + $insertData = []; + foreach ($rules as $rule) { + $rule_value = $rule['rule_value']; + if (is_array($rule_value)) { + $rule_value = json_encode($rule_value, JSON_UNESCAPED_UNICODE); + } + $insertData[] = [ + 'target_type' => 'ITEM', + 'target_id' => $item_id, + 'rule_type' => $rule['rule_type'], + 'rule_value' => $rule_value, + 'status' => 1, + 'deleted' => 0, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + ]; + } + DB::table('s_check_item_rule')->insert($insertData); + } + + DB::commit(); + return \Yz::Return(true, '保存成功'); + } catch (\Exception $e) { + DB::rollBack(); + return \Yz::Return(false, '保存失败:' . $e->getMessage()); + } + } } diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php index 730cb0c..c598003 100644 --- a/Laravel/app/Services/Admin/YeWu/PlanListService.php +++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php @@ -21,6 +21,7 @@ class PlanListService $allDevice = [];//所有医嘱检查项目绑定的设备id $commPatientType = [];//所有医嘱共同的病人类型 $zhanweiCount=0;//勾选的检查项目共计占多少名额 + $allItemRules = [];//所有检查项目的TIME_RESTRICTION规则 foreach ($entrustids as $key => $entrustid) { // $info = DB::table('s_list')->where(['reg_num' => $regnum, 'entrust_id' => $entrustid, 'episodeid' => $episodeid, 'is_nullify' => 0])->first(); $info = DB::table('s_list')->where(['entrust_id' => $entrustid, 'is_nullify' => 0])->first(); @@ -38,7 +39,16 @@ class PlanListService //只判断主渠道,如果主渠道支持,则子渠道默认也支持,即使项目没绑定子渠道 if (!in_array($appointment_type, $qudaos)) return \Yz::echoError1('此检查项目不支持在当前渠道预约'); - + $itemRules = DB::table('s_check_item_rule') + ->where(['target_type' => 'ITEM', 'target_id' => $itemInfo->id, 'rule_type' => 'TIME_RESTRICTION', 'status' => 1, 'deleted' => 0]) + ->get(); + if ($itemRules->isNotEmpty()) { + $itemRulesArray = []; + foreach ($itemRules as $r) { + $itemRulesArray[] = json_decode($r->rule_value, true); + } + $allItemRules[$itemInfo->id] = $itemRulesArray; + } //获取检查项目绑定的服务组(设备),判断状态正常的 $devices = DB::table('s_check_item_device') @@ -155,6 +165,15 @@ WHERE if (!empty(array_diff($commPatientType, $planPatientType))) { continue; } + + //检查项目时段规则过滤 + if (!empty($allItemRules)) { + $rulePass = $this->checkPlanAgainstRules($p, $allItemRules); + if (!$rulePass) { + continue; + } + } + //过期的排在后面 $time = $p->date . ' ' . $p->end_time; if ($time > $nowtime) { @@ -319,6 +338,37 @@ WHERE } } + //校验检查项目时段规则 + $itemRules = DB::table('s_check_item_rule') + ->where(['target_type' => 'ITEM', 'target_id' => $item->id, 'rule_type' => 'TIME_RESTRICTION', 'status' => 1, 'deleted' => 0]) + ->get(); + if ($itemRules->isNotEmpty()) { + $planWeekName = $planInfo->weekname; + $planBeginTime = $planInfo->begin_time; + $rulePass = false; + foreach ($itemRules as $rule) { + $rv = json_decode($rule->rule_value, true); + $days = $rv['days'] ?? []; + $startTime = $rv['start_time'] ?? null; + $endTime = $rv['end_time'] ?? null; + + if (!in_array($planWeekName, $days)) continue; + + if ($startTime && $endTime && $planBeginTime) { + if ($planBeginTime >= $startTime && $planBeginTime < $endTime) { + $rulePass = true; + break; + } + } else { + $rulePass = true; + break; + } + } + if (!$rulePass) { + return \Yz::echoError1($item->item_name . ' 当前时段不在可预约时间范围内'); + } + } + } DB::beginTransaction(); @@ -867,6 +917,36 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null) } } + //判断号源是否满足所有检查项目的时段规则 + private function checkPlanAgainstRules($plan, $allItemRules) + { + $planWeekName = $plan->weekname; + $planBeginTime = $plan->begin_time; + + foreach ($allItemRules as $itemId => $rules) { + $itemPass = false; + foreach ($rules as $rule) { + $days = $rule['days'] ?? []; + $startTime = $rule['start_time'] ?? null; + $endTime = $rule['end_time'] ?? null; + + if (!in_array($planWeekName, $days)) continue; + + if ($startTime && $endTime && $planBeginTime) { + if ($planBeginTime >= $startTime && $planBeginTime < $endTime) { + $itemPass = true; + break; + } + } else { + $itemPass = true; + break; + } + } + if (!$itemPass) return false; + } + return true; + } + //判断是否在互斥组内 function isMutuallyExclusive($ids, $huchi) { foreach ($huchi as $pair) { diff --git a/Laravel/routes/api.php b/Laravel/routes/api.php index 24a34c6..f6d5fd4 100644 --- a/Laravel/routes/api.php +++ b/Laravel/routes/api.php @@ -97,6 +97,8 @@ Route::group(['middleware'=>['checktoken','log'],'prefix'=>'v1'],function () { Route::post('admin/DelHuChi','App\Http\Controllers\API\Admin\YeWu\CheckItemController@DelHuChi');//删除互斥 Route::post('admin/CheckEntrstItemGroup','App\Http\Controllers\API\Admin\YeWu\WorkMainController@CheckEntrstItemGroup');//批量检查医嘱检查项目是否可以同时预约 Route::post('admin/GetHuChiList','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetHuChiList');//获取某个项目已经设置的互斥列表 + Route::post('admin/GetCheckItemRules','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetRules');//获取检查项目规则 + Route::post('admin/SaveCheckItemRules','App\Http\Controllers\API\Admin\YeWu\CheckItemController@SaveRules');//保存检查项目规则 Route::post('admin/InpatientWardGetList','App\Http\Controllers\API\Admin\YeWu\InpatientWardController@GetList');//获取病区列表 Route::post('admin/InpatientWardSave','App\Http\Controllers\API\Admin\YeWu\InpatientWardController@Save');//保存病区 Route::post('admin/InpatientWardDel','App\Http\Controllers\API\Admin\YeWu\InpatientWardController@Del');//删除病区 diff --git a/YiJi-admin/src/api/api.js b/YiJi-admin/src/api/api.js index bb6107e..a959c5c 100644 --- a/YiJi-admin/src/api/api.js +++ b/YiJi-admin/src/api/api.js @@ -277,6 +277,12 @@ export const DelHuChi = (data = {}) => { export const GetHuChiList = (data = {}) => { return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetHuChiList', data: data }) } +export const GetCheckItemRules = (data = {}) => { + return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetCheckItemRules', data: data }) +} +export const SaveCheckItemRules = (data = {}) => { + return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/SaveCheckItemRules', data: data }) +} //重置密码 export const resetPwd = (data = {}) => { return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/resetPwd', data: data }) diff --git a/YiJi-admin/src/components/Yewu/YuYue202506.vue b/YiJi-admin/src/components/Yewu/YuYue202506.vue index 515591f..560ecbc 100644 --- a/YiJi-admin/src/components/Yewu/YuYue202506.vue +++ b/YiJi-admin/src/components/Yewu/YuYue202506.vue @@ -13,6 +13,7 @@ 获取患者信息失败
+ @@ -216,6 +217,12 @@ const canEmergency = computed(() => { //是否有紧急权限 return props.special_privileges.includes('emergency'); }); + const hasDifferentBookedDates = computed(() => { + const booked = entrustTableDate.value.filter(v => v.list_status === 1 && v.reservation_date); + if (booked.length < 2) return false; + const dates = new Set(booked.map(v => v.reservation_date)); + return dates.size > 1; + }); const handleSelectionChange = (selection) => { selectedMianListId.value = [] selectedEntrustId.value = [] diff --git a/YiJi-admin/src/views/YeWu/CheckItemConfig.vue b/YiJi-admin/src/views/YeWu/CheckItemConfig.vue index 913e305..9797733 100644 --- a/YiJi-admin/src/views/YeWu/CheckItemConfig.vue +++ b/YiJi-admin/src/views/YeWu/CheckItemConfig.vue @@ -53,10 +53,11 @@ 关联服务组 - + @@ -215,6 +216,42 @@
+ +
+ 添加规则 + 无规则表示不限制预约时段 +
+
+
+ 规则 {{ index + 1 }} + 删除 +
+
+ 允许星期 + + + +
+
+ 允许时段 + + ~ + +
+
+
+ 暂未设置时段限制 +
+ +
@@ -234,7 +271,9 @@ DelHuChi, GetHuChiList, UpdateHisItemClass, - updateHisCheckItem + updateHisCheckItem, + GetCheckItemRules, + SaveCheckItemRules } from '@/api/api.js' import { ElMessage, @@ -635,6 +674,70 @@ }) }) } + let RuleDialogVisible = ref(false); + let RuleLoading = ref(false); + let RuleItemInfo = ref({ id: null, item_name: '' }); + let RuleList = ref([]); + const weekOptions = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']; + + const OpenRuleDialog = (row) => { + RuleItemInfo.value = { id: row.id, item_name: row.item_name }; + RuleDialogVisible.value = true; + RuleLoading.value = true; + GetCheckItemRules({ item_id: row.id }).then(res => { + RuleLoading.value = false; + if (res.status) { + RuleList.value = (res.data || []).map(r => ({ + days: r.rule_value.days || [], + start_time: r.rule_value.start_time || '', + end_time: r.rule_value.end_time || '' + })); + } else { + ElMessage.error(res.msg); + } + }); + }; + + const AddRuleRow = () => { + RuleList.value.push({ days: [], start_time: '', end_time: '' }); + }; + + const RemoveRuleRow = (index) => { + RuleList.value.splice(index, 1); + }; + + const SaveRulesFunc = () => { + for (let i = 0; i < RuleList.value.length; i++) { + const rule = RuleList.value[i]; + if (rule.days.length === 0) { + ElMessage.error('规则 ' + (i + 1) + ' 至少选择一个星期'); + return; + } + if (!rule.start_time || !rule.end_time) { + ElMessage.error('规则 ' + (i + 1) + ' 请设置完整的时间段'); + return; + } + } + const rules = RuleList.value.map(rule => ({ + rule_type: 'TIME_RESTRICTION', + rule_value: { + days: rule.days, + start_time: rule.start_time, + end_time: rule.end_time + } + })); + RuleLoading.value = true; + SaveCheckItemRules({ item_id: RuleItemInfo.value.id, rules: rules }).then(res => { + RuleLoading.value = false; + if (res.status) { + ElMessage.success('保存成功'); + RuleDialogVisible.value = false; + } else { + ElMessage.error(res.msg); + } + }); + }; + onMounted(() => { GetItemClassList() GetDeviceList() diff --git a/data.sql b/data.sql index 7485417..6b5f3b4 100644 --- a/data.sql +++ b/data.sql @@ -11,7 +11,7 @@ Target Server Version : 50726 File Encoding : 65001 - Date: 03/04/2026 21:19:56 + Date: 13/04/2026 21:44:32 */ SET NAMES utf8mb4; @@ -116,7 +116,7 @@ CREATE TABLE `s_appointment_type` ( `is_del` int(4) NULL DEFAULT NULL COMMENT '是否删除0否1删除', `status` int(4) NULL DEFAULT NULL COMMENT '0关闭1正常', PRIMARY KEY (`id`) USING BTREE -) ENGINE = MyISAM AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '预约方式' ROW_FORMAT = Dynamic; +) ENGINE = MyISAM AUTO_INCREMENT = 10000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '预约方式' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for s_appointment_type_ratio @@ -186,6 +186,23 @@ CREATE TABLE `s_check_item_device` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '科室-资源-服务组对应表' ROW_FORMAT = Dynamic; +-- ---------------------------- +-- Table structure for s_check_item_rule +-- ---------------------------- +DROP TABLE IF EXISTS `s_check_item_rule`; +CREATE TABLE `s_check_item_rule` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `target_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规则目标类型 ITEM/GROUP', + `target_id` bigint(20) NULL DEFAULT NULL COMMENT '目标id,项目id或组id', + `rule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规则类型', + `rule_value` json NULL COMMENT '规则值(结构化存储)', + `status` tinyint(4) NULL DEFAULT 1 COMMENT '0停用1启用', + `deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '逻辑删除:1-删除 0-未删', + `created_at` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `updated_at` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '检查项目规则表' ROW_FORMAT = Dynamic; + -- ---------------------------- -- Table structure for s_department -- ---------------------------- @@ -413,7 +430,7 @@ CREATE TABLE `s_list_log` ( `created_at` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0), `updated_at` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 699 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '医嘱日志表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 724 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '医嘱日志表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for s_list1111 @@ -599,7 +616,7 @@ CREATE TABLE `s_source_roster_detail` ( INDEX `department`(`department_id`) USING BTREE COMMENT '科室id索引', INDEX `resourece`(`resources_id`) USING BTREE COMMENT '资源id索引', INDEX `services`(`device_id`) USING BTREE COMMENT '服务组id索引' -) ENGINE = InnoDB AUTO_INCREMENT = 589 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '资源计划预约详情' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 677 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '资源计划预约详情' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for s_source_roster_detail_count @@ -617,7 +634,7 @@ CREATE TABLE `s_source_roster_detail_count` ( `created_at` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0), `updated_at` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2491 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '预约计划详情对应的各个渠道数量和已经预约数量' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 2931 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '预约计划详情对应的各个渠道数量和已经预约数量' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for s_source_roster_detail_device @@ -630,7 +647,7 @@ CREATE TABLE `s_source_roster_detail_device` ( `created_at` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0), `updated_at` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 589 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '计划明细关联设备表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 677 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '计划明细关联设备表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for s_source_roster_detail_log