黄石人流数据大屏
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
7.8 KiB

2 weeks ago
  1. # 客流量大屏改造方案
  2. ## Context(背景与目标)
  3. 现有项目 `hs-flow‑screen` 是一个深色科技风的"借阅/通知大屏"(三栏布局:总借阅、借阅排行、进馆、阅读之星、通知、新书推荐)。用户希望仿照目标页面 `http://libraryu.seaeverit.com:15000/main?token=...` 做一个**客流量大屏**,目标页面布局为:顶部 Header → "客流量展示"标签 → 三列卡片(当日进馆折线图 / 当月进馆折线图 / 当年进馆数字翻牌)→ 全宽"累计客流量汇总"翻牌器。
  4. 经确认的改造口径:
  5. 1. **保留深色科技风视觉**(深蓝背景 `#010326`、白色文字、蓝色发光 `#1AC9FF`、`common-title`/`module-content` 蓝色样式),**不**改成目标页的白底橙色,只仿照**布局结构**。
  6. 2. **保留现有 Header 组件**(动画线条 + 天气 iframe + 渐变标题),标题用"黄石图书馆"。
  7. 3. **删除不再使用的旧组件目录**
  8. 4. **数据先用 mock**,预留接口对接位置。
  9. ## 关键约束(基于源码确认)
  10. - 适配:rem 方案(`src/common/flexible.js`,1920 设计稿,1rem≈80px,范围 1366–2560),所有尺寸用 rem。
  11. - echarts 4:`this.$echarts` 全局已注册(`main.js`),用 `this.$echarts.init(this.$refs.chart)` + ref,**不要用 `getElementById`**(旧 `components/echart/*` 用 id 会有冲突)。
  12. - `resizeMixins.js`(`src/utils/resizeMixins.js`)提供自动 resize(要求组件 `data.chart` 字段),但其 `removeEventListener('reisze'…)` 拼写错误且不 dispose → 新组件须在 `beforeDestroy` 手动 `this.chart.dispose(); this.chart=null`
  13. - 数字翻牌:`vue-count-to` 的 `CountTo`,用法 `<count-to :start-val="0" :end-val="num" :duration="3200" />`
  14. - 滚动:`vue-seamless-scroll` 已 `Vue.use`,组件名 `<seamless>`
  15. - `.common-title` / `.module-content``.screen-main` 的后代选择器 → 新布局根容器必须仍是 `.screen-main`(叠加 `.traffic-main`)。
  16. - Header 标题 prop:`headerTitle`,`getCurrentTime()` 返回"YYYY年MM月DD日 HH:mm:ss"。
  17. - 端口 8080,`npm run serve` 自动开浏览器。
  18. ## 新文件结构
  19. ```
  20. src/views/
  21. ├── index.vue # 改写:Header + <TrafficFlow/>,删除旧的高度计算逻辑
  22. ├── header/index.vue # 保留不动
  23. └── trafficFlow/
  24. ├── index.vue # 新建:.screen-main.traffic-main 布局容器
  25. └── components/
  26. ├── DayInFlowChart.vue # 当日进馆折线图(按小时)
  27. ├── MonthInFlowChart.vue # 当月进馆折线图(按日)
  28. ├── YearInFlowCard.vue # 当年进馆数字翻牌(单个大数字)
  29. └── TotalFlowSummary.vue # 累计客流量汇总(8 位翻牌卡片,横向可滚动)
  30. ```
  31. ## 实施步骤
  32. ### 1. 新建 trafficFlow 4 个子组件 + index.vue(先建骨架,不破坏现有)
  33. - `DayInFlowChart.vue` / `MonthInFlowChart.vue`:`<div class="chart-box" ref="chart"/>`,`mixins:[resize]`,`data.chart=null` + mock 数据,`mounted` → `initChart()``setOption()`,`beforeDestroy` dispose。setOption 用蓝色系(线 `#1AC9FF`、轴 `#2C75E0`、分割线 `rgba(44,117,224,0.3)` 虚线、白色文字、`areaStyle` 用 `this.$echarts.graphic.LinearGradient` 蓝色渐变、`smooth:true`)。
  34. - `YearInFlowCard.vue`:`<count-to :end-val="yearNum"/>`,mock `yearNum:1286500`
  35. - `TotalFlowSummary.vue`:`totalNum:98765432` → `computed.digitList``padStart(8,'0').split('')` 固定 8 位,每位一个 `<count-to>`,外裹 `<seamless :data :class-option>` 横向滚动(`direction:2`)。预留 `fetchData()` 注释。
  36. - `trafficFlow/index.vue`:模板见下方。
  37. ### 2. 在 `src/assets/styles/index.scss` 末尾追加客流量布局样式(不动现有任何规则)
  38. 新增 `// ===== 客流量大屏布局 =====` 段,关键规则:
  39. - `.traffic-main { flex-direction:column; justify-content:flex-start; gap:0.125rem; }`(叠加在 `.screen-main` 上)
  40. - `.traffic-section-title`(顶部"客流量展示"标签,用 `title-big.png`
  41. - `.traffic-row { display:flex; }`、`.traffic-row-3 { flex:1; gap:0.25rem; min-height:0; }`(min-height:0 防 echarts 高度坍缩)
  42. - `.traffic-card { flex:1; display:flex; flex-direction:column; min-width:0; .module-content{flex:1; overflow:hidden; padding:0.125rem 0.2rem;} }`
  43. - `.traffic-summary { height:1.6rem; }`
  44. - `.chart-box { width:100%; height:100%; }`
  45. - `.year-num`(当年大数字,`#1AC9FF` + text-shadow)、`.summary-digits`/`.digit-card`(每位翻牌,`num-img.png` 背景)
  46. ### 3. 改写 `src/views/index.vue` 为极简入口
  47. ```vue
  48. <template>
  49. <div id="screen-container">
  50. <Header :header-title="headerTitle" />
  51. <TrafficFlow />
  52. </div>
  53. </template>
  54. <script>
  55. import Header from '@/views/header/index.vue'
  56. import TrafficFlow from '@/views/trafficFlow/index.vue'
  57. export default {
  58. name: 'Home',
  59. components: { Header, TrafficFlow },
  60. data() { return { headerTitle: '黄石图书馆' } }
  61. }
  62. </script>
  63. <style lang="scss">@import "~@/assets/styles/index.scss";</style>
  64. ```
  65. (删除原 `calcXxxHeight`/`$refs`/resize 监听等所有逻辑)
  66. `trafficFlow/index.vue` 模板骨架:
  67. ```vue
  68. <template>
  69. <div class="screen-main traffic-main">
  70. <div class="common-title traffic-section-title">客流量展示</div>
  71. <div class="traffic-row traffic-row-3">
  72. <div class="traffic-card"><div class="common-title">当日进馆</div><div class="module-content"><DayInFlowChart/></div></div>
  73. <div class="traffic-card"><div class="common-title">当月进馆</div><div class="module-content"><MonthInFlowChart/></div></div>
  74. <div class="traffic-card"><div class="common-title">当年进馆</div><div class="module-content year-content"><YearInFlowCard/></div></div>
  75. </div>
  76. <div class="traffic-row traffic-summary"><TotalFlowSummary/></div>
  77. </div>
  78. </template>
  79. ```
  80. ### 4. 启动验证一轮(`npm run serve`)
  81. 确认:Header + "客流量展示" + 三卡片(两折线图初始化、一翻牌)+ 汇总翻牌滚动;控制台无 echarts 报错。
  82. ### 5. 删除旧组件目录
  83. - `src/views/accessToLibrary/`、`totalLending/`、`lengingRanking/`、`newBookRecommend/`、`notice/`、`readStar/`、`todayBorrowed/`
  84. ### 6. 可选清理
  85. -`src/components/echart/`(删旧组件后无引用)、`src/common/scrollMixins.js`(全项目无引用)。
  86. -`index.scss` 中三栏 `.screen-left/.screen-right/.screen-middle` 及旧组件死 CSS(留着不影响,但建议删三栏那三条以免误导)。
  87. ## 接口对接预留(mock 阶段不做)
  88. - `src/api/library.js``FetchInitIntoNum` 已存在,保留不删。后续在 4 个组件的 `fetchData()`(已注释)中对接,字段参考 `historyPeopleNum`(累计)、`dayPeopleNum`/`monthPeopleNum`(当日/当月总数);按小时/按日粒度折线数据需后端补接口。
  89. ## 验证
  90. 1. `npm run serve``http://localhost:8080`
  91. - Header 显示"黄石图书馆" + 天气 + 每秒跳的时间
  92. - 顶部"客流量展示"标签
  93. - 第一行三列:左/中蓝色平滑折线图(带渐变面积)、右"当年进馆"0→1286500 翻牌动画
  94. - 第二行"累计客流量汇总"8 位翻牌(num-img.png 蓝牌背景)横向滚动
  95. 2. F12 控制台无 echarts init/id 重复/resize 报错
  96. 3. 拖拽窗口:折线图随 resizeMixins 自动 resize,rem 尺寸随 flexible 重算
  97. 4. 改 mock 数字热更新不残留旧 echarts 实例(dispose 生效)
  98. 5. `npm run build` 无打包错误
  99. ## 风险规避
  100. - echarts 容器高度坍缩:`.traffic-row-3 { min-height:0 }` + `.traffic-card .module-content { flex:1 }` 必须同时有;必要时给 `.chart-box` 兜底 `min-height:2rem`
  101. - `seamless` 横向滚动可能因 8 位内容不够触发:调小 `limitMoveNum:1`,或不要滚动直接静态居中("可滚动"非硬需求)。
  102. - 顺序:先建新→改入口→验证→再删旧,避免白屏。