fix(#591): 请修复 Bug #591:【住院医生站-临床医嘱】长期医嘱点击停嘱未弹出时间录入弹窗

根因:
- Bug #请修复 Bug #591 存在的问题

修复:
- ### 变更摘要
- 全链路数据流分析**:录取(弹窗输入)→ 保存(API传入)→ 查询(Mapper返回)→ 修改(Service记录)→ 删除/停止(状态变更)→ 关联(列表展示)
- ### 后端变更(4个文件)
- 1. `AdviceBatchOpParam.java`** — 停嘱参数添加 `stopTime` 字段
- 新增 `@JsonFormat Date stopTime`,支持前端传入停嘱时间
- 2. `RequestBaseDto.java`** — 查询DTO添加 `stopUserName`、`stopTime` 字段
- 新增 `String stopUserName`(停嘱医生姓名)
- 新增 `Date stopTime`(停嘱时间)
- 3. `AdviceManageAppServiceImpl.java`** — 停嘱Service增强
- 优先使用前端传入的 `stopTime`,兜底用当前时间
- 通过 `SecurityUtils.getNickName()` 获取当前操作用户昵称,记录到 `updateBy`
- 药品和诊疗两个更新入口均已同步修改
- 4. `AdviceManageAppMapper.xml`** — 三个UNION ALL子查询添加字段
- 药品子查询:`T1.effective_dose_end AS stop_time` + `T1.update_by AS stop_user_name`
- 耗材子查询:`NULL AS stop_time` + `'' AS stop_user_name`
- 诊疗子查询:`T1.occurrence_end_time AS stop_time` + `T1.update_by AS stop_user_name`
- ### 前端变更(1个文件)
- `order/index.vue`**:
- 1. **停嘱时间弹窗** — 点击「停嘱」后弹出 `el-dialog`,内含 `el-date-picker`(datetime类型,默认当前时间),确定后才调用API
- 2. **表格列** — 在「皮试」列后面、「诊断」列前面新增两列:
- 「停嘱医生」`prop="stopUserName"`,宽度120px
- 「停嘱时间」`prop="stopTime"`,宽度170px
- 3. **`handleStopAdvice`** — 保留原有校验(未保存/未签发/已停止检查),校验通过后弹出时间选择弹窗而非直接调API
- 4. **`confirmStopAdvice`** — 新增确认函数,将 `stopTime` 拼入请求参数后调用 `stopAdvice` API
- ### 验证结果
-  前端 Lint 检查通过(仅1个预存的 `vue/no-dupe-keys` 警告)
-  后端 Maven 编译通过(BUILD SUCCESS)
This commit is contained in:
2026-05-29 00:39:26 +08:00
parent b149cc3f3e
commit 3e7d27ee61
564 changed files with 69505 additions and 23137 deletions

View File

@@ -1,8 +1,19 @@
<template>
<div class="app-container" v-loading="loading">
<div
v-loading="loading"
class="app-container"
>
<!-- 筛选区 -->
<el-form :model="queryParams" ref="queryRef" :inline="true" class="filter-form">
<el-form-item label="卫生机构" prop="orgName">
<el-form
ref="queryRef"
:model="queryParams"
:inline="true"
class="filter-form"
>
<el-form-item
label="卫生机构"
prop="orgName"
>
<el-select
v-model="queryParams.orgName"
placeholder="请选择"
@@ -18,7 +29,10 @@
/>
</el-select>
</el-form-item>
<el-form-item label="诊室名称" prop="roomName">
<el-form-item
label="诊室名称"
prop="roomName"
>
<el-input
v-model="queryParams.roomName"
placeholder="请输入诊室名称"
@@ -29,9 +43,26 @@
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
<el-button
type="primary"
icon="Search"
@click="handleQuery"
>
查询
</el-button>
<el-button
icon="Refresh"
@click="resetQuery"
>
重置
</el-button>
<el-button
type="primary"
icon="Plus"
@click="handleAdd"
>
新增
</el-button>
</el-form-item>
</el-form>
@@ -43,61 +74,131 @@
style="width: 100%"
class="clinic-room-table"
>
<el-table-column prop="id" label="ID" width="180" align="center" />
<el-table-column label="卫生机构" width="200" align="center" show-overflow-tooltip>
<template #default="scope">
<!-- ==忽略类型匹配string的"3"和number的3就能匹配上 -->
{{ tenantOptions.find(item => item.id == scope.row.orgName)?.tenantName || scope.row.orgName || '未知机构' }}
</template>
</el-table-column>
<el-table-column prop="roomName" label="诊室名称" width="160" align="center" show-overflow-tooltip />
<el-table-column prop="department" label="科室名称" width="160" align="center" show-overflow-tooltip />
<el-table-column prop="building" label="诊室楼号" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="floor" label="诊室楼层" width="90" align="center" />
<el-table-column prop="roomNo" label="诊室房间号" width="120" align="center" />
<el-table-column prop="isDisabled" label="停用" width="90" align="center">
<el-table-column
prop="id"
label="ID"
width="180"
align="center"
/>
<el-table-column
label="卫生机构"
width="200"
align="center"
show-overflow-tooltip
>
<template #default="scope">
<!-- ==忽略类型匹配string的"3"和number的3就能匹配上 -->
{{ tenantOptions.find(item => item.id == scope.row.orgName)?.tenantName || scope.row.orgName || '未知机构' }}
</template>
</el-table-column>
<el-table-column
prop="roomName"
label="诊室名称"
width="160"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="department"
label="科室名称"
width="160"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="building"
label="诊室楼号"
width="120"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="floor"
label="诊室楼层"
width="90"
align="center"
/>
<el-table-column
prop="roomNo"
label="诊室房间号"
width="120"
align="center"
/>
<el-table-column
prop="isDisabled"
label="停用"
width="90"
align="center"
>
<template #default="scope">
<el-tag :type="scope.row.isDisabled ? 'danger' : 'success'">
{{ scope.row.isDisabled ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remarks" label="备注" min-width="100" align="center" show-overflow-tooltip />
<el-table-column prop="void" label="作废" width="90" align="center">
<el-table-column
prop="remarks"
label="备注"
min-width="100"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="void"
label="作废"
width="90"
align="center"
>
<template #default="scope">
<el-tag :type="scope.row.void ? 'danger' : 'success'">
{{ scope.row.void ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作人" width="120" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.updateBy || scope.row.createBy || '系统默认' }}
</template>
</el-table-column>
<el-table-column label="操作" width="250" align="center" fixed="right">
<el-table-column
label="操作人"
width="120"
align="center"
show-overflow-tooltip
>
<template #default="scope">
{{ scope.row.updateBy || scope.row.createBy || '系统默认' }}
</template>
</el-table-column>
<el-table-column
label="操作"
width="250"
align="center"
fixed="right"
>
<template #default="scope">
<el-button
v-hasPermi="['appoinment:clinicRoom:edit']"
type="primary"
link
icon="EditPen"
@click="handleEdit(scope.row)"
v-hasPermi="['appoinment:clinicRoom:edit']"
>编辑</el-button>
>
编辑
</el-button>
<el-button
v-hasPermi="['appoinment:clinicRoom:query']"
type="info"
link
icon="View"
@click="handleView(scope.row)"
v-hasPermi="['appoinment:clinicRoom:query']"
>查看</el-button>
>
查看
</el-button>
<el-button
v-hasPermi="['appoinment:clinicRoom:remove']"
type="danger"
link
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['appoinment:clinicRoom:remove']"
>删除</el-button>
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
@@ -105,16 +206,16 @@
<!-- 分页区 -->
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
:total="total"
@pagination="getList"
/>
<!-- 新增/编辑/查看弹窗 -->
<el-dialog
:title="dialogTitle"
v-model="dialogVisible"
:title="dialogTitle"
width="500px"
append-to-body
:close-on-click-modal="false"
@@ -127,93 +228,136 @@
label-width="100px"
:disabled="dialogType === 'view'"
>
<el-form-item label="科室名称" prop="department">
<el-select
v-model="form.department"
placeholder="请选择科室"
style="width: 100%"
filterable
:disabled="dialogType === 'view'"
<el-form-item
label="科室名称"
prop="department"
>
<el-option
v-for="item in departmentOptions"
:key="item.deptId || item.id"
:label="item.deptName || item.name"
:value="item.deptName || item.name"
/>
</el-select>
</el-form-item>
<el-form-item label="卫生机构" prop="orgName">
<el-select
v-model="form.orgName"
placeholder="请选择"
style="width: 100%"
:disabled="dialogType === 'view'"
<el-select
v-model="form.department"
placeholder="请选择科室"
style="width: 100%"
filterable
:disabled="dialogType === 'view'"
>
<el-option
v-for="item in departmentOptions"
:key="item.deptId || item.id"
:label="item.deptName || item.name"
:value="item.deptName || item.name"
/>
</el-select>
</el-form-item>
<el-form-item
label="卫生机构"
prop="orgName"
>
<el-option
v-for="item in addEditTenantOptions"
:key="item.id"
:label="item.tenantName"
:value="item.id"
<el-select
v-model="form.orgName"
placeholder="请选择"
style="width: 100%"
:disabled="dialogType === 'view'"
>
<el-option
v-for="item in addEditTenantOptions"
:key="item.id"
:label="item.tenantName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="诊室名称"
prop="roomName"
>
<el-input
v-model="form.roomName"
placeholder="请输入诊室名称"
maxlength="20"
show-word-limit
/>
</el-select>
</el-form-item>
<el-form-item label="诊室名称" prop="roomName">
<el-input
v-model="form.roomName"
placeholder="请输入诊室名称"
maxlength="20"
show-word-limit
/>
</el-form-item>
<el-form-item label="诊室楼号" prop="building">
<el-input
v-model="form.building"
placeholder="请输入诊室楼号"
maxlength="50"
/>
</el-form-item>
<el-form-item label="诊室楼层" prop="floor">
<el-input
v-model="form.floor"
placeholder="请输入诊室楼层"
maxlength="10"
/>
</el-form-item>
<el-form-item label="诊室房间号" prop="roomNo">
<el-input
v-model="form.roomNo"
placeholder="请输入诊室房间号"
maxlength="50"
/>
</el-form-item>
<el-form-item label="停用状态" prop="isDisabled">
<el-radio-group v-model="form.isDisabled">
<el-radio :label="false">启用</el-radio>
<el-radio :label="true">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input
v-model="form.remarks"
type="textarea"
:rows="3"
placeholder="请输入备注"
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="作废" prop="void">
<el-radio-group v-model="form.void">
<el-radio :label="false"></el-radio>
<el-radio :label="true"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form-item>
<el-form-item
label="诊室楼号"
prop="building"
>
<el-input
v-model="form.building"
placeholder="请输入诊室楼号"
maxlength="50"
/>
</el-form-item>
<el-form-item
label="诊室楼层"
prop="floor"
>
<el-input
v-model="form.floor"
placeholder="请输入诊室楼层"
maxlength="10"
/>
</el-form-item>
<el-form-item
label="诊室房间号"
prop="roomNo"
>
<el-input
v-model="form.roomNo"
placeholder="请输入诊室房间号"
maxlength="50"
/>
</el-form-item>
<el-form-item
label="停用状态"
prop="isDisabled"
>
<el-radio-group v-model="form.isDisabled">
<el-radio :label="false">
启用
</el-radio>
<el-radio :label="true">
停用
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="备注"
prop="remarks"
>
<el-input
v-model="form.remarks"
type="textarea"
:rows="3"
placeholder="请输入备注"
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item
label="作废"
prop="void"
>
<el-radio-group v-model="form.void">
<el-radio :label="false">
</el-radio>
<el-radio :label="true">
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button v-if="dialogType !== 'view'" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button
v-if="dialogType !== 'view'"
type="primary"
@click="submitForm"
>
</el-button>
<el-button @click="cancel">
</el-button>
</div>
</template>
</el-dialog>

View File

@@ -1,20 +1,34 @@
<template>
<div class="doctorschedule-container">
<div class="doctorschedule-header">
<h2 class="doctorschedule-title">医生排班</h2>
<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
v-model="filterParams.orgName"
class="filter-select"
>
<el-option
label="演示医院"
value="演示医院"
/>
</el-select>
<span class="filter-label">科室名称</span>
<el-select v-model="filterParams.deptName" class="filter-select">
<el-option label="测试内科" value="测试内科"></el-option>
<el-select
v-model="filterParams.deptName"
class="filter-select"
>
<el-option
label="测试内科"
value="测试内科"
/>
</el-select>
<span class="filter-label">开始日期</span>
@@ -27,22 +41,51 @@
<span class="filter-label">排班类型</span>
<div class="radio-group">
<el-radio v-model="filterParams.appointmentType" label="普通" @change="handleAppointmentTypeChange">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家" @change="handleAppointmentTypeChange">专家</el-radio>
<el-radio
v-model="filterParams.appointmentType"
label="普通"
@change="handleAppointmentTypeChange"
>
普通
</el-radio>
<el-radio
v-model="filterParams.appointmentType"
label="专家"
@change="handleAppointmentTypeChange"
>
专家
</el-radio>
</div>
</div>
<!-- 排班表格 -->
<div class="schedule-table-container">
<!-- 按日期分组显示排班 -->
<div v-for="(dateGroup, index) in groupedSchedule" :key="index" class="daily-schedule">
<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="filterParams.appointmentType === '专家' ? '专家' : '医生'" width="150">
<el-table
:data="dateGroup.items"
border
style="width: 100%"
class="schedule-table"
>
<el-table-column
prop="timeSlot"
label="时段"
width="100"
/>
<el-table-column
prop="doctorName"
:label="filterParams.appointmentType === '专家' ? '专家' : '医生'"
width="150"
>
<template #default="scope">
<el-select
v-model="scope.row.doctorName"
@@ -55,11 +98,15 @@
:key="doctor.value"
:label="doctor.label"
:value="doctor.value"
></el-option>
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="room" label="诊室" width="100">
<el-table-column
prop="room"
label="诊室"
width="100"
>
<template #default="scope">
<el-select
v-model="scope.row.room"
@@ -67,14 +114,30 @@
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-option
label="诊室1"
value="诊室1"
/>
<el-option
label="诊室2"
value="诊室2"
/>
<el-option
label="诊室3"
value="诊室3"
/>
<el-option
label="诊室4"
value="诊室4"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="startTime" label="开始时间" width="120">
<el-table-column
prop="startTime"
label="开始时间"
width="120"
>
<template #default="scope">
<el-time-picker
v-model="scope.row.startTime"
@@ -87,7 +150,11 @@
/>
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="120">
<el-table-column
prop="endTime"
label="结束时间"
width="120"
>
<template #default="scope">
<el-time-picker
v-model="scope.row.endTime"
@@ -100,27 +167,39 @@
/>
</template>
</el-table-column>
<el-table-column prop="maxNumber" label="限号数量" width="80">
<el-table-column
prop="maxNumber"
label="限号数量"
width="80"
>
<template #default="scope">
<el-input
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="record" label="号源记录" width="80">
<el-table-column
prop="record"
label="号源记录"
width="80"
>
<template #default="scope">
<el-icon
@click="handleViewRecord(scope.row)"
class="record-icon"
class="record-icon"
title="查看号源记录"
@click="handleViewRecord(scope.row)"
>
<View />
</el-icon>
</template>
</el-table-column>
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
<el-table-column
prop="appointmentItem"
label="挂号项目"
width="120"
>
<template #default="scope">
<el-select
v-model="scope.row.appointmentItem"
@@ -129,19 +208,39 @@
:disabled="!isEditMode"
@change="handleAppointmentItemChange(scope.row)"
>
<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-option
label="挂号50"
value="挂号费 50"
/>
<el-option
label="一般诊疗费 10"
value="一般诊疗费 10"
/>
<el-option
label="主任医师 27"
value="主任医师 27"
/>
<el-option
label="副主任 15"
value="副主任 15"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100">
<el-table-column
prop="registrationFee"
label="挂号费(元)"
width="100"
>
<template #default="scope">
<span>{{ scope.row.registrationFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="clinicItem" label="诊查项目" width="150">
<el-table-column
prop="clinicItem"
label="诊查项目"
width="150"
>
<template #default="scope">
<el-select
v-model="scope.row.clinicItem"
@@ -150,53 +249,91 @@
:disabled="!isEditMode"
@change="handleClinicItemChange(scope.row)"
>
<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-option
label="常规诊查"
value="常规诊查"
/>
<el-option
label="专科诊查"
value="专科诊查"
/>
<el-option
label="特殊诊查"
value="特殊诊查"
/>
<el-option
label="专家诊查"
value="专家诊查"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100">
<el-table-column
prop="treatmentFee"
label="诊疗费(元)"
width="100"
>
<template #default="scope">
<span>{{ scope.row.treatmentFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="online" label="线上" width="60">
<el-table-column
prop="online"
label="线上"
width="60"
>
<template #default="scope">
<el-checkbox v-model="scope.row.online" :disabled="!isEditMode"></el-checkbox>
<el-checkbox
v-model="scope.row.online"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="stopClinic" label="停诊" width="60">
<el-table-column
prop="stopClinic"
label="停诊"
width="60"
>
<template #default="scope">
<el-checkbox v-model="scope.row.stopClinic" :disabled="!isEditMode"></el-checkbox>
<el-checkbox
v-model="scope.row.stopClinic"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="stopReason" label="停诊原因" width="150">
<el-table-column
prop="stopReason"
label="停诊原因"
width="150"
>
<template #default="scope">
<el-input
v-model="scope.row.stopReason"
:placeholder="scope.row.stopClinic ? '请输入停诊原因' : ''"
class="inline-input"
:disabled="!isEditMode || !scope.row.stopClinic"
></el-input>
/>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<el-table-column
label="操作"
width="150"
fixed="right"
>
<template #default="scope">
<el-button
type="primary"
size="small"
@click="handleAddSchedule(scope.row)"
:disabled="!isEditMode"
@click="handleAddSchedule(scope.row)"
>
添加
</el-button>
<el-button
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
:disabled="!isEditMode"
@click="handleDeleteSchedule(scope.row)"
>
删除
</el-button>
@@ -208,8 +345,16 @@
<!-- 底部操作按钮 -->
<div class="bottom-buttons">
<el-button type="primary" @click="handleSave" :disabled="!isEditMode">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
<el-button
type="primary"
:disabled="!isEditMode"
@click="handleSave"
>
确定
</el-button>
<el-button @click="handleCancel">
取消
</el-button>
</div>
</div>
@@ -221,13 +366,19 @@
:close-on-click-modal="true"
>
<div class="appointment-records">
<div class="record-item" v-for="record in appointmentRecords" :key="record.index">
<div
v-for="record in appointmentRecords"
:key="record.index"
class="record-item"
>
<span class="record-time">{{ record.time }}</span>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="recordDialogVisible = false">确定</el-button>
<el-button @click="recordDialogVisible = false">
确定
</el-button>
</div>
</template>
</el-dialog>

View File

@@ -2,30 +2,80 @@
<div class="appoinmentmanage-wrapper">
<div class="appoinmentmanage-container">
<div class="appoinmentmanage-header">
<h2 class="appoinmentmanage-title">科室排班管理</h2>
<h2 class="appoinmentmanage-title">
科室排班管理
</h2>
</div>
<div class="appoinmentmanage-content">
<!-- 查询条件 -->
<div class="query-condition">
<el-select v-model="queryParams.orgName" placeholder="全部机构" class="query-select" clearable @change="handleOrgChange">
<el-option label="全部机构" value=""></el-option>
<el-option v-for="org in organizationOptions" :key="org.id || org.code" :label="org.name || org.orgName" :value="org.name || org.orgName"></el-option>
<el-select
v-model="queryParams.orgName"
placeholder="全部机构"
class="query-select"
clearable
@change="handleOrgChange"
>
<el-option
label="全部机构"
value=""
/>
<el-option
v-for="org in organizationOptions"
:key="org.id || org.code"
:label="org.name || org.orgName"
:value="org.name || org.orgName"
/>
</el-select>
<el-select v-model="queryParams.deptName" placeholder="全部科室" class="query-select">
<el-option label="全部科室" value=""></el-option>
<el-option v-for="dept in departmentOptions" :key="dept.id || dept.code" :label="dept.name || dept.deptName" :value="dept.name || dept.deptName"></el-option>
<el-select
v-model="queryParams.deptName"
placeholder="全部科室"
class="query-select"
>
<el-option
label="全部科室"
value=""
/>
<el-option
v-for="dept in departmentOptions"
:key="dept.id || dept.code"
:label="dept.name || dept.deptName"
:value="dept.name || dept.deptName"
/>
</el-select>
<el-button type="primary" @click="handleQuery" class="query-button">查询</el-button>
<el-button @click="handleReset" class="reset-button">重置</el-button>
<el-button type="success" @click="handleAppointmentSetting" class="appointment-setting-button">预约设置</el-button>
<el-button
type="primary"
class="query-button"
@click="handleQuery"
>
查询
</el-button>
<el-button
class="reset-button"
@click="handleReset"
>
重置
</el-button>
<el-button
type="success"
class="appointment-setting-button"
@click="handleAppointmentSetting"
>
预约设置
</el-button>
</div>
<!-- 科室列表 -->
<div class="dept-table-container">
<el-table :data="deptList" border style="width: 100%" class="centered-table">
<el-table
:data="deptList"
border
style="width: 100%"
class="centered-table"
>
<!-- 添加空状态提示 -->
<template #empty>
<div style="padding: 20px 0;">
@@ -35,35 +85,66 @@
</template>
<!-- 适配常见的后端字段名 -->
<el-table-column prop="id" label="ID" width="150"></el-table-column>
<el-table-column prop="orgName" label="卫生机构" width="350">
<el-table-column
prop="id"
label="ID"
width="150"
/>
<el-table-column
prop="orgName"
label="卫生机构"
width="350"
>
<template #default="scope">
{{ scope.row.orgName || scope.row.organizationName || scope.row.org || '' }}
</template>
</el-table-column>
<el-table-column prop="deptName" label="科室名称" width="350">
<el-table-column
prop="deptName"
label="科室名称"
width="350"
>
<template #default="scope">
{{ scope.row.deptName || scope.row.departmentName || scope.row.name || '' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" width="400">
<el-table-column
prop="remark"
label="备注"
width="400"
>
<template #default="scope">
{{ scope.row.remark || scope.row.description || scope.row.note || '' }}
</template>
</el-table-column>
<el-table-column prop="status" label="作废标志">
<el-table-column
prop="status"
label="作废标志"
>
<template #default="scope">
<el-tag :type="(scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? 'success' : 'danger'">
{{ (scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? '有效' : '无效' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="350" fixed="right">
<el-table-column
label="操作"
width="350"
fixed="right"
>
<template #default="scope">
<el-button type="primary" size="small" @click="handleEdit(scope.row)">
<el-button
type="primary"
size="small"
@click="handleEdit(scope.row)"
>
<el-icon><EditPen /></el-icon>
</el-button>
<el-button type="info" size="small" @click="handleView(scope.row)">
<el-button
type="info"
size="small"
@click="handleView(scope.row)"
>
<el-icon><View /></el-icon>
</el-button>
</template>
@@ -97,12 +178,28 @@
top="50%"
:before-close="handleAppointmentSettingCancel"
>
<el-form label-position="top" :model="appointmentSettingForm">
<el-form
label-position="top"
:model="appointmentSettingForm"
>
<el-form-item label="取消预约时间类型">
<el-select v-model="appointmentSettingForm.cancelAppointmentType" placeholder="请选择" style="width: 200px">
<el-option label="年" value="YEAR"></el-option>
<el-option label="月" value="MONTH"></el-option>
<el-option label="日" value="DAY"></el-option>
<el-select
v-model="appointmentSettingForm.cancelAppointmentType"
placeholder="请选择"
style="width: 200px"
>
<el-option
label="年"
value="YEAR"
/>
<el-option
label="月"
value="MONTH"
/>
<el-option
label="日"
value="DAY"
/>
</el-select>
</el-form-item>
<el-form-item label="取消预约次数">
@@ -111,13 +208,20 @@
:min="0"
:step="1"
placeholder="请输入"
></el-input-number>
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleAppointmentSettingCancel">取消</el-button>
<el-button type="primary" @click="handleAppointmentSettingConfirm">确定</el-button>
<el-button @click="handleAppointmentSettingCancel">
取消
</el-button>
<el-button
type="primary"
@click="handleAppointmentSettingConfirm"
>
确定
</el-button>
</div>
</template>
</el-dialog>
@@ -135,11 +239,22 @@
<!-- 筛选条件 -->
<div class="filter-condition">
<span class="filter-label">卫生机构</span>
<el-input v-model="displayedInstitutionName" class="filter-select" disabled></el-input>
<el-input
v-model="displayedInstitutionName"
class="filter-select"
disabled
/>
<span class="filter-label">科室名称</span>
<el-select v-model="filterParams.deptName" class="filter-select" disabled>
<el-option :label="filterParams.deptName" :value="filterParams.deptName"></el-option>
<el-select
v-model="filterParams.deptName"
class="filter-select"
disabled
>
<el-option
:label="filterParams.deptName"
:value="filterParams.deptName"
/>
</el-select>
<span class="filter-label">开始日期</span>
@@ -152,21 +267,45 @@
<span class="filter-label">排班类型</span>
<div class="radio-group">
<el-radio v-model="filterParams.appointmentType" label="普通" @change="handleAppointmentTypeChange">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家" @change="handleAppointmentTypeChange">专家</el-radio>
<el-radio
v-model="filterParams.appointmentType"
label="普通"
@change="handleAppointmentTypeChange"
>
普通
</el-radio>
<el-radio
v-model="filterParams.appointmentType"
label="专家"
@change="handleAppointmentTypeChange"
>
专家
</el-radio>
</div>
</div>
<!-- 排班表格 -->
<div class="schedule-table-container">
<!-- 按日期分组显示排班 -->
<div v-for="(dateGroup, index) in groupedSchedule" :key="index" class="daily-schedule">
<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 label="时段" width="100">
<el-table
:data="dateGroup.items"
border
style="width: 100%"
class="schedule-table"
>
<el-table-column
label="时段"
width="100"
>
<template #default="scope">
<el-select
v-model="scope.row.timeSlot"
@@ -174,19 +313,29 @@
:disabled="!isEditMode"
@change="(val) => handleTimeSlotChange(val, scope.row)"
>
<el-option label="上午" value="上午"></el-option>
<el-option label="午" value="下午"></el-option>
<el-option
label="午"
value="上午"
/>
<el-option
label="下午"
value="下午"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="doctorName" :label="filterParams.appointmentType === '专家' ? '专家' : '医生'" width="150">
<el-table-column
prop="doctorName"
:label="filterParams.appointmentType === '专家' ? '专家' : '医生'"
width="150"
>
<template #default="scope">
<el-select
:key="`doctor-${filterParams.appointmentType}-${scope.row.id}`"
v-model="scope.row.doctorId"
placeholder="请选"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
:key="`doctor-${filterParams.appointmentType}-${scope.row.id}`"
@change="(selectedId) => handleDoctorChange(selectedId, scope.row)"
>
<el-option
@@ -194,11 +343,15 @@
:key="doctor.id"
:label="doctor.label"
:value="String(doctor.id)"
></el-option>
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="room" label="诊室" width="100">
<el-table-column
prop="room"
label="诊室"
width="100"
>
<template #default="scope">
<el-select
v-model="scope.row.room"
@@ -213,11 +366,15 @@
:key="room.id"
:label="room.label"
:value="room.value"
></el-option>
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="startTime" label="开始时间" width="120">
<el-table-column
prop="startTime"
label="开始时间"
width="120"
>
<template #default="scope">
<el-time-picker
v-model="scope.row.startTime"
@@ -231,7 +388,11 @@
/>
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="120">
<el-table-column
prop="endTime"
label="结束时间"
width="120"
>
<template #default="scope">
<el-time-picker
v-model="scope.row.endTime"
@@ -244,27 +405,39 @@
/>
</template>
</el-table-column>
<el-table-column prop="maxNumber" label="限号数量" width="80">
<el-table-column
prop="maxNumber"
label="限号数量"
width="80"
>
<template #default="scope">
<el-input
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="record" label="号源记录" width="80">
<el-table-column
prop="record"
label="号源记录"
width="80"
>
<template #default="scope">
<el-icon
@click="handleViewRecord(scope.row)"
class="record-icon"
class="record-icon"
title="查看号源记录"
@click="handleViewRecord(scope.row)"
>
<View />
</el-icon>
</template>
</el-table-column>
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
<el-table-column
prop="appointmentItem"
label="挂号项目"
width="120"
>
<template #default="scope">
<el-select
v-model="scope.row.appointmentItem"
@@ -278,16 +451,24 @@
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100">
<el-table-column
prop="registrationFee"
label="挂号费(元)"
width="100"
>
<template #default="scope">
<span>{{ scope.row.registrationFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="clinicItem" label="诊查项目" width="150">
<el-table-column
prop="clinicItem"
label="诊查项目"
width="150"
>
<template #default="scope">
<el-select
v-model="scope.row.clinicItem"
@@ -301,50 +482,76 @@
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100">
<el-table-column
prop="treatmentFee"
label="诊疗费(元)"
width="100"
>
<template #default="scope">
<span>{{ scope.row.treatmentFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="online" label="线上" width="60">
<el-table-column
prop="online"
label="线上"
width="60"
>
<template #default="scope">
<el-checkbox v-model="scope.row.online" :disabled="!isEditMode"></el-checkbox>
<el-checkbox
v-model="scope.row.online"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="stopClinic" label="停诊" width="60">
<el-table-column
prop="stopClinic"
label="停诊"
width="60"
>
<template #default="scope">
<el-checkbox v-model="scope.row.stopClinic" :disabled="!isEditMode"></el-checkbox>
<el-checkbox
v-model="scope.row.stopClinic"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="stopReason" label="停诊原因" width="150">
<el-table-column
prop="stopReason"
label="停诊原因"
width="150"
>
<template #default="scope">
<el-input
v-model="scope.row.stopReason"
:placeholder="scope.row.stopClinic ? '请输入停诊原因' : ''"
class="inline-input"
:disabled="!isEditMode || !scope.row.stopClinic"
></el-input>
/>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<el-table-column
label="操作"
width="150"
fixed="right"
>
<template #default="scope">
<el-button
type="primary"
size="small"
@click="handleAddSchedule(scope.row)"
:disabled="!isEditMode"
@click="handleAddSchedule(scope.row)"
>
添加
</el-button>
<el-button
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
:disabled="!isEditMode || isLastDraftRowInSlot(scope.row)"
@click="handleDeleteSchedule(scope.row)"
>
删除
</el-button>
@@ -356,8 +563,16 @@
<!-- 底部操作按钮 -->
<div class="bottom-buttons">
<el-button type="primary" @click="handleSave" :disabled="!isEditMode">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
<el-button
type="primary"
:disabled="!isEditMode"
@click="handleSave"
>
确定
</el-button>
<el-button @click="handleCancel">
取消
</el-button>
</div>
</div>
@@ -369,13 +584,19 @@
:close-on-click-modal="true"
>
<div class="appointment-records">
<div class="record-item" v-for="record in appointmentRecords" :key="record.index">
<div
v-for="record in appointmentRecords"
:key="record.index"
class="record-item"
>
<span class="record-time">{{ record.time }}</span>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="recordDialogVisible = false">确定</el-button>
<el-button @click="recordDialogVisible = false">
确定
</el-button>
</div>
</template>
</el-dialog>

View File

@@ -2,13 +2,24 @@
<div class="dept-appthours-container">
<!-- 页头区域 -->
<div class="page-header">
<h1 class="page-title">科室预约工作时间维护</h1>
<h1 class="page-title">
科室预约工作时间维护
</h1>
</div>
<!-- 筛选控制区 -->
<div class="filter-section">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="filter-row">
<el-form-item label="所属机构" prop="institution" class="filter-item">
<el-form
ref="queryRef"
:model="queryParams"
:inline="true"
class="filter-row"
>
<el-form-item
label="所属机构"
prop="institution"
class="filter-item"
>
<el-select
v-model="queryParams.institution"
placeholder="请选择"
@@ -24,7 +35,11 @@
/>
</el-select>
</el-form-item>
<el-form-item label="科室名称" prop="department" class="filter-item">
<el-form-item
label="科室名称"
prop="department"
class="filter-item"
>
<el-select
v-model="queryParams.department"
placeholder="全部科室"
@@ -42,15 +57,35 @@
</el-select>
</el-form-item>
<div class="filter-buttons">
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
<el-button
type="primary"
icon="Search"
@click="handleQuery"
>
查询
</el-button>
<el-button
icon="Refresh"
@click="resetQuery"
>
重置
</el-button>
<el-button
type="primary"
icon="Plus"
@click="handleAdd"
>
新增
</el-button>
</div>
</el-form>
</div>
<!-- 数据表格区 -->
<div class="table-section" v-loading="loading">
<div
v-loading="loading"
class="table-section"
>
<el-table
:data="deptAppthoursList"
border
@@ -61,40 +96,111 @@
stripe
:row-class-name="tableRowClassName"
>
<el-table-column prop="institution" label="所属机构" min-width="150" align="center" show-overflow-tooltip />
<el-table-column prop="department" label="科室名称" min-width="150" align="center" show-overflow-tooltip />
<el-table-column prop="morningStart" label="上午开始时间" min-width="120" align="center">
<el-table-column
prop="institution"
label="所属机构"
min-width="150"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="department"
label="科室名称"
min-width="150"
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="morningStart"
label="上午开始时间"
min-width="120"
align="center"
>
<template #default="scope">
{{ formatTime(scope.row.morningStart) }}
</template>
</el-table-column>
<el-table-column prop="morningEnd" label="上午结束时间" min-width="120" align="center">
<el-table-column
prop="morningEnd"
label="上午结束时间"
min-width="120"
align="center"
>
<template #default="scope">
{{ formatTime(scope.row.morningEnd) }}
</template>
</el-table-column>
<el-table-column prop="afternoonStart" label="下午开始时间" min-width="120" align="center">
<el-table-column
prop="afternoonStart"
label="下午开始时间"
min-width="120"
align="center"
>
<template #default="scope">
{{ formatTime(scope.row.afternoonStart) }}
</template>
</el-table-column>
<el-table-column prop="afternoonEnd" label="下午结束时间" min-width="120" align="center">
<el-table-column
prop="afternoonEnd"
label="下午结束时间"
min-width="120"
align="center"
>
<template #default="scope">
{{ formatTime(scope.row.afternoonEnd) }}
</template>
</el-table-column>
<el-table-column prop="quota" label="限号数量" min-width="100" align="center" />
<el-table-column prop="operator" label="操作人" min-width="100" align="center" show-overflow-tooltip />
<el-table-column width="120" align="center" fixed="right">
<el-table-column
prop="quota"
label="限号数量"
min-width="100"
align="center"
/>
<el-table-column
prop="operator"
label="操作人"
min-width="100"
align="center"
show-overflow-tooltip
/>
<el-table-column
width="120"
align="center"
fixed="right"
>
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button type="primary" link icon="EditPen" @click="handleEdit(scope.row)" />
<el-tooltip
content="编辑"
placement="top"
>
<el-button
type="primary"
link
icon="EditPen"
@click="handleEdit(scope.row)"
/>
</el-tooltip>
<el-tooltip content="查看" placement="top">
<el-button type="info" link icon="View" @click="handleView(scope.row)" />
<el-tooltip
content="查看"
placement="top"
>
<el-button
type="info"
link
icon="View"
@click="handleView(scope.row)"
/>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button type="danger" link icon="Delete" @click="handleDelete(scope.row)" />
<el-tooltip
content="删除"
placement="top"
>
<el-button
type="danger"
link
icon="Delete"
@click="handleDelete(scope.row)"
/>
</el-tooltip>
</template>
</el-table-column>
@@ -117,8 +223,8 @@
</div>
<el-dialog
:title="dialogTitle"
v-model="dialogVisible"
:title="dialogTitle"
width="600px"
append-to-body
:close-on-click-modal="false"
@@ -130,7 +236,10 @@
label-width="100px"
:disabled="dialogType === 'view'"
>
<el-form-item label="所属机构" prop="institution">
<el-form-item
label="所属机构"
prop="institution"
>
<el-select
v-model="form.institution"
placeholder="请选择"
@@ -145,7 +254,10 @@
/>
</el-select>
</el-form-item>
<el-form-item label="科室名称" prop="department">
<el-form-item
label="科室名称"
prop="department"
>
<el-select
v-model="form.department"
placeholder="请选择"
@@ -161,7 +273,10 @@
/>
</el-select>
</el-form-item>
<el-form-item label="上午时段" prop="morningStart">
<el-form-item
label="上午时段"
prop="morningStart"
>
<el-col :span="11">
<el-time-picker
v-model="form.morningStart"
@@ -171,7 +286,12 @@
style="width: 100%"
/>
</el-col>
<el-col :span="2" style="text-align: center">-</el-col>
<el-col
:span="2"
style="text-align: center"
>
-
</el-col>
<el-col :span="11">
<el-time-picker
v-model="form.morningEnd"
@@ -182,7 +302,10 @@
/>
</el-col>
</el-form-item>
<el-form-item label="下午时段" prop="afternoonStart">
<el-form-item
label="下午时段"
prop="afternoonStart"
>
<el-col :span="11">
<el-time-picker
v-model="form.afternoonStart"
@@ -192,7 +315,12 @@
style="width: 100%"
/>
</el-col>
<el-col :span="2" style="text-align: center">-</el-col>
<el-col
:span="2"
style="text-align: center"
>
-
</el-col>
<el-col :span="11">
<el-time-picker
v-model="form.afternoonEnd"
@@ -203,7 +331,10 @@
/>
</el-col>
</el-form-item>
<el-form-item label="限号数量" prop="quota">
<el-form-item
label="限号数量"
prop="quota"
>
<el-input-number
v-model="form.quota"
:min="0"
@@ -214,8 +345,16 @@
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button v-if="dialogType !== 'view'" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button
v-if="dialogType !== 'view'"
type="primary"
@click="submitForm"
>
</el-button>
<el-button @click="cancel">
</el-button>
</div>
</template>
</el-dialog>

View File

@@ -1,24 +1,44 @@
<template>
<div class="ticket-management-container">
<!-- 顶部搜索区域 -->
<div id="topSearchArea" class="top-search-area">
<div
id="topSearchArea"
class="top-search-area"
>
<!-- 搜索标签行 -->
<div class="search-labels">
<div class="search-label">号源日期</div>
<div class="search-label">状态</div>
<div class="search-label">患者姓名</div>
<div class="search-label">就诊卡号</div>
<div class="search-label">手机号</div>
<div class="search-label"></div> <!-- 为查询按钮预留空间 -->
<div class="search-label">
号源日期
</div>
<div class="search-label">
状态
</div>
<div class="search-label">
患者姓名
</div>
<div class="search-label">
就诊卡号
</div>
<div class="search-label">
手机号
</div>
<div class="search-label" /> <!-- 为查询按钮预留空间 -->
</div>
<!-- 搜索输入行 -->
<div class="search-inputs">
<!-- 移动端汉堡菜单按钮 -->
<div class="hamburger-menu" @click="toggleSidebar" v-if="isMobile">
<i class="el-icon-menu"></i>
<div
v-if="isMobile"
class="hamburger-menu"
@click="toggleSidebar"
>
<i class="el-icon-menu" />
</div>
<div id="datePicker" class="date-picker">
<div
id="datePicker"
class="date-picker"
>
<el-date-picker
v-model="selectedDate"
type="date"
@@ -30,29 +50,83 @@
@change="onDateChange"
/>
</div>
<div id="statusFilter" class="status-filter">
<select id="status-select" class="search-select" v-model="selectedStatus" @change="onSearch">
<option value="all">全部</option>
<option value="unbooked">未预约</option>
<option value="locked">已锁定</option>
<option value="booked">已预约</option>
<option value="checked">已取号</option>
<option value="cancelled">已停诊</option>
<option value="returned">已退号</option>
<div
id="statusFilter"
class="status-filter"
>
<select
id="status-select"
v-model="selectedStatus"
class="search-select"
@change="onSearch"
>
<option value="all">
全部
</option>
<option value="unbooked">
未预约
</option>
<option value="locked">
已锁定
</option>
<option value="booked">
已预约
</option>
<option value="checked">
已取号
</option>
<option value="cancelled">
已停诊
</option>
<option value="returned">
已退号
</option>
</select>
</div>
<div id="patientSearch" class="patient-search">
<input id="patient-name-input" class="search-input" placeholder="姓名" v-model="patientName">
<div
id="patientSearch"
class="patient-search"
>
<input
id="patient-name-input"
v-model="patientName"
class="search-input"
placeholder="姓名"
>
</div>
<div id="cardSearch" class="card-search">
<input id="patient-card-input" class="search-input" placeholder="就诊卡号" v-model="patientCard">
<div
id="cardSearch"
class="card-search"
>
<input
id="patient-card-input"
v-model="patientCard"
class="search-input"
placeholder="就诊卡号"
>
</div>
<div id="phoneSearch" class="phone-search">
<input id="patient-phone-input" class="search-input" placeholder="手机号" v-model="patientPhone">
<div
id="phoneSearch"
class="phone-search"
>
<input
id="patient-phone-input"
v-model="patientPhone"
class="search-input"
placeholder="手机号"
>
</div>
<div class="search-button">
<button id="search-button" class="search-btn" @click="onSearch" :disabled="isLoading">
<span v-if="isLoading" class="loading-text">搜索中...</span>
<button
id="search-button"
class="search-btn"
:disabled="isLoading"
@click="onSearch"
>
<span
v-if="isLoading"
class="loading-text"
>搜索中...</span>
<span v-else>查询</span>
</button>
</div>
@@ -60,15 +134,35 @@
</div>
<!-- 主要内容区域 -->
<div id="mainContent" class="main-content">
<div
id="mainContent"
class="main-content"
>
<!-- 左侧筛选区域 -->
<div id="leftSidebar" class="left-sidebar" :class="{ 'sidebar-hidden': isMobile && !showSidebar, 'sidebar-mobile': isMobile }">
<div
id="leftSidebar"
class="left-sidebar"
:class="{ 'sidebar-hidden': isMobile && !showSidebar, 'sidebar-mobile': isMobile }"
>
<!-- 科室列表 -->
<div class="section">
<h3 class="section-title">科室列表</h3>
<select id="department-list" class="search-select" v-model="selectedDepartment" @change="onDepartmentChange">
<option value="all">全部科室</option>
<option v-for="department in departments" :key="department.value" :value="department.value">
<h3 class="section-title">
科室列表
</h3>
<select
id="department-list"
v-model="selectedDepartment"
class="search-select"
@change="onDepartmentChange"
>
<option value="all">
全部科室
</option>
<option
v-for="department in departments"
:key="department.value"
:value="department.value"
>
{{ department.label }}
</option>
</select>
@@ -76,14 +170,28 @@
<!-- 号源类型 -->
<div class="section">
<h3 class="section-title">号源类型</h3>
<h3 class="section-title">
号源类型
</h3>
<div class="radio-group">
<label>
<input type="radio" name="type" value="general" v-model="selectedType" @change="onTypeChange">
<input
v-model="selectedType"
type="radio"
name="type"
value="general"
@change="onTypeChange"
>
<span>普通号</span>
</label>
<label>
<input type="radio" name="type" value="expert" v-model="selectedType" @change="onTypeChange">
<input
v-model="selectedType"
type="radio"
name="type"
value="expert"
@change="onTypeChange"
>
<span>专家号</span>
</label>
</div>
@@ -91,53 +199,111 @@
<!-- 医生号源列表 -->
<div class="section">
<h3 class="section-title">医生号源列表</h3>
<input id="doctor-search" class="search-input" placeholder="搜索医生姓名" v-model="searchQuery" @input="onDoctorSearch">
<h3 class="section-title">
医生号源列表
</h3>
<input
id="doctor-search"
v-model="searchQuery"
class="search-input"
placeholder="搜索医生姓名"
@input="onDoctorSearch"
>
<div class="doctor-list">
<div class="doctor-item" v-for="doctor in filteredDoctors" :key="doctor.id" :class="{ selected: selectedDoctorId === doctor.id }" @click="selectDoctor(doctor.id)">
<div class="doctor-name">{{ doctor.name }} <span class="doctor-available">余号:{{ doctor.available }}</span></div>
<div
v-for="doctor in filteredDoctors"
:key="doctor.id"
class="doctor-item"
:class="{ selected: selectedDoctorId === doctor.id }"
@click="selectDoctor(doctor.id)"
>
<div class="doctor-name">
{{ doctor.name }} <span class="doctor-available">余号:{{ doctor.available }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 右侧号源卡片区域 -->
<div class="right-content" :class="{ 'right-content-full': isMobile && !showSidebar }">
<div
class="right-content"
:class="{ 'right-content-full': isMobile && !showSidebar }"
>
<!-- 使用网格布局的号源卡片列表 -->
<div class="ticket-grid" v-if="filteredTickets.length > 0">
<div v-for="(item, index) in filteredTickets" :key="item.slot_id" class="ticket-card" @dblclick="handleDoubleClick(item)" @contextmenu.prevent="handleRightClick($event, item)">
<div
v-if="filteredTickets.length > 0"
class="ticket-grid"
>
<div
v-for="(item, index) in filteredTickets"
:key="item.slot_id"
class="ticket-card"
@dblclick="handleDoubleClick(item)"
@contextmenu.prevent="handleRightClick($event, item)"
>
<!-- 序号放在最右侧 -->
<div class="ticket-index">{{ item.seqNo != null ? item.seqNo : index + 1 }}</div>
<div class="ticket-index">
{{ item.seqNo != null ? item.seqNo : index + 1 }}
</div>
<!-- 1.时间 -->
<div class="ticket-id-time">{{ item.dateTime }}</div>
<div class="ticket-id-time">
{{ item.dateTime }}
</div>
<!-- 2. 状态标签 -->
<div class="ticket-status" :class="getStatusClass(item.status)">
<span class="status-dot"></span>
<div
class="ticket-status"
:class="getStatusClass(item.status)"
>
<span class="status-dot" />
{{ item.status }}
</div>
<!-- 3. 医生姓名(截断显示,悬停展示完整信息) -->
<div class="ticket-doctor" :title="item.doctor">{{ item.doctor }}</div>
<div
class="ticket-doctor"
:title="item.doctor"
>
{{ item.doctor }}
</div>
<!-- 4. 科室名称 -->
<div class="ticket-department" :title="item.department || '未知科室'">
<div
class="ticket-department"
:title="item.department || '未知科室'"
>
科室:{{ item.department || '未知科室' }}
</div>
<!-- 5. 挂号费 -->
<div class="ticket-fee">挂号费:{{ item.fee }}</div>
<div class="ticket-fee">
挂号费:{{ item.fee }}
</div>
<!-- 6. 号源类型 -->
<div class="ticket-type">{{ item.ticketType === 'general' ? '普通' : '专家' }}</div>
<div class="ticket-type">
{{ item.ticketType === 'general' ? '普通' : '专家' }}
</div>
<!-- 7. 已预约患者信息 -->
<div v-if="(item.status === '已预约' || item.status === '已取号') && item.patientName" class="ticket-patient">
<div
v-if="(item.status === '已预约' || item.status === '已取号') && item.patientName"
class="ticket-patient"
>
{{ item.patientName }}({{ item.patientId }},{{ getGenderText(item.gender || item.patientGender) }})
</div>
<div class="ticket-actions">
<button class="action-button book-button" @click="openPatientSelectModal(item.slot_id)" :disabled="item.status !== '未预约'" :class="{ 'disabled': item.status !== '未预约' }">
<i class="el-icon-tickets"></i>
<button
class="action-button book-button"
:disabled="item.status !== '未预约'"
:class="{ 'disabled': item.status !== '未预约' }"
@click="openPatientSelectModal(item.slot_id)"
>
<i class="el-icon-tickets" />
预约
</button>
</div>
</div>
</div>
<div class="pagination-container" v-if="totalTickets > 0">
<div
v-if="totalTickets > 0"
class="pagination-container"
>
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
@@ -149,33 +315,63 @@
@size-change="handlePageSizeChange"
/>
</div>
<div v-if="filteredTickets.length === 0" class="empty-state">
<div class="empty-text">暂无号源数据</div>
<div
v-if="filteredTickets.length === 0"
class="empty-state"
>
<div class="empty-text">
暂无号源数据
</div>
</div>
</div>
</div>
<!-- 患者选择弹窗 -->
<div id="patient-select-modal" class="modal" v-if="showPatientModal">
<div
v-if="showPatientModal"
id="patient-select-modal"
class="modal"
>
<div class="modal-content">
<div class="modal-header">
<h3>选择患者</h3>
<button class="close-btn" @click="closePatientSelectModal">&times;</button>
<button
class="close-btn"
@click="closePatientSelectModal"
>
&times;
</button>
</div>
<div class="modal-body">
<div class="patient-search-toolbar">
<input
id="patient-keyword"
v-model.trim="patientKeyword"
class="search-input patient-keyword-input"
placeholder="姓名/就诊卡号/手机号/证件号回车查询"
v-model.trim="patientKeyword"
@keyup.enter="searchPatients"
>
<button id="patient-search-btn" class="search-btn" @click="searchPatients">查询</button>
<button id="patient-reset-btn" class="reset-btn" @click="resetPatientSearch">重置</button>
<button
id="patient-search-btn"
class="search-btn"
@click="searchPatients"
>
查询
</button>
<button
id="patient-reset-btn"
class="reset-btn"
@click="resetPatientSearch"
>
重置
</button>
</div>
<div class="patient-table-container">
<table id="patient-table" class="patient-table" v-if="patients.length > 0">
<table
v-if="patients.length > 0"
id="patient-table"
class="patient-table"
>
<thead>
<tr>
<th>序号</th>
@@ -201,21 +397,40 @@
<td>{{ patient.idCard }}</td>
<td>{{ patient.phone }}</td>
<td>
<button class="select-btn" @click.stop="selectPatient(patient._rowKey)" :disabled="!patient._rowKey">选择</button>
<button
class="select-btn"
:disabled="!patient._rowKey"
@click.stop="selectPatient(patient._rowKey)"
>
选择
</button>
</td>
</tr>
</tbody>
</table>
<!-- 无搜索结果提示 -->
<div v-else-if="hasSearchCriteria && !isLoading" class="no-results">
<div
v-else-if="hasSearchCriteria && !isLoading"
class="no-results"
>
未找到符合条件的患者,请检查搜索条件
</div>
</div>
</div>
<div class="modal-footer">
<button class="confirm-btn" @click="confirmPatientSelection">确认</button>
<button class="cancel-btn" @click="closePatientSelectModal">取消</button>
<button
class="confirm-btn"
@click="confirmPatientSelection"
>
确认
</button>
<button
class="cancel-btn"
@click="closePatientSelectModal"
>
取消
</button>
</div>
</div>
</div>
@@ -230,9 +445,13 @@
@click.stop
@contextmenu.prevent
>
<div v-if="selectedTicketForCancel && selectedTicketForCancel.status === '已预约'" class="menu-item" @click="confirmCancelAppointment">
取消预约
</div>
<div
v-if="selectedTicketForCancel && selectedTicketForCancel.status === '已预约'"
class="menu-item"
@click="confirmCancelAppointment"
>
取消预约
</div>
</div>
<!-- 点击页面其他地方关闭右键菜单 -->
@@ -241,7 +460,7 @@
class="context-menu-overlay"
@click="closeContextMenu"
@contextmenu.prevent
></div>
/>
</div>
</template>
@@ -341,6 +560,22 @@ export default {
return !!this.patientKeyword?.trim();
}
},
mounted() {
document.addEventListener('click', this.closeContextMenu);
// 初始化数据
this.selectedDate = new Date().toISOString().split('T')[0];
// 调用onSearch获取初始数据
this.onSearch();
// 检测是否为移动设备
this.checkMobileDevice();
// 监听窗口大小变化
window.addEventListener('resize', this.checkMobileDevice);
},
beforeUnmount() {
document.removeEventListener('click', this.closeContextMenu);
// 移除窗口大小变化监听
window.removeEventListener('resize', this.checkMobileDevice);
},
methods: {
selectDoctor(doctorId) {
this.selectedDoctorId = this.selectedDoctorId === doctorId ? null : doctorId;
@@ -903,22 +1138,6 @@ export default {
this.departments = [{ value: 'all', label: '全部科室' }];
}
}
},
mounted() {
document.addEventListener('click', this.closeContextMenu);
// 初始化数据
this.selectedDate = new Date().toISOString().split('T')[0];
// 调用onSearch获取初始数据
this.onSearch();
// 检测是否为移动设备
this.checkMobileDevice();
// 监听窗口大小变化
window.addEventListener('resize', this.checkMobileDevice);
},
beforeUnmount() {
document.removeEventListener('click', this.closeContextMenu);
// 移除窗口大小变化监听
window.removeEventListener('resize', this.checkMobileDevice);
}
}
</script>