/** * 驾驶舱页面导航状态恢复 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 } } } }