仓储首页重构实施说明.md 21 KB

仓储首页重构实施说明

更新日期:2026-10-16。

首页继续嵌套在 EleAdmin 页面内容区,保留原系统菜单、页头及标签栏。仅移除看板自身重复的顶部品牌/筛选栏和左侧导航,展示用户截图红框内的数据总览。看板主内容使用内容区可用宽度并随内容增长,根节点不得使用视口级 fixed/inset/z-index 或强制系统布局全屏。保留首页卡片下钻、明细筛选和返回首页入口;仓库/单位继续从现有路由参数及接口默认值读取。此约定以用户最新确认的“嵌套在页面里面、需要之前系统菜单”为准。

页面与组件

普通及宇信首页通过 warehouseManagement/index/index.vue、common.vue、yuxin.vue 嵌套进入 dashboard.vue。三个历史入口都保留原路径,避免新增“点击首页”才能打开的独立看板路由。入口组合首页、9个统计视图、待我审批和4个原业务视图,共15个视图;首页不保留快捷新建按钮,新增单据从出入库列表进入。

文件 职责
index/dashboard.vue 路由筛选、真实请求、刷新生命周期、报表导出、业务导航及批量收货队列
index/components/HomeOverview.vue 待办、指标、图表、预警与动态展示,事件上抛到入口
index/components/DashboardChart.vue ECharts绘图、点击下钻、尺寸适配与实例销毁
index/detail.vue、dashboard-screens.js 真实明细列、筛选、分页、操作和统计口径
index/components/DashboardActions.vue 阈值、采购需求、处置、财务登记与逐单结果
api/warehouseManagement/dashboard.js 统一鉴权请求和业务响应校验,身份保留字符串

dashboardView取值:home/ledger/dead/io/todo/age/alerts/turnover/locations/qc/flow/addin/addout/ioapp/inapp。筛选保存在路由查询中,显式空unit表示不自动选默认单位。月份初值使用本地月份完整首末日,接口以服务端规则再次校验。

首页以外的14个配套视图如下:

视图 路由值
库存台账 ledger
呆滞品分析 dead
出入库动态 io
待办单据 todo
批次库龄 age
安全库存预警 alerts
周转分析 turnover
库位地图 locations
入库质检 qc
待我审批 flow
新增入库单 addin
新增出库单 addout
出入库申请 ioapp
入总库申请 inapp

数据口径与刷新

  • 使用/wms/index/home-options、home-summary、home-detail及home-alert-config,不保留原型示例数字。
  • 不同基本单位不相加。库存含待检与锁定;库存总量、分类、库龄、周转等 KPI 的可用量扣锁并排除未放行(batchRows 的available_count_base−锁定量)。安全库存预警是唯一例外:预警可用量=在库量−锁定量、含待检与未放行,走alertRows 的独立子查询,与上述 KPI 不同源;batchRows/costRows 两个共享片段因此不得改动,理由见《仓储首页看板口径.md》A1。金额按可核实入库价估值,缺价不显示为零。
  • 呆滞认定要求首次入库及最近实际消耗均超过180天,占比使用呆滞估值与全部库存估值。日期或估值不足时展示原因。
  • summary.capturedAt显示为“服务端查询时间”;7日前日末实际采集时间由comparisonReason说明,不能将本次接口时间当作日结时间。
  • 总统计15分钟、预警5分钟、动态30秒刷新;后两类通过section=alerts/activities更新对应区块。请求序号及生命周期世代阻止旧响应覆盖新筛选;页面停用、销毁后清理定时器。
  • 明细真实分页,导出沿当前筛选逐页读取。空值保留未知语义,缺日期显示“日期待核实”。

原业务链路

  • 待入/出库、入总库按本月整单待办打开,默认状态0;清除首页物料、单位筛选,避免与整单计数口径冲突。入总库原API在每次查询时固定type=1,重置筛选不会混入出库申请。
  • 批量收货从真实WMS申请列表选择,逐单打开原入库表单,完成原校验和包装明细组装后暂存请求,全部核对后调用/wms/dashboard/action/batch-receive。来源为/wms/applystoragedetail/listByAppIds;extInfo.dashboardApplyDetailId保留申请明细ID,采购来源sourceReceiveProductId原样保留。
  • 批量收货确认期间阻止重复请求;旧表单事件必须与当前inId匹配。成功项移除,失败项保留完整请求及原requestKey供重试。成功表示保存并提交原审批或质检,库存变动仍取决于原流程。
  • 库存盘点入口默认type=inventory;待审批使用真实当前任务分页及逐单审批返回值。业务身份禁止转成JavaScript数值。
  • 阈值按仓库与物料基本单位配置,要求0≤最低≤安全≤最高且精度4位;历史单位不一致时提示核对。采购需求保存为EOM草稿,需在原需求详情核对并提交。
  • 呆滞处置依次保存草稿、提交真实审批、执行原调拨或出库、登记独立财务凭证。驳回/撤销可重新提交;审批本身不变动库存。财务附件复用原上传组件。
  • 库位用途字段为allocationPurpose=ordinary/repair/temporary/virtual,启停字段为enabled=0/1;新货位普通且启用,历史空值保留待核实。

跨系统与权限

从当前用户授权菜单解析门户同源入口。WT接收warehouseScope/warehouseId/month/taskId后,先按真实任务ID和授权范围查询,再打开原审批容器。WT新增stagnantDisposal/detailDialog.vue读取真实处置申请,submit.vue复用现有审批意见、通过与驳回处理。EOM通过requirementId打开原采购需求详情。

本地没有QMS前端项目,质检操作仅标“打开检验工作台”,传批次参数;未证明目标工作台消费这些参数,不宣称可精确打开质检报告。

WMS/WT/EOM在dashboard=1时启用深色Element主题。WMS样式限制在页面内容区及看板专用弹层:DashboardActions使用wms-dashboard-dialog,其选择框使用wms-dashboard-popper;不得直接覆盖整个body下的Element组件。系统页头部门、角色输入框及选项面板保持原白色样式。接口仍由服务端校验授权仓库及业务权限,不以隐藏前端按钮代替鉴权。

验证与验收边界

最终定向检查:WMS 22个、WT 5个、EOM 3个改动的Vue/JS/SCSS文件,模板编译、Babel脚本解析及看板Sass编译均无失败;三个前端仓库git diff --check通过。WT处置审批另用Vue实际选项合并断言,确认无独立模板的子组件继承原渲染函数、审批方法、任务参数,且后端两个组件路径均指向本地现存文件。

上述重构检查未执行完整前端构建、Maven、浏览器或设备验证,也未调用真实写接口。Sass仅出现现有旧JS API弃用提示。新增文档和断言脚本均未被忽略规则排除,未暂存或提交本次改动。

2026-10-16展示范围修正:实际本地浏览器确认首页位于.ele-admin-content内,系统菜单、页头和标签栏可见;部门、角色输入框和展开的选项面板计算背景均为rgb(255, 255, 255)。卡片进入库存台账及返回首页已验证。修正后的布局、看板及操作弹层模板和脚本解析、三份看板SCSS编译、现有业务断言和git diff --check通过;系统布局文件无最终差异。本次未执行完整构建、设备验证或真实写操作。

运行node scripts/check-warehouse-dashboard.cjs可重复验证月份边界、空值/零值、大整数身份、授权菜单路径、整单待办筛选、“其他”分组下钻、重复收货事件与失败项幂等重试;脚本直接加载现有组件方法,使用请求桩,不访问数据库。

部署前须在目标环境联调真实响应、菜单路径、弹层布局、审批模型及权限、采购草稿、批量收货审批/质检、处置执行与财务附件。日末数据需等真实采集积累,缺失历史不能用样例或补造值替代。后端表结构与模型准备参见后端项目docs/仓储管理首页重构-统计与数据核验.md及影响地图。

2026-10-16首页入口约定:本次将“白色字典背景”暂按“白色字体”处理,标题“仓储管理总览”和“下午好,xxx”使用白色字体,保留看板深色背景;库存总量、库存金额、库存分类“查看台账”及分类图点击统一跳转原库存台账/warehouseManagement/stockLedger,待入库与入库管理使用/warehouseManagement/stockManagement,待出库与出库管理使用/warehouseManagement/outgoingManagement,不进入首页自建台账或出入库列表。原系统入口不携带dashboard=1;ledger事件与stockLedger事件统一分流,避免其他统计页的“查看库存”再次进入自建台账。前文重构记录中的台账下钻约定以本条为准。原台账未读取首页分类查询参数,本次仅保证进入原页面,不宣称自动选中分类。

2026-10-29下钻页深色主题泄漏修复(蓝色背景问题):现象是从仓储首页下钻打开的页签(出库单详情、入库单详情、盘点工单详情、调拨详情、批次详情)整页呈深蓝底色而不是系统白底。根因不是页面自身样式,而是深色主题的实现方式:dashboard-element.scss 以 body.wms-dashboard-theme .ele-admin-content 为作用域,router.afterEach 又按 to.query.dashboard === '1' 在 body 上开关该 class,而 dashboard.vue 的 navigate() 会把 dashboard=1 一并推到业务页 URL;beforeDestroy 里 this.$route.query.dashboard !== '1' 的判断在新路由已切换后才执行,同样留下 class。于是新页签里所有 .el-card/.el-table/.el-input 被刷成 #0A1A30,白底页面看起来就是「蓝色背景」。修复方式是把主题从「URL 参数驱动的全局 class」改为「看板自身容器作用域」:dashboard-element.scss 去掉 body.wms-dashboard-theme .ele-admin-content,只保留 .wms-home(看板模板根节点)与 .wms-dashboard-dialog/.wms-dashboard-popper(append-to-body 的弹层与 popper);dashboard.vue 不再在 mounted/activated/beforeDestroy 操作 document.body.classList;router.afterEach 删除 query→class 的切换;navigate() 不再向业务页透传 dashboard=1(保持「系统原有入口不携带 dashboard=1」的约定),并补上吞 NavigationDuplicated 的 catch,重复点同一行不再弹错。dashboard=1 保留给看板自身的内部视图(tgTable 批量收货勾选、warehouseApplication 批量审批),这两处的判断都在看板路由内,不受影响。验证:npx sass 编译 dashboard-element.scss 通过;vue-template-compiler 解析 dashboard.vue/HomeOverview.vue/DashboardActions.vue 模板与 Babel 解析脚本、router/index.js 均通过;node scripts/check-warehouse-dashboard.cjs 原 12 组断言仍全通过,并新增 G1「深色主题作用域」断言(禁止 body. 级作用域、禁止 document.body.classList 主题开关、禁止 navigate 带 dashboard=1),该组断言对修复前的文件实测会失败,非空转;eslint 对 router/index.js 的报错数量由 10 降为 9(改动的第 76 行原本就是 prettier 报错行,余下 9 条为既有问题),git diff --check 通过。本次未执行完整构建与浏览器验证,蓝色背景是否消失需在目标环境点开上述五个下钻页确认;WT/EOM 两仓库的看板主题若同样以 body class 实现,需要各自单独排查(本次只改 WMS 前端)。

2026-10-29首页默认基本单位:进入首页时基本单位下拉框默认选中第一个基本单位。原因是多基本单位下不选单位,后端只能按「单位待核实」处理——库存总量、库存金额、周转天数、库龄结构、分类分布等 KPI 整片为空,用户看到的就是「首页没有数据」;下拉框虽然有「全部单位」,但不该是默认值。实现:后端 GET /wms/index/home-options 已下发 defaultUnit(unitRows.get(0),按授权仓库算好),前端 dashboard.vue 新增 defaultUnit()(优先 options.defaultUnit,缺失回退 units 第一个非空单位)与 applyDefaultUnit(explicit),在 readRoute()(仅 view === 'home')和 created() 拿到筛选项之后再各兜一次——第一次 readRoute 时 options 还没到,只靠 readRoute 会漏掉首屏;默认值同时写进 filters.unit,否则请求参数里根本没有 unit。判定「用户是否表过态」只看 URL 里有没有 unit 键:显式 unit= 是用户主动选的「全部单位」,保持不动;已有单位不覆盖。同时修掉两处会退回「全部单位」的入口:setWarehouse 不再把单位清空(单位列表是全部授权仓库口径,与单仓无关,清空后切仓立刻没数据),open('home') 从出入库申请/入总库申请返回时把被这两个视图清掉的单位补回来(这两个视图按单位过滤会把申请单筛空,所以它们自己不带单位)。验证:node scripts/check-warehouse-dashboard.cjs 新增 H1 断言组(默认选中 defaultUnit、回退 units[0]、空白单位不选、无单位返回空串、显式空单位与已选单位不被覆盖、setWarehouse 不再出现 unit: ''、返回首页补单位、created 后补兜一次);该组断言对修复前文件实测全部失败,非空转。模板/脚本解析、git diff --check 通过;未执行完整构建与浏览器验证,首屏是否直接出数需在目标环境确认。

2026-10-29盘点工单详情下钻地址修正:现象是从首页点「盘点任务进行中」/出入库动态里的盘点流水,跳转地址是 …/stocktaking/work/details?startTime=…&endTime=…&page=1&warehouseId=…&unit=KG&categoryId=…&id=…,既没有 planId,还糊了一串首页筛选参数,详情页报错。两处根因:①navigate() 把首页整套 this.filters 整包拼进业务页 URL(详情页只认 id/planId,其余全是噪声);②盘点两个下钻入口只带 id,正常地址应是列表页那套 ?id=<工单ID>&planId=<计划ID>。修复:navigate() 只透传显式参数(cleanQuery({...query}),不再 ...this.filters、也不再带 dashboard=1);business('todo') 与 business('io') 的盘点分支改为 { id, planId: row.planId }。planId 由后端首页查询列下发:WmsHomeMapper.xml#todoRows 三分支各补第 11 列(盘点分支 CAST(o.plan_id AS CHAR),另两分支 NULL),recentActivities 两分支各补第 12 列(盘点分支真实 plan_id,出入库分支 NULL),UNION 列数保持一致(11/11/11、12/12)。兼容:旧链接/旧数据没有 planId 时 cleanQuery 直接丢弃该键,不会拼出 planId=undefined;后端 PlanServiceImpl#getOrderInfoByPlanId 已能由工单反查 plan_id 兜底,所以两种地址都能打开。验证:node scripts/check-warehouse-dashboard.cjs 新增 I1 断言组(待办与动态两个入口都带 id+planId、planId 缺失不拼 undefined、URL 只剩显式参数、navigate 源码不得再出现 ...this.filters),全通过且对修复前文件实测失败;xmllint --noout、UNION 列数一致性脚本、模板/脚本解析、Sass、git diff --check 均通过。未执行完整构建、未部署、未连真实库。

2026-10-29「出入库动态 › 查看动态」改落 V13 出入库申请:原链接发 open('io'),落到首页自建的 V4 出入库动态列表(已完成流水明细,粒度是快照行)。用户要的是单据本身,改为 open('ioapp', { status: '' }) → dashboardView=ioapp,打开与系统菜单同一个「出入库申请」组件(入库/出库两个页签)。关键点:open() 对 ioapp 的默认 status=0(未处理)会把已完成单据挡住,所以必须显式传空串,cleanQuery 再把它丢掉,等价于申请列表的「全部状态」默认值(search.vue 的 defaultWhere.status='');direction 由 open() 兜底为入库页签;warehouseId 随首页筛选带过去,categoryId/unit 被 ioapp 分支清掉(按单位筛申请单会把单据筛空),时间窗沿用 monthRange() 本月。V4 列表仍然可达,入口不删:「最近作业动态 › 全部动态」、趋势柱体/无作业日点击、以及 V4 里调拨行的「查看单据」都还是 open('io'),所以 scripts/check-warehouse-dashboard.cjs 里「全部动态 › 必须仍发 open('io')」的既有断言保持不动。验证:新增 J1 断言组(模板必须发 open('ioapp', { status: '' });行为断言走真实 open()+route(),确认 dashboardView=ioapp、direction=in、带 warehouseId、query 里没有 status(否则又变回只看未处理)、unit 为空、带本月 startTime/endTime;「全部动态 ›」仍发 open('io')),全通过。模板/脚本解析、git diff --check 通过;未起浏览器验证,需在实际环境点一次确认 V13 列表默认是全部状态且入库页签有数据。

2026-10-29「查看动态」落点再修正:上一版改成看板内嵌的 open('ioapp')(dashboardView=ioapp,仍停在首页路由、只是切换内部视图),用户要的是菜单真实路由——跳 /warehouseManagement/inboundRequests(出入库申请)这个独立页签。最终实现:HomeOverview.vue 的「查看动态 ›」改发 $emit('navigate', '/warehouseManagement/inboundRequests', { warehouseId }),dashboard.vue 在 <home-overview> 上增加 @navigate="navigate",复用已有的 navigate()(只透传显式参数、cleanQuery 丢空值、吞 NavigationDuplicated)。只带当前仓库:状态/时间/页签交给目标页默认值(search.vue 的 defaultWhere.status=''=全部状态、默认入库页签、无时间窗),不得带 dashboard=1(会误开看板批量收货勾选列);未选仓库时 query 为空,?warehouseId= 这种空串不落 URL。V4 动态列表入口保持不变(「全部动态 ›」、趋势柱体/无作业日、调拨行「查看单据」仍发 open('io')),既有「全部动态 › 必须仍发 open('io')」断言不动。验证:J1 断言组重写为路由断言——模板必须发 navigate('/warehouseManagement/inboundRequests', { warehouseId: warehouseId }) 且不得出现 open('ioapp')/open('io'),dashboard.vue 必须有 @navigate="navigate";行为断言走真实 navigate() 确认 push 的 path 是 /warehouseManagement/inboundRequests、query 只有 warehouseId、无 dashboard、仓库为空时 query 为空对象。全套 11 组断言、模板/脚本解析、git diff --check 通过;未起浏览器,需实际点一次确认打开的是菜单「出入库申请」页签而不是首页内嵌视图。

2026-10-29首页首屏遮罩:看板渲染慢,之前是空卡片先渲染、数字分批填充,用户看到的是「首页没有数据」。改为首屏盖一层遮罩,数据(home-options + home-summary)落定后再显示内容。实现:dashboard.vue 增加 homeLoading(默认 true),created() 里 await this.refresh() 之后置 false(只置一次,15 分钟定时刷新、筛选项切换、路由 query 变化都不再闪遮罩);模板在 .wms-home 内加 <div v-if="homeLoading && view === 'home'" class="home-loading">转圈 + 「正在加载首页数据…」</div>,只挡首页视图——明细视图(V2/V4/V5…)有自己的 v-loading,不能被这块盖住。加载失败同样撤遮罩,露出 HomeOverview 的错误条与「重试」。样式写在 dashboard-layout.scss:.wms-home 补 position: relative 作为遮罩定位上下文(已核对 .screen-band/.card/.kpi/.todo-item 这些绝对定位装饰本来就有各自的 relative 父级,不会因为新增定位上下文移位),遮罩 position: absolute + z-index: 20 + 与看板同色的径向渐变 + min-height: 320px 下限(首屏内容为空时 .wms-home 只靠 min-height:100% 撑高,防止极端情况下压成一条线);不能用 position: fixed,那会连系统页头、菜单、标签栏一起盖掉(与 dashboard-element.scss 的既定约束一致)。转圈用 @keyframes home-loading-spin。验证:新增 K1 断言组(homeLoading 默认 true;created 中 await refresh() 之后再置 false 且全文件只出现一次;模板 v-if 必须带 view === 'home';样式必须 absolute + z-index + 动画关键帧,且不得出现 position: fixed),全套 12 组断言、模板/脚本解析、两份 SCSS 编译、git diff --check 通过。未执行完整构建与浏览器验证,实际首屏出数时间与遮罩停留时长需在目标环境确认。