Sync: add container security notes

This commit is contained in:
2026-04-24 13:16:42 +08:00
parent 761fa71f69
commit 3b55f3af4d
16 changed files with 626 additions and 144 deletions

View File

@@ -1,8 +1,8 @@
# PRD: 组织人事管理模块
**状态**: Draft
**作者**: 产品经理
**最后更新**: 2026-04-24v1.1 新增 Story 11-14补充员工离职、员工调动、奖惩记录查看与新增并同步更新技术实现与附录
**版本**: 1.1
**最后更新**: 2026-04-24v1.2 移除技术实现章节,该部分由独立 DATA_MODEL 文档承载
**版本**: 1.2
**所属系统**: Fonrey 房产经纪管理系统
**关联模块**: 权限管理、房源管理、客源管理、系统设置
@@ -465,125 +465,7 @@
---
## 6. 技术实现说明
### 6.1 数据模型
```python
# apps/org/ 模块核心数据模型
class OrgUnit(TenantModel):
"""部门/组织单元"""
name = CharField(max_length=100) # 部门名称
parent = ForeignKey('self', null=True, blank=True) # 上级部门(树形结构)
level = CharField(choices=LEVEL_CHOICES) # 级别:事业部/大区/区域/片区/门店/店组/职能
attribute = CharField(choices=[('direct', '直营'), ('franchise', '加盟')]) # 部门属性
status = CharField(choices=[('active', '启用'), ('closed', '关闭')])
address_city = CharField(blank=True)
address_district = CharField(blank=True)
address_detail = CharField(blank=True)
lat = DecimalField(null=True) # 坐标纬度
lng = DecimalField(null=True) # 坐标经度
manager = ForeignKey('Staff', null=True, related_name='managed_depts') # 负责人
phone = CharField(blank=True)
ext_range_start = IntegerField(null=True) # 分机范围起
ext_range_end = IntegerField(null=True) # 分机范围止
founded_at = DateField(null=True)
class Staff(TenantModel):
"""员工档案"""
# 任职信息
nickname = CharField() # 昵称
staff_no = CharField() # 工号
org_unit = ForeignKey(OrgUnit) # 所属部门
position = ForeignKey('Position') # 职务
position_type = CharField() # 职务类别
level = IntegerField() # 职级
status = CharField(choices=STAFF_STATUS_CHOICES) # 正式/试用/离职
supervisor = ForeignKey('self', null=True) # 直属上级
first_joined_at = DateField()
rejoined_at = DateField(null=True)
left_at = DateField(null=True)
# 个人信息
real_name = CharField()
id_type = CharField()
id_number_encrypted = CharField() # 加密存储
id_verified = BooleanField(default=False)
gender = CharField()
birth_date = DateField(null=True)
# 联系方式
phone_encrypted = CharField() # 手机号加密存储
phone_visible = BooleanField(default=True) # 通讯录是否隐藏
# 账号
login_account = OneToOneField('StaffAccount')
# ... 其他个人信息字段
class StaffRewardPunishment(TenantModel):
"""员工奖惩记录"""
staff = ForeignKey(Staff)
date = DateField() # 奖惩日期
category = CharField() # 奖惩类别(奖励/惩戒,下拉枚举)
name = CharField() # 奖惩名称(与类别联动,下拉枚举)
remark = TextField(blank=True) # 备注
created_by = ForeignKey(Staff, related_name='created_rewards')
created_at = DateTimeField(auto_now_add=True)
class StaffMutationLog(TenantModel):
"""员工异动记录"""
staff = ForeignKey(Staff)
org_unit = ForeignKey(OrgUnit) # 异动时所在部门
mutation_type = CharField() # 入职/上级变动/员工调动/离职/复职
mutation_at = DateField() # 异动时间
operated_at = DateTimeField() # 操作时间
old_value = CharField(blank=True)
new_value = CharField(blank=True)
remark = TextField(blank=True)
operator = ForeignKey(Staff, related_name='operated_mutations')
```
### 6.2 关键技术约束
**依赖关系**
- `apps/org/` — 组织人事核心 App`apps/property/``apps/client/``apps/permissions/` 等模块引用(员工归属、权限主体)
- `apps/permissions/` — 权限控制,决定哪些角色可查看员工完整手机号、隐私信息
- `core/encryption.py` — 手机号、证件号加密工具(所有敏感字段加密存储)
**性能约束**
- 部门树形列表使用 MPTTModified Preorder Tree Traversal或 Closure Table 优化多层级查询,避免 N+1 问题
- 架构图最多支持 8 层级数量
- 异动记录量大(示例图显示 575 条),需分页处理,默认 20 条/页
**异步任务**
- 「报表导出」(员工列表、异动记录)通过 Celery 异步执行,避免大数据量导出阻塞请求
**HTMX 交互模式**
- 左侧部门树点击切换右侧员工列表HTMX 局部刷新右侧内容区
- 员工详情 Tab 切换(员工基本信息/异动记录/账号信息HTMX 局部刷新内容区
- 架构图Alpine.js 管理展开/折叠状态SVG 或 Canvas 渲染树形结构
### 6.3 已知风险
| 风险 | 可能性 | 影响 | 缓解措施 |
|------|--------|------|----------|
| 部门树深度过大导致查询性能下降 | 中 | 高 | 使用 MPTT 存储,限制最大 8 层 |
| 手机号/证件号泄露 | 低 | 极高 | 全字段加密存储,权限控制脱敏展示 |
| 公安系统证件比对接口不稳定 | 中 | 中 | 系统内展示认证状态,接口失败时提示用户手动处理 |
| 多租户隔离失效 | 极低 | 极高 | `django-tenants` Schema 隔离,所有查询强制带租户上下文 |
### 6.4 待确认问题
- [ ] 「入职邀请」功能的具体流程:是发送短信邀请链接自助填写,还是 HR 手动录入?—— 需与业务方确认 —— Deadline: 开发前
- [ ] 证件实名认证是否需要对接公安部接口,还是仅展示状态由人工审核?—— 需与法务/产品负责人确认 —— Deadline: 开发前
- [x] 员工「奖惩记录」字段结构v1.1 已通过截图确认:日期/奖惩类别/奖惩名称/备注)
- [ ] 「员工相关资料」的具体字段结构(本期截图未覆盖)—— 需补充截图或访谈 —— Deadline: 下次迭代前
- [ ] 架构图是否需要支持直接在图上拖拽节点来调整层级关系,还是只读展示?—— 截图提示支持拖拽缩放,但未确认是否支持编辑 —— Deadline: 设计评审前
- [ ] 「员工入黑名单」的业务规则与对后续功能的影响(如是否可继续登录系统,名下房源/客源如何处理)—— Deadline: 开发前
- [ ] 离职类型的枚举值清单(如:自离/协商离职/辞退/其他)—— 需与 HR 业务方确认 —— Deadline: 开发前
- [ ] 奖惩类别与奖惩名称的完整枚举值及联动规则 —— 需与 HR 业务方提供配置清单 —— Deadline: 开发前
---
## 7. 上线计划
## 6. 上线计划
| 阶段 | 时间 | 受众 | 验收门槛 |
|------|------|------|----------|
@@ -599,22 +481,22 @@ class StaffMutationLog(TenantModel):
### 8.1 截图来源
| 截图文件 | 对应功能 |
|----------|----------|
| `公司组织结构.png` | Story 1 — 组织人员列表页 |
| `员工详情.png` | Story 6 — 员工基本信息详情 |
| `员工通讯录.png` | Story 9 — 员工通讯录 |
| `员工详情异动记录.png` | Story 7 — 员工异动记录(个人维度)|
| `员工详情账号信息.png` | Story 8 — 员工账号信息 |
| `部门新增.png` | Story 2 — 新增部门 |
| `部门编辑.png` | Story 3 — 编辑部门 |
| `部门详情.png` | Story 4 — 部门详情 |
| `组织员工异动记录.png` | Story 10 — 全局异动记录汇总 |
| `部门架构图.png` | Story 5 — 部门架构图 |
| `员工离职.png` | Story 11 — 员工离职操作Modal 弹窗)|
| `员工调动.png` | Story 12 — 员工调动操作(右侧抽屉面板)|
| `员工奖惩记录.png` | Story 13 — 员工奖惩记录列表 |
| `员工奖惩记录新增.png` | Story 14 — 新增奖惩记录Modal 弹窗)|
| 截图文件路径 | 对应功能 |
|-------------|----------|
| `screenshots/组织人事/组织结构/公司组织结构.png` | Story 1 — 组织人员列表页 |
| `screenshots/组织人事/组织结构/员工详情.png` | Story 6 — 员工基本信息详情 |
| `screenshots/组织人事/组织结构/员工通讯录.png` | Story 9 — 员工通讯录 |
| `screenshots/组织人事/组织结构/员工详情异动记录.png` | Story 7 — 员工异动记录(个人维度)|
| `screenshots/组织人事/组织结构/员工详情账号信息.png` | Story 8 — 员工账号信息 |
| `screenshots/组织人事/组织结构/部门新增.png` | Story 2 — 新增部门 |
| `screenshots/组织人事/组织结构/部门编辑.png` | Story 3 — 编辑部门 |
| `screenshots/组织人事/组织结构/部门详情.png` | Story 4 — 部门详情 |
| `screenshots/组织人事/组织结构/组织员工异动记录.png` | Story 10 — 全局异动记录汇总 |
| `screenshots/组织人事/组织结构/部门架构图.png` | Story 5 — 部门架构图 |
| `screenshots/组织人事/组织结构/员工离职.png` | Story 11 — 员工离职操作Modal 弹窗)|
| `screenshots/组织人事/组织结构/员工调动.png` | Story 12 — 员工调动操作(右侧抽屉面板)|
| `screenshots/组织人事/组织结构/员工奖惩记录.png` | Story 13 — 员工奖惩记录列表 |
| `screenshots/组织人事/组织结构/员工奖惩记录新增.png` | Story 14 — 新增奖惩记录Modal 弹窗)|
### 8.2 术语表