diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php
index aa1506f..922c6b7 100644
--- a/Laravel/app/Services/Admin/YeWu/PlanListService.php
+++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php
@@ -434,6 +434,21 @@ public function GetOptimalPlan($type, $regnum, $entrustids, $episodeid, $appoint
$endDate = new DateTime();
$endDate->modify('+' . $dateRange . ' day');
+ // 批量查询每个检查项目的 use_seats
+ $entrustIds = array_column($items, 'entrust_id');
+ $useSeatsMap = [];
+ if (!empty($entrustIds)) {
+ $useSeatsMap = DB::table('s_list')
+ ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name')
+ ->whereIn('s_list.entrust_id', $entrustIds)
+ ->pluck('s_check_item.use_seats', 's_list.entrust_id')
+ ->toArray();
+ }
+ foreach ($items as &$item) {
+ $item['use_seats'] = $useSeatsMap[$item['entrust_id']] ?? 1;
+ }
+ unset($item);
+
if ($type === 'full_day') {
return $this->doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
} elseif ($type === 'same_day_slot') {
@@ -496,10 +511,11 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids,
$assigned = false;
foreach ($availablePlans as $plan) {
$planId = $plan->id;
+ $useSeats = $item['use_seats'] ?? 1;
$remaining = ($plan->count ?? 0) - ($plan->used_count ?? 0);
$used = $usedCapacity[$planId] ?? 0;
- if (($remaining - $used) <= 0) continue;
+ if (($remaining - $used) < $useSeats) continue;
// 冲突检查:同一科室组内,不同排班时间不能重叠
if ($this->isTimeConflict($assignedPlans, $plan)) continue;
@@ -514,7 +530,7 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids,
'begin_time' => $plan->begin_time,
'end_time' => $plan->end_time
];
- $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + 1;
+ $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + $useSeats;
$assignedPlans[] = [
'resource_name' => $plan->department_resources_name,
'begin_time' => $plan->begin_time,
@@ -587,10 +603,11 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep
$assigned = false;
foreach ($availablePlans as $plan) {
$planId = $plan->id;
+ $useSeats = $item['use_seats'] ?? 1;
$remaining = ($plan->count ?? 0) - ($plan->used_count ?? 0);
$used = $usedCapacity[$planId] ?? 0;
- if (($remaining - $used) <= 0) continue;
+ if (($remaining - $used) < $useSeats) continue;
// 冲突检查:同一科室组内,不同排班时间不能重叠
if ($this->isTimeConflict($assignedPlans, $plan)) continue;
@@ -603,7 +620,7 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep
'begin_time' => $plan->begin_time,
'end_time' => $plan->end_time
];
- $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + 1;
+ $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + $useSeats;
$assignedPlans[] = [
'resource_name' => $plan->department_resources_name,
'begin_time' => $plan->begin_time,
@@ -705,10 +722,11 @@ private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids,
$assigned = false;
foreach ($availablePlans as $plan) {
$planId = $plan->id;
+ $useSeats = $item['use_seats'] ?? 1;
$remaining = ($plan->count ?? 0) - ($plan->used_count ?? 0);
$used = $usedCapacity[$planId] ?? 0;
- if (($remaining - $used) <= 0) continue;
+ if (($remaining - $used) < $useSeats) continue;
// 冲突检查:同一科室组内,不同排班时间不能重叠
if ($this->isTimeConflict($assignedPlans, $plan)) continue;
@@ -721,7 +739,7 @@ private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids,
'begin_time' => $plan->begin_time,
'end_time' => $plan->end_time
];
- $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + 1;
+ $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + $useSeats;
$assignedPlans[] = [
'resource_name' => $plan->department_resources_name,
'begin_time' => $plan->begin_time,
diff --git a/YiJi-admin/src/components/Yewu/YuYue202506.vue b/YiJi-admin/src/components/Yewu/YuYue202506.vue
index e6863e8..dba3807 100644
--- a/YiJi-admin/src/components/Yewu/YuYue202506.vue
+++ b/YiJi-admin/src/components/Yewu/YuYue202506.vue
@@ -206,6 +206,17 @@
确定
+
+
+
+ 确定
+
+
@@ -292,10 +303,13 @@
let crossTimeDialogVisible = ref(false)
let crossTimeDialogHtml = ref('')
let cachedCrossDialogData = ref(null) // 缓存跨时段 dialog 数据:{ html, idx }
+ let cachedRecommendResultData = ref(null) // 缓存推荐结果 dialog 数据:{ html, idx }
let conflictDialogVisible = ref(false)
let conflictDialogHtml = ref('')
let resultDialogVisible = ref(false)
let resultDialogHtml = ref('')
+ let recommendResultVisible = ref(false)
+ let recommendResultHtml = ref('')
const getWeekday = (date1) => {
let days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const date = new Date(date1); // 注意:格式可能因浏览器而异
@@ -406,6 +420,17 @@
cachedCrossDialogData.value = null
}
}
+ // 检查缓存中是否有推荐结果 dialog 需要弹出
+ if (cachedRecommendResultData.value) {
+ const currentIdx = entrustTableDate.value.findIndex(
+ r => selectedMianListId.value.includes(r.id)
+ ) + 1
+ if (currentIdx === cachedRecommendResultData.value.idx) {
+ recommendResultHtml.value = cachedRecommendResultData.value.html
+ recommendResultVisible.value = true
+ cachedRecommendResultData.value = null
+ }
+ }
checkSameSourceRoom()
}
const checkSameSourceRoom = () => {
@@ -775,6 +800,36 @@
}
}
+ // 首次自动推荐:未匹配检测
+ const matchedIds = new Set(res.data.map(v => v.id))
+ const unmatched = items.filter(v => !matchedIds.has(v.id))
+ if (unmatched.length > 0) {
+ let html = '
'
+ html += '| 序号 | 项目名称 | 排班资源 | 日期 | 时间段 | 结果 |
'
+ let idx = 1
+ res.data.forEach(v => {
+ const entrustName = entrustTableDate.value.find(r => r.id === v.id)?.entrust || ''
+ html += '| ' + (idx++) + ' | ' + entrustName + ' | ' + v.department_resources_name + ' | ' + v.date + ' | ' + v.begin_time?.substring(0, 5) + '-' + v.end_time?.substring(0, 5) + ' | ✅ 成功匹配 |
'
+ })
+ unmatched.forEach(v => {
+ const entrustName = entrustTableDate.value.find(r => r.id === v.id)?.entrust || ''
+ html += '| ' + (idx++) + ' | ' + entrustName + ' | — | ❌ 未找到合适号源 |
'
+ })
+ html += '
'
+ // 计算未匹配项目的最小序号
+ const unmatchedIndices = unmatched.map(v => entrustTableDate.value.findIndex(r => r.id === v.id) + 1).filter(i => i > 0)
+ const minUnmatchedIdx = Math.min(...unmatchedIndices)
+ const selectedIdx = entrustTableDate.value.findIndex(
+ r => selectedMianListId.value.includes(r.id)
+ ) + 1
+ if (selectedIdx === minUnmatchedIdx) {
+ recommendResultHtml.value = html
+ recommendResultVisible.value = true
+ } else {
+ cachedRecommendResultData.value = { html: html, idx: minUnmatchedIdx }
+ }
+ }
+
// 更新高亮
const newHighlightIds = findHighlightPlanIds()
if (newHighlightIds.length > 0) {
@@ -1008,11 +1063,21 @@
const matchedIds = new Set(res.data.map(v => v.id))
const unmatched = items.filter(v => !matchedIds.has(v.id))
if (unmatched.length > 0) {
- let msg = '✅ 成功匹配 ' + res.data.length + ' 项:\n'
- msg += res.data.map(v => ' ' + v.department_resources_name + ' ' + v.date + ' ' + v.begin_time?.substring(0, 5) + '-' + v.end_time?.substring(0, 5)).join('\n')
- msg += '\n\n❌ 未匹配 ' + unmatched.length + ' 项:\n'
- msg += unmatched.map(v => ' ' + (items.findIndex(i => i.id === v.id) + 1) + '、' + v.entrust_id + ':未找到合适号源').join('\n')
- ElMessageBox.confirm(msg, '预约推荐结果', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', showCancelButton: false })
+ // 构建推荐结果表格
+ let html = ''
+ html += '| 序号 | 项目名称 | 排班资源 | 日期 | 时间段 | 结果 |
'
+ let idx = 1
+ res.data.forEach(v => {
+ const entrustName = entrustTableDate.value.find(r => r.id === v.id)?.entrust || ''
+ html += '| ' + (idx++) + ' | ' + entrustName + ' | ' + v.department_resources_name + ' | ' + v.date + ' | ' + v.begin_time?.substring(0, 5) + '-' + v.end_time?.substring(0, 5) + ' | ✅ 成功匹配 |
'
+ })
+ unmatched.forEach(v => {
+ const entrustName = entrustTableDate.value.find(r => r.id === v.id)?.entrust || ''
+ html += '| ' + (idx++) + ' | ' + entrustName + ' | — | ❌ 未找到合适号源 |
'
+ })
+ html += '
'
+ recommendResultHtml.value = html
+ recommendResultVisible.value = true
} else if (res.data.length === 0) {
ElMessageBox.confirm('所有项目均未匹配到合适号源,请重新选择号源', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'error', showCancelButton: false })
}
diff --git a/YiJi-admin/src/views/YeWu/CheckItemConfig.vue b/YiJi-admin/src/views/YeWu/CheckItemConfig.vue
index 05611dc..8ff4419 100644
--- a/YiJi-admin/src/views/YeWu/CheckItemConfig.vue
+++ b/YiJi-admin/src/views/YeWu/CheckItemConfig.vue
@@ -127,6 +127,10 @@
检查时间:
+
等待时间:
医嘱开具后,预约时间需在设定的等待期之后,单位分钟
@@ -350,7 +354,8 @@
check_time: '',
check_begin_time: '',
check_notice: '',
- warm_tips: ''
+ warm_tips: '',
+ use_seats: 1
})
//获取检查项目类别list
let BigClassList = ref([]);
@@ -646,6 +651,7 @@
selectedItemInfo.value.limosis = row.limosis
selectedItemInfo.value.reservation_method = row.reservation_method
selectedItemInfo.value.check_time = row.check_time
+ selectedItemInfo.value.use_seats = row.use_seats || 1
if (row.check_begin_time == '' || row.check_begin_time == null) {
row.check_begin_time = 0
}
diff --git a/YiJi-admin/src/views/YeWu/DeptCheckItemConfig.vue b/YiJi-admin/src/views/YeWu/DeptCheckItemConfig.vue
index 8ccf53a..dfadf08 100644
--- a/YiJi-admin/src/views/YeWu/DeptCheckItemConfig.vue
+++ b/YiJi-admin/src/views/YeWu/DeptCheckItemConfig.vue
@@ -113,6 +113,10 @@
检查时间:
+
等待时间:
医嘱开具后,预约时间需在设定的等待期之后,单位分钟
@@ -323,7 +327,8 @@
check_time: '',
check_begin_time: '',
check_notice: '',
- warm_tips: ''
+ warm_tips: '',
+ use_seats: 1
})
//获取检查项目类别list
let BigClassList = ref([]);
@@ -595,6 +600,7 @@
selectedItemInfo.value.limosis = row.limosis
selectedItemInfo.value.reservation_method = row.reservation_method
selectedItemInfo.value.check_time = row.check_time
+ selectedItemInfo.value.use_seats = row.use_seats || 1
if (row.check_begin_time == '' || row.check_begin_time == null) {
row.check_begin_time = 0
}