医生排班

This commit is contained in:
2025-12-10 15:44:36 +08:00
parent b863c14f2b
commit 391506e423
18 changed files with 747 additions and 0 deletions

View File

@@ -0,0 +1,431 @@
<template>
<div class="doctorschedule-container">
<div class="doctorschedule-header">
<h2 class="doctorschedule-title">医生排班</h2>
</div>
<div class="doctorschedule-content">
<!-- 筛选条件 -->
<div class="filter-condition">
<span class="filter-label">卫生机构</span>
<el-select v-model="filterParams.orgName" class="filter-select">
<el-option label="演示医院" value="演示医院"></el-option>
</el-select>
<span class="filter-label">科室名称</span>
<el-select v-model="filterParams.deptName" class="filter-select">
<el-option label="测试内科" value="测试内科"></el-option>
</el-select>
<span class="filter-label">开始日期</span>
<el-date-picker
v-model="filterParams.startDate"
type="date"
placeholder="选择日期"
class="filter-date-picker"
/>
<span class="filter-label">排班类型</span>
<div class="radio-group">
<el-radio v-model="filterParams.appointmentType" label="普通">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家">专家</el-radio>
</div>
</div>
<!-- 排班表格 -->
<div class="schedule-table-container">
<!-- 按日期分组显示排班 -->
<div v-for="(dateGroup, index) in groupedSchedule" :key="index" class="daily-schedule">
<div class="daily-header">
<span class="date-text">{{ dateGroup.date }}</span>
<span class="weekday-text">{{ dateGroup.weekday }}</span>
</div>
<el-table :data="dateGroup.items" border style="width: 100%" class="schedule-table">
<el-table-column prop="timeSlot" label="时段" width="100"></el-table-column>
<el-table-column prop="doctorName" label="医生" width="120">
<template #default="scope">
<el-select
v-model="scope.row.doctorName"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="张医生" value="张医生"></el-option>
<el-option label="李医生" value="李医生"></el-option>
<el-option label="王医生" value="王医生"></el-option>
<el-option label="赵医生" value="赵医生"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="room" label="诊室" width="100">
<template #default="scope">
<el-select
v-model="scope.row.room"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="诊室1" value="诊室1"></el-option>
<el-option label="诊室2" value="诊室2"></el-option>
<el-option label="诊室3" value="诊室3"></el-option>
<el-option label="诊室4" value="诊室4"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="startTime" label="开始时间" width="120">
<template #default="scope">
<el-time-picker
v-model="scope.row.startTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择开始时间"
:disabled="!isEditMode"
class="time-picker"
/>
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="120">
<template #default="scope">
<el-time-picker
v-model="scope.row.endTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择结束时间"
:disabled="!isEditMode"
class="time-picker"
/>
</template>
</el-table-column>
<el-table-column prop="maxNumber" label="限号数量" width="80"></el-table-column>
<el-table-column prop="record" label="号源记录" width="80">
<template #default="scope">
<el-icon><View /></el-icon>
</template>
</el-table-column>
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
<template #default="scope">
<el-select
v-model="scope.row.appointmentItem"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="挂号费 50" value="挂号费 50"></el-option>
<el-option label="一般诊疗费 10" value="一般诊疗费 10"></el-option>
<el-option label="主任医师 27" value="主任医师 27"></el-option>
<el-option label="副主任 15" value="副主任 15"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100"></el-table-column>
<el-table-column prop="clinicItem" label="诊查项目" width="150">
<template #default="scope">
<el-select
v-model="scope.row.clinicItem"
placeholder="请选择诊查项目"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="内科诊查" value="内科诊查"></el-option>
<el-option label="专家诊查" value="专家诊查"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100"></el-table-column>
<el-table-column prop="online" label="线上" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.online" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopClinic" label="停诊" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.stopClinic" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopReason" label="停诊原因" width="150">
<template #default="scope">
<el-input
v-model="scope.row.stopReason"
placeholder="请输入停诊原因"
class="inline-input"
:disabled="!isEditMode"
></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="scope">
<el-button
type="primary"
size="small"
@click="handleAddSchedule(scope.row)"
:disabled="!isEditMode"
>
添加
</el-button>
<el-button
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
:disabled="!isEditMode"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-buttons">
<el-button type="primary" @click="handleSave" :disabled="!isEditMode">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
</div>
</div>
</div>
</template>
<script setup name="DoctorSchedule">
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { View } from '@element-plus/icons-vue'
// 路由和导航
const route = useRoute()
const router = useRouter()
// 筛选参数
const filterParams = ref({
orgName: '演示医院',
deptName: '测试内科',
startDate: new Date('2025-12-01'),
appointmentType: '普通'
})
// 编辑模式控制
const isEditMode = computed(() => {
return route.query.mode === 'edit'
})
// 排班列表数据
const scheduleList = ref([])
// 按日期分组的排班数据
const groupedSchedule = computed(() => {
// 按日期分组
const groups = {}
scheduleList.value.forEach(item => {
if (!groups[item.date]) {
groups[item.date] = {
date: item.date,
weekday: item.weekday,
items: []
}
}
groups[item.date].items.push(item)
})
// 转换为数组
return Object.values(groups)
})
// 生成一周排班数据
const generateWeekSchedule = (startDate) => {
const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
const timeSlots = [
{ label: '上午', startTime: '08:00', endTime: '12:00' },
{ label: '下午', startTime: '14:30', endTime: '18:00' }
]
const schedule = []
// 生成一周7天的数据
for (let i = 0; i < 7; i++) {
const currentDate = new Date(startDate)
currentDate.setDate(startDate.getDate() + i)
const dateStr = currentDate.toISOString().split('T')[0]
const weekday = days[currentDate.getDay()]
// 每个时间段生成一条记录
timeSlots.forEach(slot => {
schedule.push({
id: `${dateStr}-${slot.label}`,
date: dateStr,
weekday: weekday,
timeSlot: slot.label,
startTime: slot.startTime,
endTime: slot.endTime,
doctorName: '',
room: '',
maxNumber: 20,
appointmentItem: '',
registrationFee: '',
clinicItem: '',
treatmentFee: '',
online: true,
stopClinic: false,
stopReason: ''
})
})
}
return schedule
}
// 初始化数据
const initData = () => {
// 从路由参数获取科室ID
const deptId = route.params.deptId
console.log('科室ID:', deptId)
// 生成排班数据
scheduleList.value = generateWeekSchedule(filterParams.value.startDate)
}
// 添加排班
const handleAddSchedule = (row) => {
ElMessage.info('添加排班功能待实现')
}
// 删除排班
const handleDeleteSchedule = (row) => {
ElMessage.info('删除排班功能待实现')
}
// 保存排班
const handleSave = () => {
ElMessage.success('排班保存成功')
// 返回上一页
router.back()
}
// 取消操作
const handleCancel = () => {
// 返回上一页
router.back()
}
// 页面加载时初始化数据
onMounted(() => {
initData()
})
</script>
<style scoped lang="scss">
.doctorschedule-container {
width: 100%;
height: 100%;
padding: 20px;
background-color: #f5f7fa;
}
.doctorschedule-header {
margin-bottom: 20px;
}
.doctorschedule-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin: 0;
}
.doctorschedule-content {
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.filter-condition {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 16px;
}
.filter-label {
font-weight: 500;
white-space: nowrap;
}
.filter-select {
width: 150px;
}
.filter-date-picker {
width: 200px;
}
.radio-group {
display: flex;
align-items: center;
gap: 10px;
}
.schedule-table-container {
margin-bottom: 20px;
}
.daily-schedule {
margin-bottom: 20px;
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
}
.daily-header {
background-color: #f5f7fa;
padding: 10px 15px;
border-bottom: 1px solid #ebeef5;
display: flex;
align-items: center;
gap: 15px;
font-size: 16px;
font-weight: 600;
}
.date-text {
color: #333;
}
.weekday-text {
color: #606266;
font-weight: normal;
}
.schedule-table {
:deep(.el-table__header-wrapper th.el-table__cell),
:deep(.el-table__body-wrapper td.el-table__cell) {
text-align: center;
}
/* 隐藏表格头部的边框线,与日期标题融合 */
:deep(.el-table__header-wrapper) {
border-top: none;
}
}
.inline-select {
width: 100%;
}
.inline-input {
width: 100%;
}
.time-picker {
width: 100%;
}
.bottom-buttons {
display: flex;
justify-content: flex-end;
gap: 16px;
}
</style>