This commit is contained in:
parent
8d83be7cb3
commit
cf6de1d1d7
|
|
@ -279,15 +279,26 @@ const emit = defineEmits<{
|
||||||
(e: 'filter-change', filters: { [key: string]: any }): void
|
(e: 'filter-change', filters: { [key: string]: any }): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 获取路由和用户 Store
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 缓存 key 版本号(当列配置结构升级时可手动改这个值,使旧缓存失效)
|
||||||
|
const CACHE_VERSION = 'v1'
|
||||||
|
|
||||||
// 生成缓存 key
|
// 生成缓存 key
|
||||||
const getCacheKey = () => {
|
const getCacheKey = () => {
|
||||||
const baseKey = props.columnSettingStorageKey || String(route.name || route.path)
|
const baseKey = props.columnSettingStorageKey
|
||||||
const userId = String(userStore.userInfo?.id || 'guest')
|
|| String((route.name as string) || route.path || 'default')
|
||||||
return `table-column-setting-${baseKey}-${userId}`
|
const userId = String((userStore.userInfo as any)?.id || 'guest')
|
||||||
|
return `table-column-setting-${CACHE_VERSION}-${baseKey}-${userId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取列的唯一标识(用于匹配缓存中的列)
|
||||||
|
const getColumnKey = (col: TableColumn): string => {
|
||||||
|
if (col.prop) return `prop:${col.prop}`
|
||||||
|
if (col.slotName) return `slot:${col.slotName}`
|
||||||
|
if (col.type) return `type:${col.type}`
|
||||||
|
return `label:${col.label}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 气泡确认框显示状态
|
// 气泡确认框显示状态
|
||||||
|
|
@ -306,63 +317,59 @@ const finalColumns = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// 初始化列配置(从缓存或默认值)
|
// 初始化列配置(从缓存或默认值)
|
||||||
|
// 逻辑:原始 props.columns 为准,缓存只控制“可见性”和“顺序”。
|
||||||
|
// - 原始列中与缓存匹配的项 → 应用缓存的 visible / sortOrder
|
||||||
|
// - 原始列中新增的项 → 追加到末尾,visible 默认 true
|
||||||
|
// - 缓存中存在但原始列已删除的项 → 丢弃
|
||||||
const initColumns = () => {
|
const initColumns = () => {
|
||||||
if (!props.columns || props.columns.length === 0) {
|
if (!props.columns || props.columns.length === 0) {
|
||||||
localColumns.value = []
|
localColumns.value = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 读取缓存(可能为空)
|
||||||
const cacheKey = getCacheKey()
|
const cacheKey = getCacheKey()
|
||||||
|
let cachedConfig: any[] = []
|
||||||
const cached = localStorage.getItem(cacheKey)
|
const cached = localStorage.getItem(cacheKey)
|
||||||
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
try {
|
try {
|
||||||
const cachedConfig = JSON.parse(cached)
|
const parsed = JSON.parse(cached)
|
||||||
// 按 sortOrder 排序
|
if (Array.isArray(parsed)) cachedConfig = parsed
|
||||||
cachedConfig.sort((a: any, b: any) => (a.sortOrder || 0) - (b.sortOrder || 0))
|
|
||||||
|
|
||||||
// 合并缓存和原始配置,保持缓存的顺序
|
|
||||||
localColumns.value = cachedConfig.map((cached: any) => {
|
|
||||||
// 优先按 prop 匹配
|
|
||||||
const originalCol = props.columns?.find((c) => c.prop === cached.prop)
|
|
||||||
if (originalCol) {
|
|
||||||
return { ...originalCol, ...cached }
|
|
||||||
}
|
|
||||||
// 对于没有 prop 的列(如操作列),按 slotName 匹配
|
|
||||||
if (cached.slotName) {
|
|
||||||
const slotCol = props.columns?.find((c) => c.slotName === cached.slotName)
|
|
||||||
if (slotCol) {
|
|
||||||
return { ...slotCol, ...cached }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}).filter(Boolean)
|
|
||||||
} catch {
|
} catch {
|
||||||
// 解析失败,使用默认配置
|
cachedConfig = []
|
||||||
localColumns.value = props.columns.map((col) => ({
|
|
||||||
...col,
|
|
||||||
visible: col.visible !== false,
|
|
||||||
fixed: col.fixed || false,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 无缓存,使用默认配置
|
|
||||||
localColumns.value = props.columns.map((col) => ({
|
|
||||||
...col,
|
|
||||||
visible: col.visible !== false,
|
|
||||||
fixed: col.fixed || false,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建缓存映射:key -> { visible, sortOrder }
|
||||||
|
const cachedMap = new Map<string, { visible: boolean; sortOrder: number }>()
|
||||||
|
cachedConfig.forEach((c, idx) => {
|
||||||
|
cachedMap.set(c.key || getColumnKey(c), {
|
||||||
|
visible: c.visible !== false,
|
||||||
|
sortOrder: typeof c.sortOrder === 'number' ? c.sortOrder : idx,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 以原始列为主,命中缓存则用缓存的 visible / sortOrder,否则追加到末尾
|
||||||
|
const maxOrder = Math.max(-1, ...Array.from(cachedMap.values()).map((v) => v.sortOrder))
|
||||||
|
let nextOrder = maxOrder + 1
|
||||||
|
|
||||||
|
localColumns.value = props.columns.map((col) => {
|
||||||
|
const hit = cachedMap.get(getColumnKey(col))
|
||||||
|
if (hit) {
|
||||||
|
return { ...col, visible: hit.visible, sortOrder: hit.sortOrder }
|
||||||
|
}
|
||||||
|
return { ...col, visible: col.visible !== false, sortOrder: nextOrder++ }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 按 sortOrder 排序
|
||||||
|
localColumns.value.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存配置到 localStorage
|
// 保存配置到 localStorage(仅缓存 key / visible / sortOrder)
|
||||||
const saveToStorage = () => {
|
const saveToStorage = () => {
|
||||||
const config = localColumns.value.map((col, index) => ({
|
const config = localColumns.value.map((col, index) => ({
|
||||||
prop: col.prop,
|
key: getColumnKey(col),
|
||||||
visible: col.visible,
|
visible: col.visible !== false,
|
||||||
label: col.label,
|
|
||||||
width: col.width,
|
|
||||||
slotName: col.slotName,
|
|
||||||
sortOrder: index,
|
sortOrder: index,
|
||||||
}))
|
}))
|
||||||
localStorage.setItem(getCacheKey(), JSON.stringify(config))
|
localStorage.setItem(getCacheKey(), JSON.stringify(config))
|
||||||
|
|
@ -390,48 +397,33 @@ const handleReset = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听 columns 变化
|
// 监听 columns 变化
|
||||||
|
// 注意:当原始 columns 变化时(如父组件新增/删除了列配置),
|
||||||
|
// 需要重新合并缓存,否则新字段不会展示。
|
||||||
|
let lastColumnsKey = ''
|
||||||
watch(
|
watch(
|
||||||
() => props.columns,
|
() => props.columns,
|
||||||
(newColumns) => {
|
(newColumns) => {
|
||||||
if (newColumns && newColumns.length > 0) {
|
if (!newColumns || newColumns.length === 0) return
|
||||||
// 只有在本地列为空时才初始化(不要覆盖已加载的缓存)
|
// 通过长度+关键字段生成 key,避免不必要的重新初始化
|
||||||
if (localColumns.value.length === 0) {
|
const newKey = newColumns.map((c) => getColumnKey(c)).join('|')
|
||||||
|
if (newKey === lastColumnsKey && localColumns.value.length > 0) return
|
||||||
|
lastColumnsKey = newKey
|
||||||
initColumns()
|
initColumns()
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 组件挂载时初始化列配置
|
// 组件挂载时,如果列还没初始化,再次尝试
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 延迟初始化,确保 props.columns 已准备好
|
|
||||||
setTimeout(() => {
|
|
||||||
if (props.columns && props.columns.length > 0 && localColumns.value.length === 0) {
|
if (props.columns && props.columns.length > 0 && localColumns.value.length === 0) {
|
||||||
initColumns()
|
initColumns()
|
||||||
}
|
}
|
||||||
}, 100)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听 tableData 变化,清除单选选中状态
|
const tableRef = ref<TableInstance>()
|
||||||
watch(
|
|
||||||
() => props.tableData,
|
|
||||||
() => {
|
|
||||||
if (props.singleSelect) {
|
|
||||||
selectedRadioRow.value = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 监听 tableData 变化,清除单选选中状态
|
// 维护当前选中行状态
|
||||||
watch(
|
const selectedRow = ref<any>(null)
|
||||||
() => props.tableData,
|
|
||||||
() => {
|
|
||||||
if (props.singleSelect) {
|
|
||||||
selectedRadioRow.value = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 处理勾选变化
|
// 处理勾选变化
|
||||||
const handleSelectionChange = (rows: any[]) => {
|
const handleSelectionChange = (rows: any[]) => {
|
||||||
|
|
@ -444,11 +436,6 @@ const handleCurrentChange = (row: any) => {
|
||||||
emit('current-change', row)
|
emit('current-change', row)
|
||||||
}
|
}
|
||||||
|
|
||||||
const tableRef = ref<TableInstance>()
|
|
||||||
|
|
||||||
// 维护当前选中行状态
|
|
||||||
const selectedRow = ref<any>(null)
|
|
||||||
|
|
||||||
// 处理行点击事件
|
// 处理行点击事件
|
||||||
const handleRowClick = (row: any) => {
|
const handleRowClick = (row: any) => {
|
||||||
if (!row) return
|
if (!row) return
|
||||||
|
|
@ -467,23 +454,17 @@ const handleRowContextmenu = (row: any, column: any, event: MouseEvent) => {
|
||||||
emit('row-contextmenu', row, column, event)
|
emit('row-contextmenu', row, column, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听 tableData 变化,清除单选选中状态
|
// 监听 tableData 变化(清除单选/行选中状态)
|
||||||
watch(
|
watch(
|
||||||
() => props.tableData,
|
() => props.tableData,
|
||||||
() => {
|
() => {
|
||||||
if (props.singleSelect) {
|
if (props.singleSelect) {
|
||||||
selectedRadioRow.value = null
|
selectedRadioRow.value = null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
// 监听 tableData 变化
|
|
||||||
watch(
|
|
||||||
() => props.tableData,
|
|
||||||
() => {
|
|
||||||
selectedRow.value = null
|
selectedRow.value = null
|
||||||
tableRef.value?.setCurrentRow(null)
|
tableRef.value?.setCurrentRow(null)
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 处理下拉筛选命令
|
// 处理下拉筛选命令
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,6 @@ export const useTransactionStore = defineStore('transaction', () => {
|
||||||
const positionList = ref<PositionItem[]>([])
|
const positionList = ref<PositionItem[]>([])
|
||||||
/** 做市商浮动盈亏数据 Map<account_id, float_profit_loss> */
|
/** 做市商浮动盈亏数据 Map<account_id, float_profit_loss> */
|
||||||
const marketFloatProfitMap = ref<Map<string, string>>(new Map())
|
const marketFloatProfitMap = ref<Map<string, string>>(new Map())
|
||||||
/** 做市商平仓盈亏数据 Map<account_id, close_profit_loss> */
|
|
||||||
const marketCloseProfitMap = ref<Map<string, string>>(new Map())
|
|
||||||
|
|
||||||
// ------------------ 初始化 ------------------
|
// ------------------ 初始化 ------------------
|
||||||
|
|
||||||
|
|
@ -120,24 +118,21 @@ export const useTransactionStore = defineStore('transaction', () => {
|
||||||
* 格式:account_id:float_profit_loss:close_profit_loss (例:84:0.000000:0.000000)
|
* 格式:account_id:float_profit_loss:close_profit_loss (例:84:0.000000:0.000000)
|
||||||
*/
|
*/
|
||||||
const handleMarketFloatProfit = (data: string): void => {
|
const handleMarketFloatProfit = (data: string): void => {
|
||||||
|
console.log('data:', data);
|
||||||
|
|
||||||
if (!data) return
|
if (!data) return
|
||||||
|
|
||||||
const fields = data.split(':')
|
const fields = data.split(':')
|
||||||
if (fields.length < 3) return
|
if (fields.length < 2) return
|
||||||
|
|
||||||
const account_id = fields[0]
|
const account_id = fields[0]
|
||||||
const float_profit_loss = fields[1] as string
|
const float_profit_loss = fields[1] as string
|
||||||
const close_profit_loss = fields[2] as string
|
|
||||||
|
|
||||||
// 更新浮动盈亏 Map
|
// 更新浮动盈亏 Map
|
||||||
marketFloatProfitMap.value.set(account_id, float_profit_loss)
|
marketFloatProfitMap.value.set(account_id, float_profit_loss)
|
||||||
|
console.log('marketFloatProfitMap.value:', marketFloatProfitMap.value);
|
||||||
marketFloatProfitMap.value = new Map(marketFloatProfitMap.value)
|
marketFloatProfitMap.value = new Map(marketFloatProfitMap.value)
|
||||||
|
|
||||||
// 更新平仓盈亏 Map
|
|
||||||
marketCloseProfitMap.value.set(account_id, close_profit_loss)
|
|
||||||
marketCloseProfitMap.value = new Map(marketCloseProfitMap.value)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------ 持仓列表 ------------------
|
// ------------------ 持仓列表 ------------------
|
||||||
|
|
@ -178,7 +173,6 @@ export const useTransactionStore = defineStore('transaction', () => {
|
||||||
mqttClient?.disconnect()
|
mqttClient?.disconnect()
|
||||||
positionList.value = []
|
positionList.value = []
|
||||||
marketFloatProfitMap.value.clear()
|
marketFloatProfitMap.value.clear()
|
||||||
marketCloseProfitMap.value.clear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -193,7 +187,6 @@ export const useTransactionStore = defineStore('transaction', () => {
|
||||||
mqttClient,
|
mqttClient,
|
||||||
positionList,
|
positionList,
|
||||||
marketFloatProfitMap,
|
marketFloatProfitMap,
|
||||||
marketCloseProfitMap,
|
|
||||||
initMarketConditionsMQTT,
|
initMarketConditionsMQTT,
|
||||||
getPositionList,
|
getPositionList,
|
||||||
requestMarketFloatProfit,
|
requestMarketFloatProfit,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue