From ae96bbd0bb31d65c93dac2db49ae4b8d63f95cf1 Mon Sep 17 00:00:00 2001 From: sindir Date: Mon, 19 Jan 2026 17:25:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BB=E7=94=9F=E5=B8=B8=E7=94=A8=E8=AF=AD?= =?UTF-8?q?=E7=AE=A1=E7=90=86=20-=20=E8=A1=8C=E5=86=85=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E5=BC=B9=E7=AA=97=E7=BC=96=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BC=96=E8=BE=91=E4=BD=93=E9=AA=8C=E3=80=82?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=BE=91=E5=BC=B9=E7=AA=97=EF=BC=8C?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=9B=9E=E6=98=BE=E6=95=B0=E6=8D=AE=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=9B=B4=E4=BE=BF=E6=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../doctorstation/doctorphrase/index.vue | 244 ++++++++---------- 1 file changed, 110 insertions(+), 134 deletions(-) diff --git a/openhis-ui-vue3/src/views/doctorstation/doctorphrase/index.vue b/openhis-ui-vue3/src/views/doctorstation/doctorphrase/index.vue index cea611dd..0d61d84a 100644 --- a/openhis-ui-vue3/src/views/doctorstation/doctorphrase/index.vue +++ b/openhis-ui-vue3/src/views/doctorstation/doctorphrase/index.vue @@ -23,72 +23,30 @@ - - - - + @@ -102,7 +60,6 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -151,10 +143,10 @@ import { updateDoctorPhrase } from './api' import { ElMessage, ElMessageBox } from 'element-plus' -// 【修改4】如果数据字典未对齐后端枚举,暂时注释useDict,改用固定枚举(后续可替换为dict) +// 如果数据字典未对齐后端枚举,暂时注释useDict,改用固定枚举(后续可替换为dict) // import { useDict } from '@/utils/dict' -// 【核心修改】定义和后端枚举对齐的业务分类选项(替换原businessclassification) +// 核心配置:定义和后端枚举对齐的业务分类选项(替换原businessclassification) const businessTypeOptions = ref([ { label: '主诉', value: 'MAIN_COMPLAINT' }, { label: '现病史', value: 'PRESENT_HISTORY' }, @@ -170,24 +162,24 @@ const searchKeyword = ref('') // 表格数据 const tableData = ref([]) -// 分页 +// 分页参数配置 const currentPage = ref(1) const pageSize = ref(15) const total = ref(0) -// 新增模态框相关 +// 新增模态框相关配置 const addDialogVisible = ref(false) const addFormRef = ref() -// 【修改5】新增表单默认值:删除“病愈”硬编码,业务分类默认空 +// 新增表单默认值:业务分类默认空,强制用户选择 const addForm = ref({ phraseName: '', phraseContent: '', sortNo: 1, phraseType: 1, - phraseCategory: '' // 业务分类默认空,强制用户选择 + phraseCategory: '' }) -// 【修改6】完善新增表单验证规则(补充业务分类必填) +// 完善新增表单验证规则(补充业务分类必填、名称50字限制) const addRules = { phraseName: [ { required: true, message: '请输入常用语名称', trigger: 'blur' }, @@ -204,10 +196,20 @@ const addRules = { ] } -// 编辑状态管理 -const editingId = ref(null) -const editForm = ref({}) -// 【修改7】完善编辑表单验证规则 +// 编辑模态框相关配置 +const editDialogVisible = ref(false) +const editFormRef = ref() +// 编辑表单默认值配置 +const editForm = ref({ + id: '', + phraseName: '', + phraseContent: '', + sortNo: 1, + phraseType: 1, + phraseCategory: '' +}) + +// 完善编辑表单验证规则(和新增一致,保证校验统一) const editRules = { phraseName: [ { required: true, message: '请输入常用语名称', trigger: 'blur' }, @@ -224,18 +226,14 @@ const editRules = { ] } -// 【废弃】原数据字典(后续如需对接dict,需确保dict的value是后端编码:MAIN_COMPLAINT等) -// const { businessclassification } = useDict('businessclassification') - -// 【修改8】重构业务分类名称转换方法(适配后端编码→中文) +// 重构业务分类名称转换方法(适配后端编码→中文展示) const getBusinessTypeName = (code) => { if (!code) return '未知类型' - // 从枚举选项中匹配编码,返回中文名称 const item = businessTypeOptions.value.find(item => item.value === code) return item ? item.label : '未知类型' } -// 获取范围名称 +// 获取范围名称转换方法 const getScopeName = (scope) => { const scopeMap = { 1: '个人', @@ -245,46 +243,41 @@ const getScopeName = (scope) => { return scopeMap[scope] || '未知范围' } -// 名称唯一性校验函数 +// 名称唯一性校验函数(新增/编辑通用,编辑时排除自身ID) const validatePhraseName = (phraseName, excludeId = null) => { if (!phraseName || !phraseName.trim()) { return { valid: false, message: '请输入常用语名称' } } - - // 检查字数限制 + // 检查字数限制,严格控制50字 if (phraseName.trim().length > 50) { return { valid: false, message: '常用语名称不能超过50字' } } - - // 检查名称是否已存在 + // 检查名称是否已存在,编辑时排除当前记录 const existingPhrase = allData.value.find(item => { - // 排除自身(更新时) if (excludeId && item.id === excludeId) { return false } return item.phraseName.trim() === phraseName.trim() }) - if (existingPhrase) { return { valid: false, message: '常用语名称已存在,请输入不同的名称' } } - return { valid: true, message: '' } } -// 所有数据(用于客户端分页) +// 所有数据(用于客户端分页处理) const allData = ref([]) -// 获取医生常用语列表 +// 获取医生常用语列表数据 const fetchDoctorPhraseList = async () => { try { const response = await getDoctorPhraseList() // 处理后端返回的数据结构:data.data if (response.code === 200 && response.data && response.data.data) { - // 按照sortNo由小到大排序 + // 按照sortNo由小到大排序,保证列表顺序正确 allData.value = response.data.data.sort((a, b) => a.sortNo - b.sortNo) total.value = allData.value.length - // 执行客户端分页 + // 执行客户端分页逻辑 applyPagination() } else { ElMessage.error('获取数据失败: ' + (response.msg || '未知错误')) @@ -292,14 +285,14 @@ const fetchDoctorPhraseList = async () => { total.value = 0 } } catch (error) { - console.error('获取列表失败:', error) // 【优化】增加控制台日志便于调试 + console.error('获取列表失败:', error) // 增加控制台日志便于调试 ElMessage.error('获取数据失败: 网络请求错误') allData.value = [] total.value = 0 } } -// 重置功能 +// 重置功能方法 const handleReset = () => { // 重置搜索条件 searchScope.value = null @@ -310,33 +303,32 @@ const handleReset = () => { fetchDoctorPhraseList() } -// 客户端分页处理 +// 客户端分页处理核心方法 const applyPagination = () => { const start = (currentPage.value - 1) * pageSize.value const end = start + pageSize.value tableData.value = allData.value.slice(start, end) } -// 分页处理 +// 分页条数改变事件 const handleSizeChange = (val) => { pageSize.value = val applyPagination() } +// 分页页码改变事件 const handleCurrentChange = (val) => { currentPage.value = val applyPagination() } -// 搜索功能 +// 搜索功能核心方法 const handleSearch = async () => { try { // searchScope可能是null(未选择)、1=个人,2=科室,3=全院 const phraseType = searchScope.value === null ? undefined : searchScope.value - // 调用搜索接口:phraseName, phraseType const response = await searchDoctorPhraseList(searchKeyword.value, phraseType) - if (response.code === 200 && response.data && response.data.data) { // 按照sortNo由小到大排序 allData.value = response.data.data.sort((a, b) => a.sortNo - b.sortNo) @@ -356,15 +348,15 @@ const handleSearch = async () => { } } -// 打开新增模态框 +// 打开新增模态框方法 const showAddDialog = () => { - // 重置表单 + // 重置表单数据 addForm.value = { phraseName: '', phraseContent: '', sortNo: 1, phraseType: 1, - phraseCategory: '' // 【修改9】默认空,强制选择 + phraseCategory: '' } // 重置表单验证状态 if (addFormRef.value) { @@ -374,7 +366,7 @@ const showAddDialog = () => { addDialogVisible.value = true } -// 提交新增表单 +// 提交新增表单方法 const handleAdd = async () => { try { // 先执行表单验证 @@ -400,7 +392,6 @@ const handleAdd = async () => { // 调用新增接口 const response = await addDoctorPhrase(formData) - // 处理新增结果 if (response.code === 200) { ElMessage.success('新增成功') @@ -417,7 +408,7 @@ const handleAdd = async () => { } } -// 删除功能 +// 删除功能方法 const handleDelete = async (row) => { try { // 弹出确认对话框 @@ -430,10 +421,8 @@ const handleDelete = async (row) => { type: 'warning' } ) - // 调用删除接口 const response = await deleteDoctorPhrase(row.id) - if (response.code === 200) { ElMessage.success('删除成功') // 重新拉取数据 @@ -450,61 +439,48 @@ const handleDelete = async (row) => { } } -// 编辑按钮点击事件 -const handleEdit = (row) => { - // 进入编辑状态 - editingId.value = row.id - // 复制当前行数据到编辑表单(深拷贝避免原数据被修改) +// 打开编辑弹窗核心方法 - 点击表格编辑按钮触发 +const showEditDialog = (row) => { + // 深拷贝当前行数据到编辑表单,避免原数据被修改 editForm.value = JSON.parse(JSON.stringify(row)) - // 确保类型正确 + // 确保数字类型正确,防止表单赋值异常 editForm.value.sortNo = Number(editForm.value.sortNo) || 1 editForm.value.phraseType = Number(editForm.value.phraseType) || 1 + // 重置表单验证状态 + if (editFormRef.value) { + editFormRef.value.clearValidate() + } + // 打开编辑弹窗 + editDialogVisible.value = true } -// 取消编辑 -const handleCancel = () => { - editingId.value = null - editForm.value = {} -} - -// 保存编辑 -const handleSave = async () => { +// 编辑表单提交保存方法 +const handleEditSave = async () => { try { - // 基础非空校验 - if (!editForm.value.phraseName || !editForm.value.phraseContent) { - ElMessage.error('请填写名称和内容') - return - } - if (!editForm.value.phraseCategory) { - ElMessage.error('请选择业务分类') - return - } - if (!editForm.value.phraseType) { - ElMessage.error('请选择范围') - return - } + // 先执行表单验证 + const validateResult = await editFormRef.value.validate() + if (!validateResult) return - // 名称唯一性校验(排除当前记录) - const nameValidation = validatePhraseName(editForm.value.phraseName, editingId.value) + // 名称唯一性校验(排除当前编辑的这条记录ID) + const nameValidation = validatePhraseName(editForm.value.phraseName, editForm.value.id) if (!nameValidation.valid) { ElMessage.error(nameValidation.message) return } - // 准备更新数据 + // 准备更新数据,修复时间格式为ISO字符串,适配后端LocalDateTime const updateData = { ...editForm.value, enableFlag: 1, - updateTime: new Date().toISOString() // 可选:前端临时赋值,后端最终以自己的为准 + updateTime: new Date().toISOString() // 前端临时赋值,后端最终以自己的为准 } // 调用更新接口 const response = await updateDoctorPhrase(updateData) - if (response.code === 200) { ElMessage.success('更新成功') - editingId.value = null - editForm.value = {} + editDialogVisible.value = false + // 重新拉取数据,保证列表数据最新 fetchDoctorPhraseList() } else { ElMessage.error('更新失败: ' + (response.msg || '未知错误')) @@ -515,7 +491,7 @@ const handleSave = async () => { } } -// 组件挂载时获取数据 +// 组件挂载时初始化加载数据 onMounted(() => { fetchDoctorPhraseList() }) @@ -531,7 +507,7 @@ onMounted(() => { align-items: center; margin-bottom: 20px; flex-wrap: wrap; - /* 【优化】适配小屏幕,防止按钮换行溢出 */ + /* 适配小屏幕,防止按钮换行溢出 */ gap: 10px; /* 替换margin-left,更优雅的间距 */ } @@ -542,7 +518,7 @@ onMounted(() => { justify-content: flex-end; } -/* 【优化】新增表单样式适配 */ +/* 新增表单样式适配 */ .add-form { padding: 10px 0; }