From af01e6a6913da42289c0e34c876bb74e3db4802a Mon Sep 17 00:00:00 2001 From: juzi <819872918@qq.com> Date: Tue, 7 Jul 2026 16:01:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AE=AD=E5=A4=B4=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E9=80=BB=E8=BE=91=E6=88=90=E6=9C=AC=E8=B4=B9=E7=94=A8?= =?UTF-8?q?=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/驾驶舱-路由返回状态保持.md | 245 ------------------ src/views/home/components/cost-Item.vue | 21 +- .../monthlyOverview.vue | 2 +- .../totalOverview.vue | 2 +- .../operatingComponents/verticalBarChart.vue | 6 +- .../monthlyOverview.vue | 2 +- .../totalOverview.vue | 2 +- 7 files changed, 15 insertions(+), 265 deletions(-) delete mode 100644 docs/驾驶舱-路由返回状态保持.md diff --git a/docs/驾驶舱-路由返回状态保持.md b/docs/驾驶舱-路由返回状态保持.md deleted file mode 100644 index c5b97c88..00000000 --- a/docs/驾驶舱-路由返回状态保持.md +++ /dev/null @@ -1,245 +0,0 @@ -# 驾驶舱:导航状态管理方案 - -## 需求概述 - -1. **页面通过菜单进入**:不清空 sessionStorage,使用新日期 -2. **页面带参数跳转**:记录 sessionStorage -3. **sessionStorage 作为容器**: - - 点击跳转(非菜单点击)→ sessionStorage 多一条 - - 点击返回 → sessionStorage 少一条 - - 返回到最开始的页面 → sessionStorage 为空 - - sessionStorage 为空 → 返回按钮消失 -4. **多页面跳转支持**:A 可跳到 E,B 也可跳到 E,返回时能回到来源页面 - -## 方案设计:导航栈 + 页面状态分离 - -### sessionStorage 结构 - -```javascript -// 导航栈:记录访问路径 -key: 'cockpit_nav_stack' -value: [ - { path: '/operatingRevenue', timestamp: 123456 }, - { path: '/operatingRevenueBase', timestamp: 123457 } -] - -// 各页面状态:记录业务数据 -key: 'cockpit_nav_state_/operatingRevenue' -value: { dateData: {...}, factory: 'xxx', toPage: '/operatingRevenueBase' } -``` - -### 核心 API - -```javascript -import { - pushNavigation, // 跳转前调用,将当前页面入栈 - popNavigation, // 返回时调用,出栈并返回前一个页面 - getNavStackLength, // 获取栈长度(用于返回按钮显示) - clearNavigation, // 菜单进入时清空所有(会触发 navigation-cleared 事件) - saveNavigationState, // 保存页面状态 - consumeNavigationState // 消费页面状态 -} from '@/utils/navigationReturnState'; -``` - -### 核心流程 - -| 场景 | 操作 | 结果 | -|------|------|------| -| **菜单进入** | `clearNavigation()` | 清空栈和所有状态,触发 `navigation-cleared` 事件 | -| **A 跳转 B** | `pushNavigation('/A')` + `saveNavigationState('/A', {...})` | 栈长度 +1 | -| **B 返回 A** | `popNavigation()` → 跳转 | 栈长度 -1,状态自动恢复 | -| **栈为空** | 返回按钮隐藏 | 无历史记录 | - -### 跳转时的调用示例 - -```javascript -// A 页面跳转 B -const currentPath = this.$route.path; -const state = { - dateData: { startTime: this.dateData.startTime, endTime: this.dateData.endTime }, - factory: this.$route.query.factory, - toPage: '/B' // 要跳转的目标页面 -}; -pushNavigation(currentPath, state); // 入栈 -saveNavigationState(currentPath, state); // 保存状态 -this.$router.push({ path: '/B', query: {...} }); -``` - -### 返回按钮逻辑(noRouterHeader.vue) - -```javascript -// data -data() { - return { - navStackLength: 0, // 存储栈长度 - } -}, - -// computed:基于 navStackLength 显示按钮 -computed: { - showReturnBtn() { - return this.navStackLength > 0; - } -}, - -// watch:监听菜单进入和路由变化 -watch: { - '$route.query.menu': { - immediate: true, - handler(menuFlag) { - if (menuFlag === '1') { - this.$nextTick(() => { - this.updateNavStackLength(); - }); - } - } - }, - $route() { - this.updateNavStackLength(); - } -}, - -// 生命周期:监听 navigation-cleared 事件 -mounted() { - this.updateNavStackLength(); - window.addEventListener('navigation-cleared', this.handleNavigationCleared); -}, -beforeDestroy() { - window.removeEventListener('navigation-cleared', this.handleNavigationCleared); -}, - -methods: { - updateNavStackLength() { - this.navStackLength = getNavStackLength(); - }, - handleNavigationCleared() { - this.updateNavStackLength(); // 收到清空事件后立即更新 - }, - handleReturn() { - this.$emit('before-return'); - const prev = popNavigation(); // 出栈 - if (prev && prev.path) { - this.$router.push(prev.path); - } else { - this.$router.go(-1); - } - } -} -``` - -### 列表页 mounted 时恢复状态 - -```javascript -mounted() { - // 菜单进入时清空导航栈 - if (this.$route.query.menu === '1') { - clearNavigation(); - } - - const currentPath = this.$route.path; - const saved = consumeNavigationState(currentPath); - if (saved && saved.dateData) { - this.dateData = saved.dateData; - this.getData(); - } -} -``` - -## 涉及文件 - -### 工具类 - -- `src/utils/navigationReturnState.js`: - - 提供导航栈管理 API - - `clearNavigation()` 执行后触发 `navigation-cleared` 事件 - -### 公共组件 - -- `src/views/home/components/noRouterHeader.vue`: - - `showReturnBtn` 根据 `navStackLength` 显示/隐藏返回按钮 - - `handleNavigationCleared` 监听 `navigation-cleared` 事件 - - `updateNavStackLength` 更新栈长度 - - `handleReturn` 出栈并跳转到前一个页面 - -- `src/layout/components/AppMain.vue`: - - `key` 使用 `$route.fullPath`(包含 query 参数),确保组件能正确刷新 - -- `src/layout/components/Sidebar/Link.vue`: - - 点击菜单时自动添加 `menu=1` 和 `_t` 时间戳参数 - -### 跳转组件(点击跳转) - -| 文件 | 改动 | -|------|------| -| `operatingLineBarSale.vue` | 跳转前调用 `pushNavigation` + `saveNavigationState` | -| `yearRelatedMetrics.vue` | 跳转前调用 `pushNavigation` + `saveNavigationState` | -| `monthlyRelatedMetrics.vue` | 跳转前调用 `pushNavigation` + `saveNavigationState` | - -### 详情页 - -| 文件 | 改动 | -|------|------| -| `operatingRevenueBase.vue` | `@before-return` 时无需额外保存(已由跳转组件保存) | -| `salesVolumeAnalysisBase.vue` | 同上 | -| `unitPriceAnalysisBase.vue` | 同上 | - -### 列表页(菜单入口) - -| 文件 | 改动 | -|------|------| -| `operatingRevenue.vue` | `mounted` 时检测 `menu=1` 调用 `clearNavigation()`,并调用 `consumeNavigationState` 恢复状态 | -| `totalProfit.vue` | 同上 | -| `salesVolumeAnalysis.vue` | 同上 | -| `unitPriceAnalysis.vue` | 同上 | -| `expenseAnalysis.vue` | 同上 | -| `grossMargin.vue` | 同上 | -| `fullCostAnalysis.vue` | 同上 | -| `electricityCostAnalysis.vue` | 同上 | -| `inputOutputRatio.vue` | 同上 | -| `netPriceAnalysis.vue` | 同上 | -| `operatingProfit.vue` | 同上 | -| `procurementGainAnalysis.vue` | 同上 | -| `rawSheetYield.vue` | 同上 | -| `productionCostAnalysis.vue` | 同上 | -| `depreciationAnalysis.vue` | 同上 | -| `inventoryAnalysis.vue` | 同上 | -| `accountsReceivable.vue` | 同上 | - -## 注意事项 - -1. **菜单进入清空**:需要在页面入口处调用 `clearNavigation()` -2. **状态键名**:使用页面路径作为键名,如 `/operatingRevenue` -3. **consume 即删除**:`consumeNavigationState` 读取后立即删除 -4. **返回按钮同步**:通过 `navigation-cleared` 事件确保 sessionStorage 清空后返回按钮立即隐藏 -5. **多页面跳转**:导航栈记录完整路径链,支持任意页面间的跳转和返回 -6. **组件刷新**:AppMain 的 key 使用 fullPath,确保带参数的路由能正确刷新组件 -7. **菜单参数**:Link.vue 自动添加 `menu=1` 和 `_t` 时间戳,确保每次 URL 不同 -8. **额外字段配置**:`navigationExtraFields` 必须配置(重要!) - - 如果页面需要额外参数(如 `meterialName`)恢复,必须在组件 `data` 中配置 `navigationExtraFields` - - 格式:`navigationExtraFields: { 字段名: 默认值 }` - - 示例:`navigationExtraFields: { meterialName: '氢氧化铝' }` - - 缺少此配置会导致从详情页返回时额外参数无法恢复 -9. **getData 调用条件**:mixin 回调中 `getData()` 的调用条件 - - 原条件:`if (factory != null && dateData && dateData.startTime != null)` - - 问题:从浏览器直接打开页面时,`dateData.startTime` 为 null,导致 `getData()` 不执行 - - 建议条件:`if (factory != null)` 只要 factory 有值就获取数据 -10. **B→C→B 返回场景分析**: - | 进入 B 方式 | URL 参数 | sessionStorage | 状态恢复来源 | 备注 | - |-------------|----------|-----------------|--------------|------| - | 菜单直接进入 | 无 | 清空 | store 默认值 | 无返回按钮 | - | 从 A 页面跳转 | 有 | 有 | URL 参数 | 需配置 `navigationExtraFields` | - | 从 C 返回 B | 无 | 有 | sessionStorage | 需配置 `navigationExtraFields` | - - 从浏览器直接打开 B → 跳转 C → C 返回 B 时:`dateData.startTime` 可能为 null,需放宽 `getData()` 调用条件 -11. **mixin 使用方式**:`mixins: [navigationStateMixin]` 后,需在组件 `created` 钩子中手动调用 `_initNavigationStateMixin(callback)` - - mixin **不自动执行** `created` 钩子,避免 `_navigationStateInitialized` 标记冲突 - - callback 回调参数:`{ factory, dateData, ...extraFields }` - - 示例: - ```javascript - created() { - this._initNavigationStateMixin(({ factory, dateData }) => { - if (factory != null && dateData && dateData.startTime != null) { - this.getData(); - } - }); - } - ``` diff --git a/src/views/home/components/cost-Item.vue b/src/views/home/components/cost-Item.vue index 2cc8400a..b95ac278 100644 --- a/src/views/home/components/cost-Item.vue +++ b/src/views/home/components/cost-Item.vue @@ -13,7 +13,7 @@
-
+
{{ item.currentValue }}
{{currentTap==='month'?'本月':'本年'}}
@@ -23,7 +23,7 @@
-
+
{{ item.thbe }}
环比额
@@ -126,18 +126,11 @@ export default { }, // 颜色判断:本月 >= 上月 绿色,否则 橙色 - getColor(current, target) { - return current >= target - ? "rgba(98, 213, 180, 1)" // 绿色:增长或持平 - : "rgba(249, 164, 74, 1)"; // 橙色:下降 - }, - - // 计算环比额(本月 - 上月),保留一位小数 - // getData(current, target) { - // const diff = current - target; - // // 正数加"+"号,负数和零保持原样 - // return diff > 0 ? `+${diff.toFixed(1)}` : diff.toFixed(1); - // } + getColor(thbe) { + return thbe < 0 + ? "rgba(98, 213, 180, 1)" // 绿色 + : "rgba(249, 164, 74, 1)"; // 橙色 + } }, }; diff --git a/src/views/home/expenseAnalysisComponents/monthlyOverview.vue b/src/views/home/expenseAnalysisComponents/monthlyOverview.vue index 928f2e73..ac47b3e5 100644 --- a/src/views/home/expenseAnalysisComponents/monthlyOverview.vue +++ b/src/views/home/expenseAnalysisComponents/monthlyOverview.vue @@ -15,7 +15,7 @@
环比{{ monthData?.momRate }}% - +
diff --git a/src/views/home/expenseAnalysisComponents/totalOverview.vue b/src/views/home/expenseAnalysisComponents/totalOverview.vue index bfb03fcf..7d06851e 100644 --- a/src/views/home/expenseAnalysisComponents/totalOverview.vue +++ b/src/views/home/expenseAnalysisComponents/totalOverview.vue @@ -15,7 +15,7 @@
同比{{ ytdData?.yoyRate || 0 }}% - +
diff --git a/src/views/home/operatingComponents/verticalBarChart.vue b/src/views/home/operatingComponents/verticalBarChart.vue index 27a78a19..3258ee91 100644 --- a/src/views/home/operatingComponents/verticalBarChart.vue +++ b/src/views/home/operatingComponents/verticalBarChart.vue @@ -5,7 +5,7 @@
完成率:{{detailData.rate}}% - 差值:{{detailData.diff}} + 差值:{{detailData.diff}}
@@ -18,6 +18,7 @@ export default { data() { return { myChart: null, // 存储图表实例,避免重复创建 + flag: 0, resizeHandler: null, // 窗口resize事件处理器 isMounted: false // 图表挂载标志,避免过早执行 }; @@ -90,7 +91,8 @@ export default { this.myChart = echarts.init(chartDom); const diff = this.detailData.diff || 0 const rate = this.detailData.rate || 0 - const flagValue = (this.detailData.rate>=100?1:0) || 0 + const flagValue = this.detailData.rate>=100?1:0 + this.flag = flagValue const option = { tooltip: { diff --git a/src/views/home/productionCostAnalysisComponents/monthlyOverview.vue b/src/views/home/productionCostAnalysisComponents/monthlyOverview.vue index 157effa1..114fa9d4 100644 --- a/src/views/home/productionCostAnalysisComponents/monthlyOverview.vue +++ b/src/views/home/productionCostAnalysisComponents/monthlyOverview.vue @@ -13,7 +13,7 @@
环比{{ formatRate(factoryData?.thb) }}% - 上升 + 上升 下降
diff --git a/src/views/home/productionCostAnalysisComponents/totalOverview.vue b/src/views/home/productionCostAnalysisComponents/totalOverview.vue index c20206b3..88c7da58 100644 --- a/src/views/home/productionCostAnalysisComponents/totalOverview.vue +++ b/src/views/home/productionCostAnalysisComponents/totalOverview.vue @@ -15,7 +15,7 @@
同比{{ formatRate(factoryData?.thb) }}% - 上升 + 上升 下降