主界面列缓存,数据栏拖拉功能

This commit is contained in:
wyuu 2026-04-15 18:03:32 +08:00
parent f256dd5d34
commit 47277ee5eb
11 changed files with 190 additions and 61 deletions

View File

@ -43,6 +43,9 @@
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
<span>布局设置</span>
</el-dropdown-item>
<el-dropdown-item command="clearCache">
<span>清除缓存</span>
</el-dropdown-item>
<el-dropdown-item divided command="logout">
<span>退出登录</span>
</el-dropdown-item>
@ -56,7 +59,7 @@
</template>
<script setup>
import { ElMessageBox } from 'element-plus'
import { ElMessageBox, ElMessage } from 'element-plus'
// 引入原有组件
import Breadcrumb from '@/components/Breadcrumb'
import TopNav from '@/components/TopNav'
@ -76,7 +79,8 @@ import { formatDict, getDictData } from '@/hooks'
const appStore = useAppStore()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
import { useRoute } from 'vue-router';
const route = useRoute();
// 处理角色名称(取第一个角色,多角色可自定义)
const roleName = computed(() => {
if (!userStore.roles || userStore.roles.length === 0) {
@ -103,6 +107,9 @@ function handleCommand(command) {
case "setLayout":
setLayout();
break;
case "clearCache":
clearCache();
break;
case "logout":
logout();
break;
@ -111,6 +118,31 @@ function handleCommand(command) {
}
}
const clearCache = () => {
console.log(route.path);
const routeColumnKeyMap = {
'/liswork/work': 'cgjyList_column_config', // 检验列表页面
'/liswork/micro': 'wswList_column_config', // 微生物列表页面
};
// 获取当前页面的缓存KEY
const currentKey = routeColumnKeyMap[route.path];
if (!currentKey) {
ElMessage.warning('当前页面无表格列缓存可清除');
return;
}
try {
localStorage.removeItem(currentKey);
ElMessage.success('当前页面表格列缓存已清除');
// 可选:刷新页面使配置生效(或通知对应页面重置列)
location.reload();
} catch (e) {
console.error('清除当前列缓存失败', e);
ElMessage.error('清除缓存失败');
}
}
function logout() {
ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',

View File

@ -177,24 +177,30 @@ const selecChange = (rows: any[]) => {
//确定
const handleOk = () => {
if (selecRows.value.length == 0) {
ElMessage.warning('请选择要操作的行!')
return
}
let arr = []
arr = selecRows.value.map((item) => {
return {
...item,
yq: formData.value.yq,
}
})
if (formData.value.queryDylx == '1') {
addBatch(selecRows.value).then((res: any) => {
addBatch(arr).then((res) => {
if (res.code == 0) {
ElMessage.success('操作成功!')
selecRows.value = []
getList()
}
})
} else if (formData.value.queryDylx == '2') {
let arr = []
arr = selecRows.value.map((item: any) => {
return {
yq: formData.value.yq,
xmid: item.xmid,
}
})
delBatch(arr).then((res: any) => {
delBatch(arr).then((res) => {
if (res.code == 0) {
ElMessage.success('操作成功!')
selecRows.value = []
getList()
}
})

View File

@ -26,8 +26,9 @@
value="value" objKey="value" :border="true" width="8.75rem" size="small" @getDataValue="getList" />
</el-form-item>
<el-form-item label="项目ID:">
<el-input clearable placeholder="项目ID" prefix-icon="Search" v-model="queryParams.xmid"
style="width: 8.75rem" @change="getList" />
<el-input clearable placeholder="项目ID" prefix-icon="Search" v-model="queryParams.xmid" @input="(val) => {
queryParams.xmid = val.replace(/[^0-9]/g, '');
}" style="width: 8.75rem" @change="getList" />
</el-form-item>
<el-form-item>
<el-radio-group v-model="queryParams.uflag" fill="primary" :size="autoSize" @change="changeStauts">
@ -358,6 +359,9 @@ const handleSave = async (flag: any) => {
}
const flagCommon = modelParam.value.commonlyValuesData.every((item: any) => item.qz && item.srm && item.jgbz)
if (!flagCommon) return ElMessage.warning('请完整填写常用取值项!');
const flagUserInstr = modelParam.value.userInstrData.every((item: any) => item.yq)
if (!flagUserInstr) return ElMessage.warning('请完整选择对应的仪器!');
saveDataService({
xmInfoNew: modelParam.value.basicData,
xmDoubleRows: [],

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="13">
<el-splitter>
<el-splitter-panel size="55%">
<div class="box-shadow">
<el-form :model="queryParams" ref="queryRef" :inline="true" :size="aotuSize" :rules="rules"
class="compact-form">
@ -68,10 +68,10 @@
</el-col>
</el-row>
</div>
</el-col>
</el-splitter-panel>
<el-col :span="11">
<div>
<el-splitter-panel :min="300">
<div style="margin-left: 10px;">
<tabView :tabList="tabList" v-model:activeTab="activeTab" />
<div class="box-shadow right_box">
<template v-if="activeTab == 'LabPatList'">
@ -92,9 +92,9 @@
@click="handleNext"></el-button>
</el-tooltip>
<PatientQueryForm :initial-params="initialParams" @query="handleQueryResult" @reset="handleReset"
width="14rem" :size="aotuSize" placeholder="查询条件" :dict-data="dictData" :clearable="true" />
width="12rem" :size="aotuSize" placeholder="查询条件" :dict-data="dictData" :clearable="true" />
<el-input v-model="searchText" clearable :size="aotuSize" @keyup.enter="searchQuery" class="ml10"
@clear="clearSearch" style="width: 10rem" />
@clear="clearSearch" style="width: 9rem" />
</div>
<div>
<el-checkbox v-model="lbFlag" :size="aotuSize"> 列表翻页 </el-checkbox>
@ -132,8 +132,8 @@
</div>
</div>
</el-col>
</el-row>
</el-splitter-panel>
</el-splitter>
<!-- 校验用户 -->
<CheckUser ref="checkUserRef" @onConfirm="handleCheckUserConfirm" @onCancel="checkUserCancel" />
<!-- 批量扫码弹窗 -->

View File

@ -130,10 +130,13 @@ const handleMenuSelect = ((item: ContextMenuItem) => {
show.value = true
fcYq.value = props.tableKey.yq
})
const tableColumns = ref<any[]>([])
// 表格列配置
const tableColumns = ref([
const defaultTableColumns = [
{ field: 'jyrq', title: '录入时间', width: 80, align: 'center', resizable: true },
{ field: 'finish', title: '药敏', width: 30, align: 'center', slotName: 'finish', resizable: true },
{ field: 'finish', title: '药敏', width: 40, align: 'center', slotName: 'finish', resizable: true },
{ field: 'alarmflag', title: '警', width: 30, align: 'center', slotName: 'alarmflag', resizable: true },
{ field: 'cp_pyzq', title: '培养周期', width: 60, align: 'center', resizable: true },
{ field: 'jgbz', title: '状态', width: 50, align: 'center', resizable: true, slotName: 'jgbz' },
@ -152,7 +155,25 @@ const tableColumns = ref([
{ field: 'brly', title: '类型', width: 50, align: 'center', slotName: 'brly', resizable: true },
{ field: 'dybz', title: '印', width: 30, align: 'center', slotName: 'dybz', resizable: true },
{ field: 'shcs', title: '次数', width: 40, align: 'center', resizable: true },
])
]
const TABLE_COLUMN_KEY = 'wswList_column_config' // 唯一标识当前表格的列配置
const initTableColumns = () => {
try {
const savedColumns = localStorage.getItem(TABLE_COLUMN_KEY)
if (savedColumns) {
// 解析本地存储的列配置
const parsedColumns = JSON.parse(savedColumns)
tableColumns.value = parsedColumns
return
}
} catch (e) {
console.error('读取列配置失败', e)
}
// 无本地配置则使用默认配置
tableColumns.value = [...defaultTableColumns]
}
const getLableType = (type: string) => {
switch (type) {
@ -179,7 +200,24 @@ const handleColumnDragEnd = (data: any) => {
tableColumns.value = [];
// 使用nextTick确保DOM更新后再设置新值
nextTick(() => {
tableColumns.value = [...data.columns];
const newColumns = [...data.columns];
tableColumns.value = newColumns;
try {
const saveData = newColumns.map(col => ({
field: col.field,
title: col.title,
width: col.width,
align: col.align,
resizable: col.resizable,
slotName: col.slotName,
}))
localStorage.setItem(TABLE_COLUMN_KEY, JSON.stringify(saveData))
} catch (e) {
console.error('保存列配置失败', e)
}
});
}
const handleRowClick = (row: any) => {
@ -240,6 +278,8 @@ const formatDict = (v: string, dictType: string) => {
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label || v;
}
onMounted(() => {
initTableColumns()
const row = props.labPatList.find((item: any) => item.ybh == props.tableKey.ybh)
if (!row) return
setTimeout(() => { setCurrentRow(row) }, 100)

View File

@ -54,7 +54,7 @@
<el-tab-pane label="有效数据" name="2" />
</el-tabs>
<div v-if="activeName == '1'">
<div v-if="activeName == '1'" style="height: 100%;">
<div class="tips">
仪器:{{ yqmc }} &nbsp; 质控项目:{{ xmInfo.xmdh }} {{ xmInfo.xmmc }} &nbsp;
区间:{{ queryParams.st }} - {{ queryParams.et }}
@ -444,7 +444,7 @@ onMounted(async () => {
}
.echarts-box {
height: calc(100% - 50px);
height: calc(100% - 60px);
overflow: auto;
}

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="13">
<el-splitter>
<el-splitter-panel size="55%">
<div class="box-shadow">
<el-form :model="queryParams" ref="queryRef" :inline="true" :size="aotuSize" :rules="rules"
class="compact-form">
@ -54,10 +54,10 @@
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="11">
<div>
</el-splitter-panel>
<el-splitter-panel :min="300">
<div style="margin-left: 10px;">
<tabView :tabList="tabList" v-model:activeTab="activeTab" />
<div class="box-shadow right_box">
<template v-if="activeTab == 'LabPatList'">
@ -78,9 +78,9 @@
@click="handleNext"></el-button>
</el-tooltip>
<PatientQueryForm :initial-params="initialParams" @query="handleQueryResult" @reset="handleReset"
width="14rem" :size="aotuSize" placeholder="查询条件" :dict-data="dictData" :clearable="true" />
width="12rem" :size="aotuSize" placeholder="查询条件" :dict-data="dictData" :clearable="true" />
<el-input v-model="searchText" clearable :size="aotuSize" @keyup.enter="searchQuery" class="ml10"
@clear="clearSearch" style="width: 10rem" />
@clear="clearSearch" style="width: 9rem" />
</div>
<div>
@ -103,8 +103,11 @@
</div>
</div>
</el-col>
</el-row>
</el-splitter-panel>
</el-splitter>
<!-- 批量扫码弹窗 -->
<BatchCode ref="batchRef" v-model:labPat="labPat" :labPatKey="queryParams" :dictData="dictData"
:totalCount="labPatList.length" @goNext="handleNext" @goPrev="handlePrev" @goLast="handleLast"
@ -772,6 +775,7 @@ const sendMessage = () => {
.flex-between {
margin-bottom: .5rem;
flex-shrink: 0;
}
}

View File

@ -137,8 +137,10 @@ const handleMenuSelect = ((item: ContextMenuItem) => {
show.value = true
fcYq.value = props.tableKey.yq
})
const tableColumns = ref<any[]>([])
// 表格列配置
const tableColumns = ref([
const defaultTableColumns = [
{ field: 'finish', title: '完', width: 30, align: 'center', slotName: 'finish', resizable: true },
{ field: 'jgbz', title: '审', width: 30, align: 'center', slotName: 'jgbz', resizable: true },
{ field: 'alarmflag', title: '警', width: 30, align: 'center', slotName: 'alarmflag', resizable: true },
@ -160,7 +162,26 @@ const tableColumns = ref([
{ field: 'jymd', title: '检验目的', width: 90, align: 'center', resizable: true },
{ field: 'yhdh', title: '检验医生', width: 60, align: 'center', resizable: true, slotName: 'yhdh' },
{ field: 'yljg', title: '送检医院', width: 120, align: 'center', slotName: 'yljg', resizable: true, }
])
]
const TABLE_COLUMN_KEY = 'cgjyList_column_config' // 唯一标识当前表格的列配置
const initTableColumns = () => {
try {
const savedColumns = localStorage.getItem(TABLE_COLUMN_KEY)
if (savedColumns) {
// 解析本地存储的列配置
const parsedColumns = JSON.parse(savedColumns)
tableColumns.value = parsedColumns
return
}
} catch (e) {
console.error('读取列配置失败', e)
}
// 无本地配置则使用默认配置
tableColumns.value = [...defaultTableColumns]
}
// 更新列配置
const handleColumnDragEnd = (data: any) => {
@ -168,7 +189,22 @@ const handleColumnDragEnd = (data: any) => {
tableColumns.value = [];
// 使用nextTick确保DOM更新后再设置新值
nextTick(() => {
tableColumns.value = [...data.columns];
const newColumns = [...data.columns];
tableColumns.value = newColumns;
try {
const saveData = newColumns.map(col => ({
field: col.field,
title: col.title,
width: col.width,
align: col.align,
resizable: col.resizable,
slotName: col.slotName,
}))
localStorage.setItem(TABLE_COLUMN_KEY, JSON.stringify(saveData))
} catch (e) {
console.error('保存列配置失败', e)
}
});
}
const handleRowClick = (row: any) => {
@ -220,6 +256,8 @@ const formatDict = (v: string, dictType: string) => {
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label || v;
}
onMounted(() => {
initTableColumns()
const row = props.labPatList.find((item: any) => item.ybh == props.tableKey.ybh)
if (!row) return
setTimeout(() => { setCurrentRow(row) }, 100)

View File

@ -1,12 +1,10 @@
<!-- 修改界面 -->
<template>
<el-dialog v-model="visible" width="600px" @open="open">
<template #header>
{{ title }}
</template>
<el-dialog v-model="visible" :title="title" width="35vw" @open="open">
<span class="text-span">项目信息:</span>
<el-divider style="margin: 5px 0;" />
<el-form ref="form" :model="formData" size="small" class="form-inline" inline label-width="70px">
<el-form ref="form" :model="formData" class="form-inline" inline label-width="70px">
<el-form-item label="项目代号" prop="xmdh">
<el-input placeholder="项目代号" v-model="formData.xmdh"></el-input>
</el-form-item>
@ -113,7 +111,7 @@ const formData = ref({
const columnsRight = ref([
{ prop: 'reserve', label: '类别', visible: true, align: 'center', slot: 'reserve', width: 50, showOverflowTooltip: false },
{ prop: 'textresult', label: '说明', visible: true, align: 'center', slot: 'textresult', width: 300, showOverflowTooltip: false },
{ prop: 'zd', label: '指导建议', visible: true, align: 'center', slot: 'zd', width: 200, showOverflowTooltip: false },
{ prop: 'zd', label: '指导建议', visible: true, align: 'center', slot: 'zd', showOverflowTooltip: false },
])
const tableConfig = ref({
@ -194,14 +192,17 @@ const open = () => {
</script>
<style scoped lang="scss">
.text-span {
font-size: 16px;
font-weight: bold;
color: #1f6dd3;
}
.form-inline {
padding: 10px;
background-color: #f5f7fa;
height: auto;
.el-input {
width: 150px;
}
.el-form-item {
margin-right: 10px;

View File

@ -74,7 +74,7 @@ const modifyVisible = ref(false)
const modifyTitle = ref('')
const modifyType = ref('')
const modifyRef = ref()
const selectRow = ref()
const selectRow: any = ref(null)
//退拽属性
const handleColumnDragEnd = (data: any) => {
@ -118,7 +118,8 @@ const onClick = async (row: any) => {
selectRow.value = row
}
const onDBClick = () => {
const onDBClick = (info) => {
}
@ -129,16 +130,21 @@ const onAddClick = () => {
}
const onDelClick = async () => {
if (selectRow.value) {
await ElMessageBox.confirm('是否要删除选中的数据?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', });
await delService(selectRow.value.xmid)
ElMessage.success('删除成功!')
}
const onDelClick = () => {
if (!selectRow.value) return ElMessage.warning('请先选择要删除的数据!')
ElMessageBox.confirm('是否要删除选中的数据?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', }).then(() => {
delService(selectRow.value.xmid).then((res) => {
if (res.code == 0) {
ElMessage.success('删除成功!')
getList()
selectRow.value = null
}
})
})
}
const onQueryClick = () => {
pagination.value.currentPage = 1
getList()
}
@ -147,9 +153,7 @@ const getList = async () => {
const res = await queryService(data);
dataListLeft.value = res.rows
pagination.value.total = res.total
dataListRight.value = []
}

View File

@ -115,7 +115,7 @@ const tabList = [
{ key: 'SysSort', label: '项目排序', component: SysSort },
{ key: 'SysReport', label: '报告单设置', component: SysReport },
]
const activeName = ref('SysDefaultParams')
const activeName = ref('SysGlobal')
// 计算当前要渲染的组件
const currentComponent = computed(() => {