列设置添加缓存

调整监测点台账导出id重复问题
This commit is contained in:
guanj
2026-07-17 08:50:25 +08:00
parent dc3b3cfc74
commit 6c70a776a0
9 changed files with 173 additions and 133 deletions

View File

@@ -1,23 +1,41 @@
<script lang='ts'> <script lang="ts">
import { defineComponent, createVNode, reactive } from 'vue' import { defineComponent, createVNode, reactive } from 'vue'
import { Column } from 'vxe-table' import { Column } from 'vxe-table'
import { uuid } from '@/utils/random' import { uuid } from '@/utils/random'
export default defineComponent({ /** storage 开启时列必须有稳定 field序号/操作等无 field 列按 title 生成 */
name: 'Column', function resolveColumnField(attr: Record<string, any>): string | undefined {
props: { if (attr.field) return attr.field
attr: { if (attr.prop) return attr.prop
type: Object, // checkbox / radio / expand / seq 等类型列由 vxe 内部处理,可不强制 field
required: true if (attr.type && ['checkbox', 'radio', 'expand', 'html'].includes(attr.type)) {
} return undefined
}, }
setup(props, { slots }) { if (attr.title != null && attr.title !== '') {
const attr = reactive(props.attr) return `__col_${attr.title}`
attr['align'] = attr['align'] ? attr['align'] : 'center' }
attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.prop || uuid() return `col_${uuid()}`
return () => { }
return createVNode(Column, attr, slots.default)
} export default defineComponent({
} name: 'Column',
}) props: {
</script> attr: {
type: Object,
required: true
}
},
setup(props, { slots }) {
const attr = reactive({ ...props.attr })
attr['align'] = attr['align'] ? attr['align'] : 'center'
const field = resolveColumnField(attr)
if (field) {
attr.field = field
}
attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.field || attr.prop || uuid()
return () => {
return createVNode(Column, attr, slots.default)
}
}
})
</script>

View File

@@ -7,11 +7,11 @@ export const defaultAttribute: VxeTableProps = {
stripe: true, stripe: true,
size: 'small', size: 'small',
columnConfig: { resizable: true, useKey: true }, columnConfig: { resizable: true, useKey: true },
rowConfig: { isCurrent: true, isHover: true, keyField: 'id' }, rowConfig: { isCurrent: true, isHover: true, },
scrollX: { scrollToLeftOnChange: true }, scrollX: { scrollToLeftOnChange: true },
scrollY: { enabled: false }, scrollY: { enabled: false },
// 注意:全局不要默认开启 treeConfig会与 stripe 冲突;树表在页面自行配置 // 注意:全局不要默认开启 treeConfig会与 stripe 冲突;树表在页面自行配置
customConfig: { enabled: true, allowFixed: false, showFooter: false, immediate: true, mode: 'default' }, customConfig: { enabled: true, allowFixed: true, storage: true, showFooter: false, immediate: true ,mode:'default'},
showOverflow: 'tooltip', showOverflow: 'tooltip',
showHeaderOverflow: false showHeaderOverflow: false
} }

View File

@@ -1,20 +1,23 @@
<template> <template>
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }"> <div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
<div v-if="showCustomColumn && !tableStore?.table?.customColumnInHeader" class="table-custom-toolbar"> <div v-if="showCustomColumn && !tableStore?.table?.customColumnInHeader" class="table-custom-toolbar">
<el-button icon="el-icon-Setting" @mousedown="onCustomColumnMousedown" @click="openCustomColumn">列设置</el-button> <el-button icon="el-icon-Setting" @mousedown="onCustomColumnMousedown" @click="openCustomColumn">
列设置
</el-button>
</div> </div>
<vxe-table <vxe-table
ref="tableRef" ref="tableRef"
height="auto" height="auto"
:key="key" :key="key"
:id="getTableId()"
:data="tableStore.table.data" :data="tableStore.table.data"
v-loading="tableStore.table.loading" v-loading="tableStore.table.loading"
v-bind="tableBindProps" v-bind="tableBindProps"
@checkbox-all="selectChangeEvent" @checkbox-all="selectChangeEvent"
@checkbox-change="selectChangeEvent" @checkbox-change="selectChangeEvent"
@cell-click="onCellClick" @cell-click="onCellClick"
> >
<!-- @sort-change="handleSortChange" --> <!-- @sort-change="handleSortChange" -->
<!-- Column 组件内部是 el-table-column --> <!-- Column 组件内部是 el-table-column -->
<template v-if="isGroup"> <template v-if="isGroup">
<GroupColumn :column="tableStore.table.column" /> <GroupColumn :column="tableStore.table.column" />
@@ -163,6 +166,9 @@ const openCustomColumn = () => {
const getRef = () => { const getRef = () => {
return tableRef.value return tableRef.value
} }
const getTableId = () => {
return tableStore.table.filename || document.querySelectorAll('.ba-nav-tab.active')[0].textContent || ''
}
// 排序 // 排序
const handleSortChange = ({ column, order }: { column: TableColumn; order: 'asc' | 'desc' | null }) => { const handleSortChange = ({ column, order }: { column: TableColumn; order: 'asc' | 'desc' | null }) => {
// console.log('排序列:', column?.property); // console.log('排序列:', column?.property);

View File

@@ -43,6 +43,7 @@ import { useConfig } from '@/stores/config'
import { useAdminInfo } from '@/stores/adminInfo' import { useAdminInfo } from '@/stores/adminInfo'
import { useNavTabs } from '@/stores/navTabs' import { useNavTabs } from '@/stores/navTabs'
import { logout } from '@/api/user-boot/user' import { logout } from '@/api/user-boot/user'
import { Local } from '@/utils/storage'
import Config from './config.vue' import Config from './config.vue'
import PopupPwd from './popup/password.vue' import PopupPwd from './popup/password.vue'
import AdminInfo from './popup/adminInfo.vue' import AdminInfo from './popup/adminInfo.vue'
@@ -114,8 +115,8 @@ const handleLogout = async () => {
// 清理本地数据 // 清理本地数据
const clearLocalData = () => { const clearLocalData = () => {
// 清空 localStorage // 清空 localStorage(保留 VXE 自定义列、DevTools 配置)
window.localStorage.clear() Local.clear()
// 清空用户状态 // 清空用户状态
adminInfo.reset() adminInfo.reset()

View File

@@ -30,6 +30,7 @@ import { validatePwd } from '@/utils/common'
import { useAdminInfo } from '@/stores/adminInfo' import { useAdminInfo } from '@/stores/adminInfo'
import router from '@/router' import router from '@/router'
import { useNavTabs } from '@/stores/navTabs' import { useNavTabs } from '@/stores/navTabs'
import { Local } from '@/utils/storage'
const navTabs = useNavTabs() const navTabs = useNavTabs()
const adminInfo = useAdminInfo() const adminInfo = useAdminInfo()
const dialogVisible = ref(false) const dialogVisible = ref(false)
@@ -103,7 +104,7 @@ const submit = () => {
dialogVisible.value = false dialogVisible.value = false
setTimeout(() => { setTimeout(() => {
navTabs.closeTabs() navTabs.closeTabs()
window.localStorage.clear() Local.clear()
adminInfo.reset() adminInfo.reset()
router.push({ name: 'login' }) router.push({ name: 'login' })
}, 0) }, 0)

View File

@@ -1,54 +1,54 @@
.block-loading { .block-loading {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: fixed; position: fixed;
z-index: 9990; z-index: 9990;
background-color: var(--ba-bg-color); background-color: var(--ba-bg-color);
} }
.block-loading .block-loading-box { .block-loading .block-loading-box {
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
.block-loading .block-loading-box-warp { .block-loading .block-loading-box-warp {
width: 80px; width: 80px;
height: 80px; height: 80px;
} }
.block-loading .block-loading-box-warp .block-loading-box-item { .block-loading .block-loading-box-warp .block-loading-box-item {
width: 33.333333%; width: 33.333333%;
height: 33.333333%; height: 33.333333%;
background: #409eff; background: #409eff;
float: left; float: left;
animation: block-loading-animation 1.2s infinite ease; animation: block-loading-animation 1.2s infinite ease;
border-radius: 1px; border-radius: 1px;
} }
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(7) { .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(7) {
animation-delay: 0s; animation-delay: 0s;
} }
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(4), .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(4),
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(8) { .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(8) {
animation-delay: 0.1s; animation-delay: 0.1s;
} }
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(1), .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(1),
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(5), .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(5),
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(9) { .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(9) {
animation-delay: 0.2s; animation-delay: 0.2s;
} }
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(2), .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(2),
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(6) { .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(6) {
animation-delay: 0.3s; animation-delay: 0.3s;
} }
.block-loading .block-loading-box-warp .block-loading-box-item:nth-child(3) { .block-loading .block-loading-box-warp .block-loading-box-item:nth-child(3) {
animation-delay: 0.4s; animation-delay: 0.4s;
} }
@keyframes block-loading-animation { @keyframes block-loading-animation {
0%, 0%,
70%, 70%,
100% { 100% {
transform: scale3D(1, 1, 1); transform: scale3D(1, 1, 1);
} }
35% { 35% {
transform: scale3D(0, 0, 1); transform: scale3D(0, 0, 1);
} }
} }

View File

@@ -1,45 +1,59 @@
/** /**
* window.localStorage * window.localStorage
* @method set 设置 * @method set 设置
* @method get 获取 * @method get 获取
* @method remove 移除 * @method remove 移除
* @method clear 移除全部 * @method clear 移除全部
*/ */
export const Local = { export const Local = {
set(key: string, val: any) { set(key: string, val: any) {
window.localStorage.setItem(key, JSON.stringify(val)) window.localStorage.setItem(key, JSON.stringify(val))
}, },
get(key: string) { get(key: string) {
const json: any = window.localStorage.getItem(key) const json: any = window.localStorage.getItem(key)
return JSON.parse(json) return JSON.parse(json)
}, },
remove(key: string) { remove(key: string) {
window.localStorage.removeItem(key) window.localStorage.removeItem(key)
}, },
clear() { clear() {
window.localStorage.clear() // 退出登录时保留表格自定义列、Vue DevTools 等配置
}, const preserveKeys = [
} 'VXE_CUSTOM_STORE',
'__VUE_DEVTOOLS_NEXT_PLUGIN_SETTINGS__dev.esm.pinia__',
/** ]
* window.sessionStorage const preserved: Record<string, string | null> = {}
* @method set 设置会话缓存 preserveKeys.forEach(key => {
* @method get 获取会话缓存 preserved[key] = window.localStorage.getItem(key)
* @method remove 移除会话缓存 })
* @method clear 移除全部会话缓存 window.localStorage.clear()
*/ preserveKeys.forEach(key => {
export const Session = { if (preserved[key] !== null) {
set(key: string, val: any) { window.localStorage.setItem(key, preserved[key] as string)
window.sessionStorage.setItem(key, JSON.stringify(val)) }
}, })
get(key: string) { },
const json: any = window.sessionStorage.getItem(key) }
return JSON.parse(json)
}, /**
remove(key: string) { * window.sessionStorage
window.sessionStorage.removeItem(key) * @method set 设置会话缓存
}, * @method get 获取会话缓存
clear() { * @method remove 移除会话缓存
window.sessionStorage.clear() * @method clear 移除全部会话缓存
}, */
} export const Session = {
set(key: string, val: any) {
window.sessionStorage.setItem(key, JSON.stringify(val))
},
get(key: string) {
const json: any = window.sessionStorage.getItem(key)
return JSON.parse(json)
},
remove(key: string) {
window.sessionStorage.removeItem(key)
},
clear() {
window.sessionStorage.clear()
},
}

View File

@@ -109,7 +109,7 @@ const tableStore = new TableStore({
publicHeight: 65, publicHeight: 65,
isWebPaging: true, isWebPaging: true,
method: 'POST', method: 'POST',
filename: '监测点台账', filename: '监测点台账 ',
column: [ column: [
{ {
title: '序号', title: '序号',
@@ -155,7 +155,7 @@ const tableStore = new TableStore({
{ field: 'powerFlag', title: '用户性质', width: '120px' }, { field: 'powerFlag', title: '用户性质', width: '120px' },
/* { field: 'comFlag', title: '通讯状态 ', minWidth: 120 },*/ /* { field: 'comFlag', title: '通讯状态 ', minWidth: 120 },*/
{ field: 'id', title: '监测点序号', minWidth: 90 }, { field: 'runNo', title: '监测点序号', minWidth: 90 },
{ {
field: 'comFlag', field: 'comFlag',
title: '通讯状态', title: '通讯状态',

View File

@@ -53,7 +53,7 @@
maxlength="32" maxlength="32"
show-word-limit show-word-limit
clearable clearable
style="minWidth: 280px;" style="min-Width: 280px;"
/> />
</el-form-item> </el-form-item>
</template> </template>