@@ -7,65 +7,46 @@
< el-option label = "科室" :value = "2" > < / el-option >
< el-option label = "全院" :value = "3" > < / el-option >
< / el-select >
< el-input
v-model = "searchKeyword"
placeholder = "请输入名称"
style = "width: 240px; margin-left: 10px;"
@keyup.enter ="handleSearch"
> < / el-input >
< el-button style = "margin-left: 10px;" @click ="handleSearch" > < el -icon > < Search / > < / el-icon > 查询 < / el-button >
< el-button style = "margin-left: 10px;" @click ="handleReset" > < el -icon > < Refresh / > < / el-icon > 重置 < / el-button >
< el-button type = "primary" style = "margin-left: 10px;" @click ="showAddDialog" > < el -icon > < Plus / > < / el-icon > 增加 < / el-button >
< el-input v-model = "searchKeyword" placeholder="请输入名称" style="width: 240px; margin-left: 10px;"
@keyup.enter ="handleSearch" > < / el -input >
< el-button style = "margin-left: 10px;" @click ="handleSearch" > < el -icon >
< Search / >
< / el-icon > 查询 < / el-button >
< el-button style = "margin-left: 10px;" @click ="handleReset" > < el -icon >
< Refresh / >
< / el-icon > 重置 < / el-button >
< el-button type = "primary" style = "margin-left: 10px;" @click ="showAddDialog" > < el -icon >
< Plus / >
< / el-icon > 增加 < / el-button >
< / div >
<!-- 表格 -- >
< el-table :data = "tableData" style = "width: 100%; margin-top: 20px;" >
< el-table-column prop = "sortNo" label = "排序号" width = "200" >
< template # default = "scope" >
< el-input-number
v-if = "editingId === scope.row.id"
v-model = "editForm.sortNo"
:min = "1"
:step = "1"
style = "width: 100%"
/ >
< el-input-number v-if = "editingId === scope.row.id" v-model="editForm.sortNo" :min="1" :step="1"
style = "width: 100%" / >
< span v-else > {{ scope.row.sortNo }} < / span >
< / template >
< / el -table -column >
< el-table-column prop = "phraseName" label = "名称" width = "250" >
< template # default = "scope" >
< el-input
v-if = "editingId === scope.row.id"
v-model = "editForm.phraseName"
placeholder = "请输入名称(不超过50字)"
maxlength = "50"
show -word -limit
style = "width: 100%"
/ >
< el-input v-if = "editingId === scope.row.id" v-model="editForm.phraseName" placeholder="请输入名称(不超过50字)"
maxlength = "50" show -word -limit style = "width: 100%" / >
< span v-else > {{ scope.row.phraseName }} < / span >
< / template >
< / el -table -column >
< el-table-column prop = "phraseContent" label = "内容" >
< template # default = "scope" >
< el-input
v-if = "editingId === scope.row.id"
v-model = "editForm.phraseContent"
placeholder = "请输入内容"
type = "textarea"
:rows = "3"
style = "width: 100%"
/ >
< el-input v-if = "editingId === scope.row.id" v-model="editForm.phraseContent" placeholder="请输入内容"
type = "textarea" :rows = "3" style = "width: 100%;" / >
< span v-else > {{ scope.row.phraseContent }} < / span >
< / template >
< / el -table -column >
< el-table-column label = "范围" width = "250" >
< template # default = "scope" >
< el-select
v-if = "editingId === scope.row.id"
v-model = "editForm.phraseType"
placeholder = "请选择范围"
style = "width: 100%"
>
< el-select v-if = "editingId === scope.row.id" v-model="editForm.phraseType" placeholder="请选择范围"
style = "width: 100%" >
< el-option label = "个人" :value = "1" > < / el-option >
< el-option label = "科室" :value = "2" > < / el-option >
< el-option label = "全院" :value = "3" > < / el-option >
@@ -73,21 +54,13 @@
< span v-else > {{ getScopeName ( scope.row.phraseType ) }} < / span >
< / template >
< / el -table -column >
<!-- 【 修改1 】 业务分类列 : 删除硬编码的 “ 病愈 ” 选项 , 统一用枚举 -- >
< el-table-column label = "业务分类" width = "200" >
< template # default = "scope" >
< el-select
v-if = "editingId === scope.row.id"
v-model = "editForm.phraseCategory "
placeholder = "请选择业务分类"
style = "width: 100%"
>
< el-option label = "病愈" value = "12" > < / el-option >
< el-option
v-for = "item in businessclassification"
:key = "item.value"
:label = "item.label"
:value = "item.value"
> < / el-option >
< el-select v-if = "editingId === scope.row.id" v-model="editForm.phraseCategory" placeholder="请选择业务分类"
style = "width: 100%" >
< el-option v-for = "item in businessTypeOptions" :key="item.value" :label="item.label "
:value = "item.value" > < / el-option >
< / el-select >
< span v-else > {{ getBusinessTypeName ( scope.row.phraseCategory ) }} < / span >
< / template >
@@ -96,37 +69,23 @@
< template # default = "scope" >
<!-- 编辑状态 -- >
< template v-if = "editingId === scope.row.id" >
< el -button
type = "success"
size = "small"
@click ="handleSave"
>
< el-icon > < Check / > < / el-icon > 保存
< el -button type = "success" size = "small" @click ="handleSave" >
< el -icon >
< Check / >
< / el-icon > 保存
< / el-button >
< el-button
type = "warning"
size = "small"
style = "margin-left: 5px;"
@click ="handleCancel"
>
< el-icon > < Close / > < / el-icon > 取消
< el-button type = "warning" size = "small" style = "margin-left: 5px;" @click ="handleCancel" >
< el -icon >
< Close / >
< / el-icon > 取消
< / el-button >
< / template >
<!-- 非编辑状态 -- >
< template v-else >
< el -button
type = "primary"
size = "small"
@click ="handleEdit(scope.row)"
>
< el -button type = "primary" size = "small" @click ="handleEdit(scope.row)" >
编辑
< / el -button >
< el-button
type = "danger"
size = "small"
style = "margin-left: 5px;"
@click ="handleDelete(scope.row)"
>
< el-button type = "danger" size = "small" style = "margin-left: 5px;" @click ="handleDelete(scope.row)" >
删除
< / el -button >
< / template >
@@ -136,54 +95,34 @@
<!-- 分页 -- >
< div class = "pagination-container" >
< el-pagination
@ size -change = " handleSizeChange "
@ current -change = " handleCurrentChange "
:current-page = "currentPage"
: page -sizes = " [ 15 , 30 , 50 ] "
:page-size = "pageSize"
layout = "total, prev, pager, next, jumper, sizes"
:total = "total"
> < / el-pagination >
< el-pagination @ size -change = " handleSizeChange " @ current -change = " handleCurrentChange " :current-page = "currentPage"
: page -sizes = " [ 15 , 30 , 50 ] " :page-size = "pageSize" layout = "total, prev, pager, next, jumper, sizes "
:total = "total" > < / el-pagination >
< / div >
<!-- 新增模态框 -- >
< el-dialog
v-model = "addDialogVisible"
title = "新增医生常用语"
width = "600px"
center
>
< el-form ref = "addFormRef" :model = "addForm" :rules = "rules" label -width = " 100px " class = "add-form" >
< el-form-item label = "名称" prop = "phraseName" required >
< el-input v-model = "addForm.phraseName" placeholder="请输入常用语名称(不超过50字)" maxlength="50" show-word-limit style="width: 100%;" > < / el -input >
< el-dialog v-model = "addDialogVisible" title="新增医生常用语" width="600px" center >
<!-- 【 修改2 】 绑定编辑表单的ref和验证规则 -- >
< el-form ref = "addFormRef" :model = "addForm" :rules = "addRules" label -width = " 100px " class = "add-form" >
< el-form-item label = "名称" prop = "phraseName" >
< el-input v-model = "addForm.phraseName" placeholder="请输入常用语名称(不超过50字)" maxlength="50" show -word -limit
style = "width: 100%;" > < / el-input >
< / el-form-item >
< el-form-item label = "内容" prop = "phraseContent" required >
< el-input
v-model = "addForm.phraseContent"
placeholder = "请输入常用语内容"
type = "textarea"
:rows = "4"
style = "width: 100%;"
> < / el-input >
< el-form-item label = "内容" prop = "phraseContent" >
< el-input v-model = "addForm.phraseContent" placeholder="请输入常用语内容" type="textarea" :rows="4"
style = "width: 100%;" > < / el-input >
< / el-form-item >
< el-form-item label = "排序号" >
< el-input-number v-model = "addForm.sortNo" :min="1" :step="1" style="width: 100%;" > < / el -input -number >
< / el-form-item >
< el-form-item label = "业务分类" >
<!-- 【 修改3 】 新增表单业务分类 : 删除硬编码 “ 病愈 ” , 用枚举 -- >
< el-form-item label = "业务分类" prop = "phraseCategory" >
< el-select v-model = "addForm.phraseCategory" placeholder="请选择业务分类" style="width: 100%;" >
<! - - 默认添加 " 病愈 " 选项 - - >
< el-option label = "病愈" value = "12 "> < / el-option >
<!-- 从数据字典获取其他选项 -- >
< el-option
v-for = "item in businessclassification"
:key = "item.value"
:label = "item.label"
:value = "item.value"
> < / el-option >
<el -option v-for = "item in businessTypeOptions" :key="item.value" :label="item.label"
:value = "item.value "> < / el-option >
< / el-select >
< / el-form-item >
< el-form-item label = "范围" >
< el-form-item label = "范围" prop = "phraseType" >
< el-select v-model = "addForm.phraseType" placeholder="请选择范围" style="width: 100%;" >
< el -option label = "个人" :value = "1" > < / el-option >
< el-option label = "科室" :value = "2" > < / el-option >
@@ -212,7 +151,17 @@ import {
updateDoctorPhrase
} from './api'
import { ElMessage , ElMessageBox } from 'element-plus'
import { useDict } from '@/utils/ dict'
// 【修改4】如果数据字典未对齐后端枚举, 暂时注释useDict, 改用固定枚举( 后续可替换为 dict)
// import { useDict } from '@/utils/dict'
// 【核心修改】定义和后端枚举对齐的业务分类选项( 替换原businessclassification)
const businessTypeOptions = ref ( [
{ label : '主诉' , value : 'MAIN_COMPLAINT' } ,
{ label : '现病史' , value : 'PRESENT_HISTORY' } ,
{ label : '术前' , value : 'PRE_OPERATION' } ,
{ label : '术后' , value : 'POST_OPERATION' } ,
{ label : '既往史' , value : 'PAST_HISTORY' }
] )
// 搜索条件
const searchScope = ref ( null ) // null表示未选择, 数字类型: 1=个人, 2=科室, 3=全院
@@ -229,50 +178,61 @@ const total = ref(0)
// 新增模态框相关
const addDialogVisible = ref ( false )
const addFormRef = ref ( )
// 【修改5】新增表单默认值: 删除“病愈”硬编码, 业务分类默认空
const addForm = ref ( {
phraseName : '' ,
phraseContent : '' ,
sortNo : 1 ,
phraseType : 1 ,
phraseCategory : '病愈 '
phraseCategory : '' // 业务分类默认空,强制用户选择
} )
// 表单验证规则
const r ules = {
// 【修改6】完善新增表单验证规则( 补充业务分类必填)
const addR ules = {
phraseName : [
{ required : true , message : '请输入常用语名称' , trigger : 'blur' }
{ required : true , message : '请输入常用语名称' , trigger : 'blur' } ,
{ max : 50 , message : '常用语名称不能超过50字' , trigger : 'blur' }
] ,
phraseContent : [
{ required : true , message : '请输入常用语内容' , trigger : 'blur' }
] ,
phraseType : [
{ required : true , message : '请选择范围' , trigger : 'change' }
] ,
phraseCategory : [
{ required : true , message : '请选择业务分类' , trigger : 'change' }
]
}
// 编辑状态管理
const editingId = ref ( null )
const editForm = ref ( { } )
// 【修改7】完善编辑表单验证规则
const editRules = {
phraseName : [
{ required : true , message : '请输入常用语名称' , trigger : 'blur' }
{ required : true , message : '请输入常用语名称' , trigger : 'blur' } ,
{ max : 50 , message : '常用语名称不能超过50字' , trigger : 'blur' }
] ,
phraseContent : [
{ required : true , message : '请输入常用语内容' , trigger : 'blur' }
] ,
phraseType : [
{ required : true , message : '请选择范围' , trigger : 'change' }
] ,
phraseCategory : [
{ required : true , message : '请选择业务分类' , trigger : 'change' }
]
}
// 获取业务分类数据字典
const { businessclassification } = useDict( 'businessclassification')
// 【废弃】原数据字典( 后续如需对接dict, 需确保dict的value是后端编码: MAIN_COMPLAINT等)
// const { businessclassification } = useDict( 'businessclassification')
// 获取业务分类名称
const getBusinessTypeName = ( category ) => {
// 直接返回后端返回的phrase_category字段值
// 从数据库截图看, phrase_category已经是中文名称: "主诉"、"现病史"、"术后"等
if ( category ) {
return category
}
return '未知类型'
// 【修改8】重构业务分类名称转换方法( 适配后端编码→中文)
const getBusinessTypeName = ( code ) => {
if ( ! code ) return '未知类型'
// 从枚举选项中匹配编码,返回中文名称
const item = businessTypeOptions . value . find ( item => item . value === code )
return item ? item . label : '未知类型'
}
// 获取范围名称
@@ -302,7 +262,7 @@ const validatePhraseName = (phraseName, excludeId = null) => {
if ( excludeId && item . id === excludeId ) {
return false
}
return item . phraseName === phraseName . trim ( )
return item . phraseName . trim ( ) === phraseName . trim ( )
} )
if ( existingPhrase ) {
@@ -323,7 +283,7 @@ const fetchDoctorPhraseList = async () => {
if ( response . code === 200 && response . data && response . data . data ) {
// 按照sortNo由小到大排序
allData . value = response . data . data . sort ( ( a , b ) => a . sortNo - b . sortNo )
total . value = response . d ata. data . length
total . value = allD ata. value . length
// 执行客户端分页
applyPagination ( )
} else {
@@ -332,6 +292,7 @@ const fetchDoctorPhraseList = async () => {
total . value = 0
}
} catch ( error ) {
console . error ( '获取列表失败:' , error ) // 【优化】增加控制台日志便于调试
ElMessage . error ( '获取数据失败: 网络请求错误' )
allData . value = [ ]
total . value = 0
@@ -343,7 +304,8 @@ const handleReset = () => {
// 重置搜索条件
searchScope . value = null
searchKeyword . value = ''
// 重置分页到第一页
currentPage . value = 1
// 重新加载所有数据
fetchDoctorPhraseList ( )
}
@@ -370,18 +332,15 @@ const handleCurrentChange = (val) => {
const handleSearch = async ( ) => {
try {
// searchScope可能是null( 未选择) 、1=个人, 2=科室, 3=全院
const searchScopeV alue = searchScope . value
const phraseType = searchScopeValue === null ? undefined : searchScopeValue
const phraseType = searchScope. v alue === null ? undefined : searchScope . value
// 调用搜索接口: phraseName, phraseType
// 如果phraseType为undefined, 则后端不会按范围过滤, 查询所有数据
const response = await searchDoctorPhraseList ( searchKeyword . value , phraseType )
// 处理后端返回的数据结构: data.data
if ( response . code === 200 && response . data && response . data . data ) {
// 按照sortNo由小到大排序
allData . value = response . data . data . sort ( ( a , b ) => a . sortNo - b . sortNo )
total . value = response . d ata. data . length
total . value = allD ata. value . length
currentPage . value = 1 // 搜索后重置到第一页
applyPagination ( ) // 应用分页
} else {
@@ -390,6 +349,7 @@ const handleSearch = async () => {
total . value = 0
}
} catch ( error ) {
console . error ( '搜索失败:' , error )
ElMessage . error ( '搜索失败: 网络请求错误' )
allData . value = [ ]
total . value = 0
@@ -404,7 +364,11 @@ const showAddDialog = () => {
phraseContent : '' ,
sortNo : 1 ,
phraseType : 1 ,
phraseCategory : '病愈 '
phraseCategory : '' // 【修改9】默认空, 强制选择
}
// 重置表单验证状态
if ( addFormRef . value ) {
addFormRef . value . clearValidate ( )
}
// 打开模态框
addDialogVisible . value = true
@@ -413,8 +377,9 @@ const showAddDialog = () => {
// 提交新增表单
const handleAdd = async ( ) => {
try {
// 验证表单
await addFormRef . value . validate ( )
// 先执行表单 验证
const validateResult = await addFormRef . value . validate ( )
if ( ! validateResult ) return
// 名称唯一性校验
const nameValidation = validatePhraseName ( addForm . value . phraseName )
@@ -426,11 +391,11 @@ const handleAdd = async () => {
// 添加数据库要求的必填默认字段
const formData = {
... addForm . value ,
phraseCode : 'PHR000' ,
phraseCode : 'PHR000' , // 建议后端自动生成,前端可传空
enableFlag : 1 ,
staffId : 1001 ,
deptCode : 'DEPT001' ,
creatorId : 1001
staffId : 1001 , // 建议从登录态获取,不要硬编码
deptCode : 'DEPT001' , // 建议从登录态获取
creatorId : 1001 // 建议从登录态获取
}
// 调用新增接口
@@ -439,28 +404,16 @@ const handleAdd = async () => {
// 处理新增结果
if ( response . code === 200 ) {
ElMessage . success ( '新增成功' )
// 关闭模态框
addDialogVisible . value = false
// 将新数据添加到数组开头,使新增的数据在表格最上方显示
const newData = {
... formData ,
id : response . data . id || Date . now ( ) // 使用后端返回的id或当前时间戳作为临时id
}
allData . value . unshift ( newData )
total . value = allData . value . length
// 重新应用分页
applyPagination ( )
// 重新拉取数据( 比手动unshift更可靠, 避免数据不一致)
fetchDoctorPhraseList ( )
} else {
ElMessage . error ( '新增失败: ' + ( response . msg || '未知错误' ) )
}
} catch ( error ) {
console . error ( '新增失败:' , error )
// 表单验证失败或其他错误
if ( error instanceof Error ) {
ElMessage . error ( '请填写完整信息或网络请求错误' )
} else {
// 表单验证失败的情况
ElMessage . error ( '请填写完整信息' )
}
ElMessage . error ( '新增失败: 请填写完整信息或网络异常' )
}
}
@@ -468,33 +421,31 @@ const handleAdd = async () => {
const handleDelete = async ( row ) => {
try {
// 弹出确认对话框
await ElMessageBox . confirm ( '确定要删除该常用语吗?' , '删除确认' , {
await ElMessageBox . confirm (
'确定要删除该常用语吗?删除后无法恢复!' ,
'删除确认' ,
{
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning'
} )
}
)
// 调用删除接口
const response = await deleteDoctorPhrase ( row . id )
// 处理删除结果
if ( response . code === 200 ) {
ElMessage . success ( '删除成功' )
// 重新获 取数据以更新界面
// 重新拉 取数据
fetchDoctorPhraseList ( )
} else {
ElMessage . error ( '删除失败: ' + ( response . msg || '未知错误' ) )
}
} catch ( error ) {
// 如果 用户取消删除,不显 示错误信息
if ( error !== 'cancel' && error !== undefined ) {
if ( error . msg ) {
ElMessage . error ( '删除操作失败: ' + error . msg )
} else if ( error instanceof Error ) {
ElMessage . error ( '删除操作失败: 网络请求错误' )
} else {
ElMessage . error ( '删除操作失败: 未知错误' )
}
// 用户取消删除时不提 示错误
if ( error !== 'cancel' ) {
console . error ( '删除失败:' , error )
ElMessage . error ( '删除操作失败: 网络异常或权限不足' )
}
}
}
@@ -503,29 +454,33 @@ const handleDelete = async (row) => {
const handleEdit = ( row ) => {
// 进入编辑状态
editingId . value = row . id
// 复制当前行数据到编辑表单
editForm . value = {
... row ,
// 确保phraseCategory和phraseType类型正确
phraseCategory : row . phraseCategory ,
phraseType : row . phraseType
}
// 复制当前行数据到编辑表单(深拷贝避免原数据被修改)
editForm . value = JSON . parse ( JSON . stringify ( row ) )
// 确保类型正确
editForm . value . sortNo = Number ( editForm . value . sortNo ) || 1
editForm . value . phraseType = Number ( editForm . value . phraseType ) || 1
}
// 取消编辑
const handleCancel = ( ) => {
// 退出编辑状态
editingId . value = null
// 清空编辑表单
editForm . value = { }
}
// 保存编辑
const handleSave = async ( ) => {
try {
// 验证表单数据
// 基础非空校 验
if ( ! editForm . value . phraseName || ! editForm . value . phraseContent ) {
ElMessage . error ( '请填写完整信息 ' )
ElMessage . error ( '请填写名称和内容 ' )
return
}
if ( ! editForm . value . phraseCategory ) {
ElMessage . error ( '请选择业务分类' )
return
}
if ( ! editForm . value . phraseType ) {
ElMessage . error ( '请选择范围' )
return
}
@@ -539,25 +494,23 @@ const handleSave = async () => {
// 准备更新数据
const updateData = {
... editForm . value ,
enableFlag : 1 // 确保启用状态
enableFlag : 1 ,
updateTime : new Date ( ) . toISOString ( ) // 可选:前端临时赋值,后端最终以自己的为准
}
// 调用更新接口
const response = await updateDoctorPhrase ( updateData )
// 处理更新结果
if ( response . code === 200 ) {
ElMessage . success ( '更新成功' )
// 退出编辑状态
editingId . value = null
// 清空编辑表单
editForm . value = { }
// 重新获取数据以更新界面
fetchDoctorPhraseList ( )
} else {
ElMessage . error ( '更新失败: ' + ( response . msg || '未知错误' ) )
}
} catch ( error ) {
console . error ( '更新失败:' , error )
ElMessage . error ( '更新操作失败: 网络请求错误' )
}
}
@@ -577,6 +530,10 @@ onMounted(() => {
display : flex ;
align - items : center ;
margin - bottom : 20 px ;
flex - wrap : wrap ;
/* 【优化】适配小屏幕,防止按钮换行溢出 */
gap : 10 px ;
/* 替换margin-left, 更优雅的间距 */
}
. pagination - container {
@@ -584,4 +541,9 @@ onMounted(() => {
display : flex ;
justify - content : flex - end ;
}
/* 【优化】新增表单样式适配 */
. add - form {
padding : 10 px 0 ;
}
< / style >