完善医生常用语管理功能

### 后端修改
1. 实体类DoctorPhrase:字段/注解调整
2. 枚举完善:新增DoctorPhraseAppTypeEnum/DoctorPhraseBizTypeEnum,统一业务分类
3. 服务实现类:修正类名拼写(DoctorPhraesAppS → DoctorPhraseAppServiceImpl
### 前端修改
1. 常用语管理页面(doctorphrase/index.vue):
   业务分类硬编码替换为枚举(主诉/现病史/术前/术后/既往史)
This commit is contained in:
sindir
2026-01-19 15:43:34 +08:00
parent 97f04d0b15
commit 9cba8fea12
4 changed files with 228 additions and 219 deletions

View File

@@ -13,7 +13,7 @@ import javax.annotation.Resource;
import java.util.List;
@Service
public class DoctorPhraesAppServiceImpl implements IDoctorPhraseAppService {
public class DoctorPhraseAppServiceImpl implements IDoctorPhraseAppService {
@Resource
private IDoctorPhraseService doctorPhraseService;

View File

@@ -1,12 +1,14 @@
package com.openhis.template.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
@Data
@@ -28,8 +30,13 @@ public class DoctorPhrase {
private Integer phraseType;
/** 业务分类(主诉/现病史等) */
@NotBlank(message = "业务分类不能为空")
private String phraseCategory;
// 非数据库字段,用于前端展示名称
@TableField(exist = false)
private String businessTypeName;
/** 模板内容 */
private String phraseContent;

View File

@@ -0,0 +1,40 @@
package com.openhis.template.enums;
// 枚举类不需要任何Lombok注解@Data/@AllArgsConstructor/@NoArgsConstructor都删掉
public enum DoctorPhraseBizTypeEnum {
// 1. 枚举项直接传值不用code:xxx直接写字符串
MAIN_COMPLAINT("MAIN_COMPLAINT", "主诉"),
PRESENT_HISTORY("PRESENT_HISTORY", "现病史"),
PRE_OPERATION("PRE_OPERATION", "术前"),
POST_OPERATION("POST_OPERATION", "术后"),
PAST_HISTORY("PAST_HISTORY", "既往史");
// 2. 定义枚举的成员变量private final 保证不可变)
private final String code; // 数据库存储的编码
private final String name; // 前端展示的名称
// 3. 手动写私有构造器(枚举构造器必须私有,且要给变量赋值)
DoctorPhraseBizTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
// 4. 提供getter方法枚举没有setter因为枚举项是常量不能改
public String getCode() {
return code;
}
public String getName() {
return name;
}
// 【可选】添加工具方法根据code找对应的枚举前端传code时后端快速匹配
public static DoctorPhraseBizTypeEnum getByCode(String code) {
for (DoctorPhraseBizTypeEnum enumObj : values()) {
if (enumObj.getCode().equals(code)) {
return enumObj;
}
}
return null; // 或抛异常throw new IllegalArgumentException("无效的业务分类编码:" + code);
}
}

View File

@@ -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>
@@ -202,8 +141,8 @@
</template>
<script setup>
import {onMounted, ref} from 'vue'
import {Check, Close, Plus, Refresh, Search} from '@element-plus/icons-vue'
import { onMounted, ref } from 'vue'
import { Check, Close, Plus, Refresh, Search } from '@element-plus/icons-vue'
import {
addDoctorPhrase,
deleteDoctorPhrase,
@@ -211,12 +150,22 @@ import {
searchDoctorPhraseList,
updateDoctorPhrase
} from './api'
import {ElMessage, ElMessageBox} from 'element-plus'
import {useDict} from '@/utils/dict'
import { ElMessage, ElMessageBox } from 'element-plus'
// 【修改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=全院
const searchKeyword = ref('')
const searchScope = ref(null) // null表示未选择数字类型1=个人2=科室3=全院
const searchKeyword = ref('')
// 表格数据
const tableData = ref([])
@@ -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 rules = {
// 【修改6】完善新增表单验证规则补充业务分类必填
const addRules = {
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 : '未知类型'
}
// 获取范围名称
@@ -290,25 +250,25 @@ const validatePhraseName = (phraseName, excludeId = null) => {
if (!phraseName || !phraseName.trim()) {
return { valid: false, message: '请输入常用语名称' }
}
// 检查字数限制
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 === phraseName.trim()
return item.phraseName.trim() === phraseName.trim()
})
if (existingPhrase) {
return { valid: false, message: '常用语名称已存在,请输入不同的名称' }
}
return { valid: true, message: '' }
}
@@ -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.data.data.length
total.value = allData.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 searchScopeValue = searchScope.value
const phraseType = searchScopeValue === null ? undefined : searchScopeValue
const phraseType = searchScope.value === 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.data.data.length
total.value = allData.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
@@ -399,13 +359,17 @@ const handleSearch = async () => {
// 打开新增模态框
const showAddDialog = () => {
// 重置表单
addForm.value = {
phraseName: '',
phraseContent: '',
sortNo: 1,
phraseType: 1,
phraseCategory: '病愈'
}
addForm.value = {
phraseName: '',
phraseContent: '',
sortNo: 1,
phraseType: 1,
phraseCategory: '' // 【修改9】默认空强制选择
}
// 重置表单验证状态
if (addFormRef.value) {
addFormRef.value.clearValidate()
}
// 打开模态框
addDialogVisible.value = true
}
@@ -413,54 +377,43 @@ 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)
if (!nameValidation.valid) {
ElMessage.error(nameValidation.message)
return
}
// 添加数据库要求的必填默认字段
const formData = {
...addForm.value,
phraseCode: 'PHR000',
phraseCode: 'PHR000', // 建议后端自动生成,前端可传空
enableFlag: 1,
staffId: 1001,
deptCode: 'DEPT001',
creatorId: 1001
staffId: 1001, // 建议从登录态获取,不要硬编码
deptCode: 'DEPT001', // 建议从登录态获取
creatorId: 1001 // 建议从登录态获取
}
// 调用新增接口
const response = await addDoctorPhrase(formData)
// 处理新增结果
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('确定要删除该常用语吗?', '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
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,61 +454,63 @@ 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
}
// 名称唯一性校验(排除当前记录)
const nameValidation = validatePhraseName(editForm.value.phraseName, editingId.value)
if (!nameValidation.valid) {
ElMessage.error(nameValidation.message)
return
}
// 准备更新数据
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: 20px;
flex-wrap: wrap;
/* 【优化】适配小屏幕,防止按钮换行溢出 */
gap: 10px;
/* 替换margin-left更优雅的间距 */
}
.pagination-container {
@@ -584,4 +541,9 @@ onMounted(() => {
display: flex;
justify-content: flex-end;
}
/* 【优化】新增表单样式适配 */
.add-form {
padding: 10px 0;
}
</style>