220 lines
7.5 KiB
JavaScript
220 lines
7.5 KiB
JavaScript
/**
|
||
* 驾驶舱页面导航状态恢复 Mixin
|
||
* 用于:从 C 页面返回时恢复状态(dateData、factory)
|
||
* 使用方式:在组件中 import 并添加到 mixins 数组
|
||
*
|
||
* 3 种进入方式及优先级:
|
||
* 1. 菜单直接进入 → URL 无参数,sessionStorage 无状态 → 使用默认值
|
||
* 2. A 页面跳转进入 → URL 有参数 ?factory=9&startTime=... → 使用 URL 参数
|
||
* 3. C 页面返回进入 → URL 无参数,sessionStorage 有状态 → 使用 sessionStorage 恢复
|
||
*
|
||
* 额外字段配置(可选):
|
||
* 有些页面需要额外字段(如 meterialName),需要在组件 data 中配置:
|
||
* navigationExtraFields: {
|
||
* meterialName: '氢氧化铝' // 字段名: 默认值
|
||
* }
|
||
* 组件中也需要定义对应的 data 字段:meterialName: '氢氧化铝'
|
||
*/
|
||
|
||
import { consumeNavigationState, clearNavigation } from '@/utils/navigationReturnState'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
// 公共状态字段(可被子组件覆盖)
|
||
dateData: {},
|
||
factory: null,
|
||
// 有效基地 ID 列表
|
||
validFactoryIds: [5, 2, 7, 3, 8, 9, 10, 6],
|
||
// 额外字段配置(可被子组件覆盖)
|
||
// 格式:{ 字段名: 默认值 }
|
||
// 例如:{ meterialName: '氢氧化铝' }
|
||
navigationExtraFields: {}
|
||
}
|
||
},
|
||
methods: {
|
||
/**
|
||
* 初始化导航状态恢复
|
||
* @param {Function} onStateRestored - 状态恢复后的回调(用于调用 getData)
|
||
*/
|
||
_initNavigationStateMixin(onStateRestored) {
|
||
const currentPath = this.$route.path
|
||
const query = this.$route.query
|
||
|
||
// 防止重复初始化 - 使用实例属性作为标记
|
||
if (this._navigationStateInitialized) {
|
||
return
|
||
}
|
||
this._navigationStateInitialized = true
|
||
|
||
// 菜单入口时,先清空 sessionStorage,避免旧数据影响
|
||
if (query.menu === '1') {
|
||
clearNavigation()
|
||
}
|
||
|
||
const saved = consumeNavigationState(currentPath)
|
||
|
||
// ========== 处理 factory ==========
|
||
const urlFactoryNum = query.factory != null && query.factory !== '' ? Number(query.factory) : null
|
||
const hasUrlFactory = urlFactoryNum != null && this.validFactoryIds.includes(urlFactoryNum)
|
||
let restoredFactory = false
|
||
|
||
// 方式 2:URL 有有效参数
|
||
if (hasUrlFactory) {
|
||
this.factory = urlFactoryNum
|
||
restoredFactory = true
|
||
}
|
||
|
||
// 方式 3:从 sessionStorage 恢复
|
||
if (saved && !restoredFactory) {
|
||
const savedFactoryNum = Number(saved.factory)
|
||
if (saved.factory != null && this.validFactoryIds.includes(savedFactoryNum)) {
|
||
this.factory = savedFactoryNum
|
||
restoredFactory = true
|
||
}
|
||
}
|
||
|
||
// 方式 1:使用 store 默认值
|
||
if (!restoredFactory) {
|
||
if (this.$store.getters.levelList && this.$store.getters.levelList.length > 0) {
|
||
const validBases = this.$store.getters.levelList.filter(item => item.id !== 1)
|
||
if (validBases.length > 0) {
|
||
this.factory = validBases[0].id
|
||
} else {
|
||
this.factory = this.$store.getters.levelList[0].id
|
||
}
|
||
}
|
||
}
|
||
|
||
// ========== 处理 dateData ==========
|
||
const hasUrlDateData = (query.startTime && query.endTime) ||
|
||
(typeof query.dateData === 'string' && query.dateData && query.dateData !== '[object Object]')
|
||
let restoredDateData = false
|
||
|
||
// 方式 2:URL 有参数
|
||
if (hasUrlDateData) {
|
||
if (query.startTime && query.endTime) {
|
||
this.dateData = {
|
||
startTime: Number(query.startTime),
|
||
endTime: Number(query.endTime)
|
||
}
|
||
} else if (typeof query.dateData === 'string') {
|
||
try {
|
||
const parsed = JSON.parse(query.dateData)
|
||
if (parsed && parsed.startTime != null && parsed.endTime != null) {
|
||
this.dateData = parsed
|
||
}
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
restoredDateData = true
|
||
}
|
||
|
||
// 方式 3:从 sessionStorage 恢复
|
||
if (saved && !restoredDateData) {
|
||
if (saved.dateData && saved.dateData.startTime != null && saved.dateData.endTime != null) {
|
||
this.dateData = {
|
||
startTime: saved.dateData.startTime,
|
||
endTime: saved.dateData.endTime
|
||
}
|
||
restoredDateData = true
|
||
}
|
||
}
|
||
|
||
// ========== 处理额外字段(如 meterialName)==========
|
||
const extraFields = this.navigationExtraFields || {}
|
||
const extraFieldKeys = Object.keys(extraFields)
|
||
const extraFieldResults = {}
|
||
|
||
extraFieldKeys.forEach(fieldName => {
|
||
const defaultValue = extraFields[fieldName]
|
||
let restored = false
|
||
|
||
// 方式 2:URL 有参数
|
||
if (query[fieldName] != null && query[fieldName] !== '') {
|
||
this[fieldName] = query[fieldName]
|
||
restored = true
|
||
extraFieldResults[fieldName] = { source: 'url', value: query[fieldName] }
|
||
}
|
||
|
||
// 方式 3:从 sessionStorage 恢复
|
||
if (saved && !restored && saved[fieldName] != null) {
|
||
this[fieldName] = saved[fieldName]
|
||
restored = true
|
||
extraFieldResults[fieldName] = { source: 'sessionStorage', value: saved[fieldName] }
|
||
}
|
||
|
||
// 方式 1:使用默认值
|
||
if (!restored) {
|
||
this[fieldName] = defaultValue
|
||
extraFieldResults[fieldName] = { source: 'default', value: defaultValue }
|
||
}
|
||
})
|
||
|
||
// 状态恢复完成后,调用回调
|
||
this.$nextTick(() => {
|
||
if (onStateRestored) {
|
||
onStateRestored({
|
||
factory: this.factory,
|
||
dateData: this.dateData,
|
||
...extraFieldResults
|
||
})
|
||
} else if (this._onNavigationStateRestored) {
|
||
this._onNavigationStateRestored({
|
||
factory: this.factory,
|
||
dateData: this.dateData,
|
||
...extraFieldResults
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 保存当前页面状态到 sessionStorage
|
||
* @param {string} targetPath - 目标页面路径
|
||
* @param {object} extraState - 额外要保存的状态(可选,用于动态添加字段)
|
||
*/
|
||
_saveNavigationState(targetPath, extraState = {}) {
|
||
const { pushNavigation, saveNavigationState } = require('@/utils/navigationReturnState')
|
||
const currentPath = this.$route.path
|
||
|
||
// 收集额外字段
|
||
const extraFields = this.navigationExtraFields || {}
|
||
const extraFieldData = {}
|
||
Object.keys(extraFields).forEach(fieldName => {
|
||
if (this[fieldName] != null) {
|
||
extraFieldData[fieldName] = this[fieldName]
|
||
}
|
||
})
|
||
|
||
const state = {
|
||
dateData: this.dateData && this.dateData.startTime != null ? {
|
||
startTime: this.dateData.startTime,
|
||
endTime: this.dateData.endTime
|
||
} : undefined,
|
||
factory: this.factory,
|
||
...extraFieldData,
|
||
...extraState
|
||
}
|
||
pushNavigation(currentPath, state)
|
||
saveNavigationState(currentPath, state)
|
||
|
||
// 构建 URL query
|
||
const query = {
|
||
factory: this.factory != null ? String(this.factory) : '',
|
||
startTime: this.dateData && this.dateData.startTime != null ? String(this.dateData.startTime) : '',
|
||
endTime: this.dateData && this.dateData.endTime != null ? String(this.dateData.endTime) : ''
|
||
}
|
||
|
||
// 添加额外字段到 query
|
||
Object.keys(extraFieldData).forEach(fieldName => {
|
||
query[fieldName] = extraFieldData[fieldName]
|
||
})
|
||
|
||
return {
|
||
path: targetPath,
|
||
query
|
||
}
|
||
}
|
||
}
|
||
}
|