技术栈:Vue 2 + Element UI 2.15 + ele-admin(EleProLayout)+ vuex-persistedstate,样式统一放 src/styles/views/<模块>/…(页面 .vue 用 <style src=… scoped lang="scss"> 引入)。
src/styles/index.scss 有 main[class*='-page'] { min-height: calc(100vh - 100px); display: flex; flex-direction: column; },优先级 (0,1,1) 高于页面自己的 .xxx-page 类 (0,1,0),会覆盖页面的 display 和 min-height。想让页面用 grid/固定高度,根 class 不要带 -page(例如看板页用 psd-screen)。100vh - 顶栏56 - 页签40 - 卡片间距8 = 100vh - 104px(见 ele-admin/lib/ele-pro-layout/style/layout-style.scss)。页面按 height: calc(100vh - 104px) 或 height: 100%(父级 .ele-admin-content-view 高度确定)即可一屏展示、外层 .ele-admin-content(overflow-y: auto)不出滚动条。推荐写成 height: calc(100vh - 104px); max-height: 100%; overflow: hidden —— max-height: 100% 是兜底,门户 chrome 高度不同时也不会溢出。.panel-grid)必须显式 grid-template-rows: minmax(0, 1fr),否则内部行按内容高度撑,flex:1 的图表会收缩到 0、面板只剩标题栏高;② 图表容器不要写死 height: 390px 之类,改用 .chart{flex:1;min-height:0} 跟随面板,饼图容器用 height:100%(父级要是 flex:1 的定高盒子)。auto auto minmax(0,1fr) minmax(0,1fr) + overflow: hidden)让图表有确定高度,ECharts 才不会画布大于容器被裁;容器尺寸变化要把图表容器也纳入 ResizeObserver。position:absolute 四角网格),不要用 ECharts graphic 的百分比定位 —— 容器被拉高后标签会漂离图形中心或被裁。ECharts 饼图 radius 百分比按 min(w,h)/2 计算,容器窄高时图会显得很小。http://192.168.1.147:18086/doc.html(Springfox Swagger2,18 个分组:hr/eom/sys/mes…)。抓取姿势:/swagger-resources → /v2/api-docs?group=hr(约 1MB,web_fetch 会截断,用 Invoke-WebRequest -OutFile + node 解析更可靠)。src/views/homeView/index.vue)数据只来自 GET /hr/overview/data-center(查询人力资源总览),封装在 src/api/hr/overview.js;一次返回 topCards / turnoverTrends / departmentHeadcountRatios / urgentTodos,不再调用 cockpit 与证照预警接口,也不再使用本地 mock 兜底。null(权威事实缺失),前端统一显示 -- 并用 title 提示 message;drillDownPath 由后端给出,前端直接 $router.push。人力资源-人员结构报表(Hr Personnel Structure Report Controller),13 个 GET 全在 /hr/personnel-structure-reports/ 下:dashboard/{summary,structure-trend,overall-distribution,age-distribution,organization-distribution,talent-structure,quality-analysis}、analysis/summary、analysis/{dimensionCode}、mobility-analysis、effectiveness-analysis、details、details/export。src/api/hr/personnelStructure.js(含字段适配 + buildQuery + 两个 adapt* 器),两个页面共用的小工具/枚举在 src/views/hrAnalysis/shared.js(合同类型枚举、组织下拉构造、-- 格式化、trend tone、比例条宽度等)。organizationId/departmentId(int64) + year+month(必须成对,int 1-12) + contractType(字典 code,值由劳动合同模块维护)。buildQuery 兼容 month 传 'yyyy-MM' 或数字。{code,message,data},data = {dataStatus( AVAILABLE/PARTIAL/DATA_UNAVAILABLE ), reportMonth, statisticsDate, message, kpis[], dimensions[], trends[], scopeDepartmentIds[]}。dimensions[].items[] = {valueCode,valueName,count,percentage};kpis[] = {metricCode,metricName,value,unit,rateValue(比例型才有值),monthOnYearRate,yearOnYearRate,dataStatus,message}。metricCode 取值,pickMetric() 用「精确编码 → metricName 关键字 → 返回顺序」三级兜底;若要改指标口径,改 SUMMARY_CARDS/METRIC_CARDS 里的 codes/keywords/index 即可。analysis/{dimensionCode} 的 11 个白名单维度:POSITION_LEVEL、WORK_LOCATION、POSITION_SEQUENCE、DEPARTMENT、GENDER、CONTRACT_TYPE、EDUCATION、AGE、TENURE、POSITION_TENURE、PROFESSIONAL_TITLE(职称未开发,四个字段恒为空值)。没有"职业属性"这类维度。shared.js 的 HIDDEN_DIMENSION_CODES = [PROFESSIONAL_TITLE] + isDimensionVisible/filterVisibleGroups 是唯一开关;看板页签由接口 dimensions 动态生成,所以要靠它过滤(B 页还会跳过职称维度的请求)。职称功能上线后清空该数组即可恢复,页面无需改动。details 只返回统计日在岗人员,分页用 pageNum/size,支持 dimensionCode + dimensionValueCode 组合下钻(图表点击 → 取维度项 valueCode);details/export 返回 blob。effectiveness-analysis 的「人均产出、编制使用率」固定 DATA_UNAVAILABLE,必须展示 message 而不是编数。personnelStructureDashboard 根类 .psd-screen(6 指标卡 + 6 面板,grid 4 行一屏);personnelStructureAnalysisBoard 根类 .psa-board(3 指标卡 + 12 面板 = 4 列 × 3 行,11 个维度 + 人员结构趋势 + 整体人员分布;学历/职称共用一个面板做成页签)。mock.js 已删除;文件已按接口重构(禁止再回退 mock)。src/components/addDoc/index.vue(全局注册为 fileMain)是附件上传/查看统一入口,main.vue 是弹框 + 文件列表,browse.vue 是 kkfile 预览,doc_template.vue 是文档库选择,file-edit.vue 是本地上传。fileMain 查看逻辑:type="view" 且只有 1 个附件时直接进预览、不弹文件列表;多附件才弹列表。user.info 只有门户调用 user/setInfo 后才有值,读 this.user.info.userId 前必须做空值兜底。@/api/organization 的 adaptEmployee / adaptEmployeeProfile;familyMembers、awards、files 目前恒为空数组,payrollType/insuredCity/housingFundAccount 等字段后端不返回。