Files
yudao-dev/src/utils/mixins/navigationStateMixin.js

220 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 驾驶舱页面导航状态恢复 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
// 方式 2URL 有有效参数
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
// 方式 2URL 有参数
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
// 方式 2URL 有参数
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
}
}
}
}