feat(menu): 优化菜单路径唯一性校验并更新前端界面

- 在SysLoginController中添加optionMap数据返回
- 添加JSQLParser依赖支持MyBatis Plus功能
- 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验
- 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑
- 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询
- 在前端路由中注释患者管理相关路由配置
- 在用户store中添加optionMap配置项并优先从optionMap获取医院名称
- 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计
- 更新检查项目设置页面的导航栏样式和交互体验
- 优化门诊记录页面的搜索条件和表格展示功能
- 添加性别和状态筛选条件并改进数据加载逻辑
This commit is contained in:
2026-01-03 23:47:09 +08:00
parent 61f4020487
commit 0c35044231
54 changed files with 5871 additions and 510 deletions

View File

@@ -76,32 +76,51 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="surgeryList" row-key="id">
<el-table-column label="手术编号" align="center" prop="surgeryNo" width="150" />
<el-table v-loading="loading" :data="surgeryList" row-key="id" :row-class-name="getRowClassName">
<!-- 申请日期datetime - 2025-09-19 14:15:00 - 不可操作 -->
<el-table-column label="申请日期" align="center" prop="createTime" width="180">
<template #default="scope">
{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
</template>
</el-table-column>
<!-- 手术单号string - OP2025092003 - 可查看详情 -->
<el-table-column label="手术单号" align="center" prop="surgeryNo" width="150" show-overflow-tooltip />
<!-- 患者姓名string - 张小明 - 不可操作 -->
<el-table-column label="患者姓名" align="center" prop="patientName" width="100" />
<el-table-column label="性别" align="center" prop="patientGender" width="60" />
<el-table-column label="年龄" align="center" prop="patientAge" width="60" />
<!-- 申请医生string - 张医生 - 不可操作 -->
<el-table-column label="申请医生" align="center" prop="applyDoctorName" width="100" />
<!-- 申请科室string - 普外科 - 不可操作 -->
<el-table-column label="申请科室" align="center" prop="applyDeptName" width="120" show-overflow-tooltip />
<!-- 手术名称string - 腹腔镜胆囊切除术 - 不可操作 -->
<el-table-column label="手术名称" align="center" prop="surgeryName" min-width="150" show-overflow-tooltip />
<el-table-column label="手术类型" align="center" prop="surgeryTypeEnum_dictText" width="100" />
<!-- 手术等级string - 三级手术 - 不可操作 -->
<el-table-column label="手术等级" align="center" prop="surgeryLevel_dictText" width="100" />
<el-table-column label="手术状态" align="center" prop="statusEnum_dictText" width="100">
<!-- 状态badge - 已安排 - 不可操作 -->
<el-table-column label="状态" align="center" prop="statusEnum_dictText" width="100">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.statusEnum)">
{{ scope.row.statusEnum_dictText }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="计划时间" align="center" prop="plannedTime" width="160" />
<el-table-column label="主刀医生" align="center" prop="mainSurgeonName" width="100" />
<el-table-column label="麻醉医生" align="center" prop="anesthetistName" width="100" />
<el-table-column label="手术室" align="center" prop="operatingRoomName" width="120" />
<el-table-column label="执行科室" align="center" prop="orgName" width="120" show-overflow-tooltip />
<!-- 操作action - 查看/编辑/删除 - 可操作 -->
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<!-- 查看显示手术申请详情只读模式 -->
<el-button link type="primary" @click="handleView(scope.row)">查看</el-button>
<el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.statusEnum === 0 || scope.row.statusEnum === 1">编辑</el-button>
<el-button link type="primary" @click="handleStart(scope.row)" v-if="scope.row.statusEnum === 1">开始</el-button>
<el-button link type="primary" @click="handleComplete(scope.row)" v-if="scope.row.statusEnum === 2">完成</el-button>
<!-- 编辑修改手术申请信息只有状态为新开的能修改 -->
<el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.statusEnum === 0">编辑</el-button>
<!-- 删除取消手术申请作废 -->
<el-button link type="danger" @click="handleDelete(scope.row)" v-if="scope.row.statusEnum === 0 || scope.row.statusEnum === 1">删除</el-button>
</template>
</el-table-column>
@@ -449,6 +468,7 @@ const queryParams = ref({
})
const open = ref(false)
const viewOpen = ref(false)
const isEditMode = ref(false)
const form = ref({
id: undefined,
patientId: undefined,
@@ -614,8 +634,17 @@ function handleAdd() {
}
function handleEdit(row) {
// 检查状态只有状态为新开0时才允许编辑
if (row.statusEnum !== 0) {
proxy.$modal.msgWarning('当前状态不允许编辑手术,仅新开状态可编辑')
return
}
title.value = '编辑手术'
open.value = true
// 设置为编辑模式
isEditMode.value = true
getSurgeryDetail(row.id).then(res => {
if (res.code === 200) {
Object.assign(form.value, res.data)
@@ -685,37 +714,63 @@ function submitForm() {
proxy.$refs['surgeryRef'].validate((valid) => {
if (valid) {
if (form.value.id == undefined) {
// 新增手术
addSurgery(form.value).then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getPageList()
}).catch(error => {
console.error('新增手术失败:', error)
proxy.$modal.msgError('新增手术失败,请稍后重试')
// 显示红色 toast 提示
proxy.$message.error('新增手术失败,请检查表单信息')
})
} else {
// 修改手术
updateSurgery(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getPageList()
}).catch(error => {
console.error('更新手术失败:', error)
proxy.$modal.msgError('更新手术失败,请稍后重试')
// 显示红色 toast 提示
proxy.$message.error('更新手术失败,请检查表单信息')
})
}
} else {
// 表单校验失败 - 显示红色 toast 提示
proxy.$message.error('请检查表单信息,标红字段为必填项')
}
})
}
function handleDelete(row) {
proxy.$modal.confirm('是否确认删除手术"' + row.surgeryName + '"?').then(() => {
return deleteSurgery(row.id)
}).then(() => {
getPageList()
proxy.$modal.msgSuccess('删除成功')
}).catch(error => {
console.error('删除手术失败:', error)
})
// 检查状态
if (row.statusEnum === 0) {
// 新开状态 - 直接删除
proxy.$modal.confirm('是否确认删除手术"' + row.surgeryName + '"?').then(() => {
return deleteSurgery(row.id)
}).then(() => {
getPageList()
proxy.$modal.msgSuccess('删除成功')
}).catch(error => {
console.error('删除手术失败:', error)
proxy.$modal.msgError('删除失败')
})
} else if (row.statusEnum === 1) {
// 已排期状态 - 更新为已取消
proxy.$modal.confirm('是否确认取消手术"' + row.surgeryName + '"?').then(() => {
return updateSurgeryStatus(row.id, 4) // 4 = 已取消
}).then(() => {
getPageList()
proxy.$modal.msgSuccess('手术已取消')
}).catch(error => {
console.error('取消手术失败:', error)
proxy.$modal.msgError('取消失败')
})
} else {
// 其他状态 - 不允许操作
proxy.$modal.msgWarning('当前状态不允许取消手术')
}
}
function handleStart(row) {
@@ -756,4 +811,57 @@ function getStatusType(status) {
}
return typeMap[status] || 'info'
}
// 获取表格行样式
function getRowClassName({ row }) {
return row.statusEnum === 4 ? 'cancelled-row' : ''
}
// 时间格式化函数
function parseTime(time, pattern) {
if (!time) return ''
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
return value.toString().padStart(2, '0')
})
return time_str
}
</script>
<style scoped>
/* 已取消行的样式 */
:deep(.cancelled-row) {
background-color: #f5f5f5;
color: #999;
}
:deep(.cancelled-row .el-button--danger) {
display: none;
}
</style>