hr-system/docs/01-design/ui-design.md

238 lines
16 KiB
Markdown
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.

# 迭代1总体设计 —— UI/页面设计(hr-web,ocai 口径)
- 版本:v2.0(迭代1-总体设计,取代 v1 Vue3/Element Plus 口径,v1 已归档至 `docs/_archive/01-design-v1-old/ui-design.md`)
- 状态:评审通过(主agent评审,基线冻结)
- 规范依据:ocai 技能集 bricks-framework、bricks-layout-patterns、module-development-spec(index.ui 强制)、crud-definition-spec;交互基线 `docs/01-design/architecture.md`
## 1. 界面体系与总体布局
1. **技术形态**:无 Vue/无手写 HTML。页面 = `wwwroot/*.ui`(纯 JSON bricks 组件树)+ `*.dspy`(数据端点);CRUD 列表/表单页由 json/*.json 经 xls2ui 自动生成 DataViewer/Form/Tree 页面。
2. **入口**:`/index.ui`(应用门户,菜单聚合 6 模块入口);每模块强制 `/{module}/index.ui`(ResponsableBox 功能卡片导航)。
3. **权限渲染**:菜单与按钮可见性由 rbac 角色控制(Menu 只注册已授权路径;操作按钮 binds 前按角色渲染)。
4. **核心 widgets**:VBox/HBox、ResponsableBox(自适应,员工自助移动端兼容)、Menu、DataViewer(列表:data_filter 筛选/toolbar binds/子表 subtables)、Tree(组织树)、Form、PopupWindow、Chart(报表)、Text、FileUpload/FilePreview、UrlWidget。
5. **binds actiontype 仅 5 种**:urlwidget / script / url / datawidget / event(禁止 script 内 fetch;弹窗走 PopupWindow + urlwidget)。
6. **URL 规则**:.ui 内全部 url 使用 `{{entire_url('/module/xxx.ui')}}` 绝对路径;json/ 内引用别名用 `{{entire_url('../alias')}}`。
### 1.1 应用门户 /index.ui
```
index.ui (VBox, height:100%)
├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_list 未读数)]
├── 内容区(HBox, flex:1)
│ ├── Menu(id:app.menu, width:220px)
│ │ ├── 工作台 → /hrsystem/workbench_*.ui(按角色路由)
│ │ ├── 组织管理 → /hrorg/index.ui
│ │ ├── 花名册 → /hrroster/index.ui
│ │ ├── 审批中心 → /hrflow/index.ui
│ │ ├── 合同管理 → /hrcontract/index.ui
│ │ ├── 人事报表 → /hrreport/index.ui
│ │ ├── 员工服务 → /hrsystem/service.ui(公告/政策)
│ │ └── 系统管理 → /hrsystem/index.ui(角色/范围/管理员/日志)
│ └── VBox(id:app.content, flex:1) ← Menu items url 统一加载到此
└── 说明:Menu 不加 binds(内部处理点击);内容区置于 sidebar 之前(DOM 顺序)
```
## 2. 路由表(wwwroot 自动路由)
| URL | 页面 | 说明 | 角色 |
|---|---|---|---|
| /index.ui | 应用门户 | 全局导航 | L |
| /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/黑名单 | L |
| /hrorg/org_tree.ui | 组织管理 | Tree + 详情表单 + 变更时间轴 | L |
| /hrorg/org_chart.ui | 组织架构图 | 层级展开/as_of 历史/导出 | A,H |
| /hrorg/position_list.ui 等 | 职位/职务/职级/职等/序列 CRUD | xls2ui 生成 DataViewer | A,H |
| /hrorg/entry_workbench.ui | 入职工作台 | 待入职/审批中/黑名单高亮 | A,H |
| /hrorg/transfer_list.ui | 调动查询 | 待确定/已确定/已取消筛选 | A,H,M |
| /hrorg/leave_workbench.ui | 离职工作台 | 待离职名单/交接/证明 | A,H,M |
| /hrroster/index.ui | 花名册入口 | 卡片:花名册/字段配置/工号规则/导入导出 | A,H |
| /hrroster/roster_list.ui | 花名册列表 | DataViewer + data_filter + 自定义列 | A,H,M(团队) |
| /hrroster/employee_detail.ui | 员工档案 | Tabs 分组 + 时间轴 | L(按范围) |
| /hrroster/field_config.ui | 字段/分组/类型规则配置 | 拖拽排序 | A,H |
| /hrflow/index.ui | 审批中心入口 | 待办/已办/我发起/我收到/流程配置 | L |
| /hrflow/todo_list.ui | 待办列表 | DataViewer,行内审批 | L |
| /hrflow/inst_detail.ui | 审批单 | 表单渲染 + 流转记录 + 操作按钮 | 参与者 |
| /hrflow/flow_design.ui | 流程/表单/节点/审批角色配置 | A,H/A | A,H |
| /hrcontract/index.ui | 合同入口 | 台账/类型/模板/提醒规则 | A,H |
| /hrcontract/contract_list.ui | 合同台账 | DataViewer + 到期高亮 | A,H |
| /hrreport/index.ui | 报表看板 | 五类分析卡片 | A,H,M |
| /hrreport/report_board.ui | 看板页 | Chart 组件 | A,H,M |
| /hrsystem/index.ui | 系统管理入口 | 角色/管理员/数据范围/日志/提醒配置 | A |
| /hrsystem/workbench_employee.ui | 员工工作台 | 个人档案/发起审批/待办 | E |
| /hrsystem/workbench_manager.ui | 经理工作台 | 团队统计/入转调离审批/关怀 | M |
| /hrsystem/workbench_admin.ui | 管理员工作台 | 人事统计/合同/提醒 | A,H |
| /hrsystem/audit_log_list.ui | 操作日志 | DataViewer + 详情对比弹窗 | A |
| /hrsystem/service.ui | 员工服务 | 公告/政策查询预览 | L |
| /hrsystem/message_list.ui | 站内消息 | 未读/已读 | L |
## 3. 关键页面结构与组件树
### 3.1 组织管理 /hrorg/org_tree.ui(F01)
```
org_tree.ui (HBox)
├── 左侧 VBox(width:320px)
│ ├── 搜索行(HBox): Input(keyword) + Button[搜索](binds script → 触发 Tree 刷新)
│ ├── Tree(id:org_tree, dataurl=/hrorg/api/org_tree.dspy, 点击节点→右侧详情)
│ └── 工具按钮行: [新增子组织][新增同级](PopupWindow → org_unit_form.dspy) [导入](FileUpload→org_import.dspy)
└── 右侧 VBox(flex:1)
├── 组织详情 Form(id:org_detail, dataurl=/hrorg/api/org_unit_detail.dspy?id=..)
│ 字段: org_code/org_name/org_type(codes:ORG_TYPE)/leader_id(dataurl:employee_options)/effective_date/自定义字段(动态渲染 org_field_def)
├── 操作按钮行: [编辑][移动(PopupWindow)][停用(二次确认)] ← A/H 角色可见
└── 变更时间轴 VBox(id:org_timeline, dataurl=/hrorg/api/org_change_timeline.dspy)
每条: Text(时间+操作人+类型) + before/after 对比展开
```
交互:Tree 节点点击 → urlwidget 刷新 org_detail 与 org_timeline(params_mapping 传 id);停用前弹确认 PopupWindow;停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active)。
### 3.2 组织架构图 /hrorg/org_chart.ui(F01)
```
org_chart.ui (VBox)
├── 工具行(HBox): DatePicker(as_of 历史日期) + TreeSelect(根节点) + 显示内容多选(姓名/职位/负责人) + Button[查看][导出PNG][导出XMind]
└── Chart/Tree 容器(id:chart_box, dataurl=/hrorg/api/org_tree.dspy?as_of=..&root_id=..)
```
交互:as_of 变更后重查;导出经 PopupWindow 提示后浏览器下载(org_chart_export.dspy 返回文件)。
### 3.3 花名册列表 /hrroster/roster_list.ui(F03,CRUD 生成)
```
roster_list.ui = DataViewer(json/roster_employee_list.json 生成)
├── data_filter: keyword(姓名/工号 LIKE) + org_id(TreeSelect:org_options) + employee_status(codes) + employee_type(codes) + 自定义字段筛选(动态追加)
├── toolbar binds:
│ ├── [新增员工] → PopupWindow → roster_employee_create.dspy
│ ├── [导入] → PopupWindow: 模板下载链接 + FileUpload(roster_import.dspy) + 结果文件下载
│ ├── [导出] → PopupWindow: 字段多选(拖拽排序) + as_of 日期 → roster_export.dspy
│ └── [字段配置] → url 跳转 field_config.ui(A/H)
├── 列: 工号/姓名(点击→employee_detail.ui?id=)/组织/职位/员工类型/状态/入职日期 + 自定义显示列
└── 行操作: [详情][发起转正][发起调动][办理离职](按角色与员工状态显隐)
```
### 3.4 员工档案 /hrroster/employee_detail.ui(F03)
```
employee_detail.ui (VBox)
├── 头部卡片(HBox): 头像 + 姓名/工号/状态标签 + 快捷操作[编辑][发起审批](PopupWindow 选择 biz_type)
├── Tabs(id:profile_tabs)
│ ├── Tab 分组字段(按 roster_field_group 动态生成): Form 只读/可编辑(按 editable_self+角色)
│ ├── Tab 时间轴(id:timeline, dataurl=timeline.dspy, 垂直时间线) + [添加记录](A/H)
│ ├── Tab 兼岗记录(DataViewer subtables: org_concurrent_post by employee_id)
│ ├── Tab 合同(DataViewer subtables: contract_info by employee_id)
│ └── Tab 审批记录(dataurl=inst_mine.dspy?about=..)
└── 附件: 字段类型=file → FileUpload + FilePreview(file_preview_url.dspy)
```
交互:自助修改——employee 角色仅看到 editable_self=1 字段可编辑;提交时若字段 need_audit=1,服务端走 roster_self_edit 审批流,页面提示"已提交审核";否则直接生效。
### 3.5 入转调离工作台(F04~F07)
```
entry_workbench.ui (VBox)
├── 状态卡片行(ResponsableBox): 待入职数/审批中数/本月入职数(dataurl=workbench_transfer.dspy)
├── 待入职列表 DataViewer(org_entry by entry_status=pending_entry)
│ ├── 黑名单命中行: 高亮样式(confidential_fields/行样式) + [拦截原因]
│ └── 行操作: [邀请填登记表][发送入职通知][直接入花名册]
└── 工具行: [手动入职(批量 PopupWindow)][发起入职审批]
transfer_list.ui: DataViewer(org_transfer) + data_filter(status=pending/confirmed/cancelled, transfer_type, effective_date)
行操作: [查看明细(org_transfer_detail subtable)][取消](pending 状态)
leave_workbench.ui (VBox)
├── 待离职名单 DataViewer(org_leave by status=pending_leave)
│ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑)][办理离职][开具证明][加入黑名单(确认弹窗)]
└── 已离职列表 DataViewer(status=left) + [离职证明下载]
```
### 3.6 审批中心(F10)
```
todo_list.ui = DataViewer(dataurl=task_todo.dspy)
列: 审批编号/标题/发起人/发起时间/当前节点 行操作:[审批]→ inst_detail.ui?instance_id=
inst_detail.ui (VBox)
├── 表单渲染区(id:form_box, dataurl=inst_detail.dspy) —— 按 flow_form_def 动态渲染,节点字段权限控制可编辑性
├── 流转记录 VBox: 节点链(提交→各审批人意见/时间)
└── 操作行(binds urlwidget POST): [同意(task_approve.dspy)][驳回(task_reject.dspy)][转交(PopupWindow 选人)][撤回(发起人)][打印(inst_print.dspy)]
操作完成后 script 刷新页面 → 列表刷新
flow_design.ui (A/H): 三区块
├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_def)
├── 流程定义 DataViewer(flow_def) + 节点编辑 PopupWindow(审批人类型/通过规则/字段权限)
└── 审批角色 DataViewer(flow_role, 仅 admin)
```
### 3.7 报表看板 /hrreport/report_board.ui(F13)
```
report_board.ui (VBox)
├── 顶部 Tab: 花名册分析 | 入职 | 转正 | 调岗 | 离职
├── 花名册分析 Tab: 维度选择器(codes: type/status/age/edu/location/gender + 自定义字段) + Chart(饼图/柱状, dataurl=roster_analysis.dspy) + 明细 DataViewer
├── 入职 Tab: 维度(部门/地区/岗位) + 周期选择 + Chart(趋势折线 + 分布柱)
├── 转正 Tab: Chart(趋势) + 近期待转正 DataViewer(regular_analysis.dspy)
├── 调岗 Tab: 日期范围 + Chart(按类型柱状)
└── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图)
```
所有看板查询服务端叠加数据范围;manager 仅见团队。
### 3.8 系统管理(F11/F12/F15)
```
index.ui(hrsystem): 卡片导航 → role_admin.ui / data_scope.ui / audit_log_list.ui / remind_config.ui / service.ui
role_admin.ui: DataViewer(角色) + 权限树勾选 PopupWindow(rbac paths)
data_scope.ui: 管理员列表 + 范围编辑 PopupWindow(scope_type 切换: 组织 TreeSelect 多选 / 花名册字段多选)
audit_log_list.ui: DataViewer(module/operation/date_range 筛选) + 行[详情] → PopupWindow 前后 JSON 对比(左右双栏 Text)
remind_config.ui: DataViewer(sys_remind_rule) + DataViewer(sys_care_config)
service.ui: Tabs[公告 DataViewer(sys_announcement)][政策 DataViewer(sys_policy, 行内预览/下载按权限)]
message_list.ui: DataViewer(msg_type/is_read 筛选) 行点击标已读
```
### 3.9 工作台(F14)
```
workbench_employee.ui (ResponsableBox)
├── 卡片: 个人档案(→employee_detail.ui?id=self) | 发起审批(PopupWindow 选择流程类型→flow_start)
├── 待办/已办/我发起/我收到 四 Tab DataViewer(task_todo/done/inst_mine/received)
workbench_manager.ui (VBox)
├── 统计卡片行(dataurl=team_stats.dspy): 团队人数/本月入离职/待审批数
├── 待审批 DataViewer(task_todo 范围=团队) | 团队入转调离 DataViewer(workbench_transfer.dspy)
└── 关怀提醒 VBox(生日/周年/合同到期 近期列表)
workbench_admin.ui (VBox)
├── 人事统计卡片(team_stats scope=all) + 合同即将到期 DataViewer(contract_expire_soon.dspy)
└── 待审批 + 关怀提醒(同经理视图,范围=数据权限内全部)
```
## 4. 核心交互流程(页面级时序)
1. **入职(审批)**:entry_workbench [发起入职审批] → PopupWindow 表单 → entry_approval.dspy →(BLACKLIST_HIT 则红色高亮提示)成功 → 待审批列表出现;审批人在 todo_list 处理 → inst_detail 同意 → 花名册新增记录 → message_list 收到入职通知。
2. **员工自助修改**:employee_detail → 编辑可改字段 → 保存 → 提示"直接生效"或"已提交审核"(need_audit)→ 审核通过后字段更新、时间轴留痕。
3. **调动批量**:transfer_list [发起调动] → PopupWindow 多人选择 + 目标组织/职位 → transfer_apply.dspy → 生成批量审批单 → 通过后逐人更新,明细可追溯。
4. **离职全流程**:leave_workbench 发起/手动 → 待离职名单 → [交接管理]逐项勾选 → [办理离职] → 状态 left → [开具证明]下载 → 可选[加入黑名单]。
5. **合同到期提醒**:remind_scan(后台)→ message_list 消息 → workbench_admin 到期卡片 → contract_list 行内到期高亮。
6. **历史架构图**:org_chart 选择 as_of 日期 → 查看 → 导出 PNG/XMind。
## 5. 设计规范
1. **布局**:左侧 Menu 固定 220px;内容区 VBox 滚动;卡片统一圆角 8px、间距 16px;表单 label 右对齐;列表默认每页 50。
2. **状态色**:active/在职=绿、probation/审批中=橙、inactive/离职/驳回=灰、黑名单/超期=红。
3. **反馈**:操作成功 message 提示并刷新当前视图;不可逆操作(停用/删除语义/加黑名单)一律 PopupWindow 二次确认;耗时操作(导入导出)返回 task_id 后轮询/消息通知结果。
4. **空态/加载**:DataViewer 自带 loading 与空数据提示。
5. **权限感知**:按钮与列按角色渲染(load_path + CRUD confidential_fields);敏感字段服务端脱敏后展示。
6. **移动端兼容**:员工自助页面(工作台/档案/待办/服务/消息)使用 ResponsableBox 自适应,窄屏卡片化;管理类页面 PC 优先。
7. **打印**:审批单 inst_print.dspy 输出 A4 打印样式页面。
## 6. 页面-接口追溯
| 页面 | 主要接口(见 api-design.md) |
|---|---|
| org_tree.ui | org_tree / org_unit_create / org_unit_update / org_unit_move / org_unit_disable / org_change_timeline / org_import |
| org_chart.ui | org_tree(as_of) / org_chart_export |
| roster_list.ui | roster_list / roster_employee_create / roster_import / roster_export / check_employee_no |
| employee_detail.ui | employee_detail / roster_employee_update / timeline / file_preview_url |
| entry_workbench.ui | entry_approval / entry_manual / entry_invite_register / entry_blacklist_check / entry_notify |
| transfer_list.ui | transfer_apply / transfer_cancel |
| leave_workbench.ui | leave_apply / leave_manual / leave_handover_save / leave_certificate / blacklist_add |
| todo_list.ui / inst_detail.ui | task_todo / inst_detail / task_approve / task_reject / task_forward / inst_withdraw / inst_print |
| flow_design.ui | form_def_save / flow_def_save / flow_node_save / flow_role_save |
| contract_list.ui | contract_list / contract_create / contract_import / contract_apply / contract_remind_rule_save |
| report_board.ui | roster_analysis / entry_analysis / regular_analysis / transfer_analysis / leave_analysis |
| workbench_*.ui | workbench_employee / workbench_manager / workbench_admin / team_stats |
| audit_log_list.ui | audit_log_list / audit_log_detail |
| remind_config.ui / service.ui | remind_rule_save / care_config_save / announcement_save / policy_save |