mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 08:20:31 +08:00
8b15445328
Former-commit-id: 1de24b7eb79676d1aba9d799a58c5a753290cf52
9.4 KiB
9.4 KiB
租户 / 组织 / 人员 / 访客 — 数据模型、表关系与用例
文档性质:架构梳理(电梯仓 + 组织组件约定)。
校验状态:已使用 tools/visitor_floor_verification/.env.visitor_verify 所列主机(本地开发库)执行 INFORMATION_SCHEMA + 抽样查询,纪要见 §6.1(日期 2026-04-30)。其它环境仍以现场库为准。
关联精读:访客注册与派梯楼层 — 业务流程、租户访客默认楼层隔离边界。
1. 术语与请求上下文
| 术语 | 含义 | 典型落点 |
|---|---|---|
| 租户 / 机构 ID | 多租户数据隔离边界 | HTTP Header businessid → FeignThreadLocalUtil → CloudwalkCallContext.company.companyId |
business_id(库列) |
与上下文 businessid 相同的字符串 |
组织库 cw_is_organization.BUSINESS_ID、cw_is_person.BUSINESS_ID;电梯库 tenant_visitor_floor_policy.business_id、image_rule_ref.business_id |
| 组织节点 ID | 机构树上一节点(公司、部门等) | cw_is_organization.ID;父子关系 PARENT_ID → ID |
人员主键 personId |
API / 组件语境的人员 ID | 对应组织库 cw_is_person.ID(导出 CSV 列名为 ID) |
| 被访人 | 接待访客的员工 | add/visitor 请求体字段 personId(勿与访客混淆) |
| 访客 | 访客档案 | 请求体 visitorId;派梯写库时 image_rule_ref.person_id = 访客 ID |
关键辨析
business_id不是cw_is_organization的主键。组织节点主键为ID;BUSINESS_ID是在同一租户下多行组织节点上重复出现的作用域字段。- 跨库之间不存在数据库级外键;一致性依赖
business_id与cw_is_person.ID(API 字段personId)。关联表cw_is_person_organization_ref.PERSON_ID存储的也是该ID。
2. 数据库边界(两库)
flowchart TB
subgraph orgLib [component_organization]
O[cw_is_organization]
P[cw_is_person]
R[cw_is_person_organization_ref]
L[cw_is_person_label_ref]
LB[cw_is_label]
end
subgraph elevLib [cw_elevator_application]
POL[tenant_visitor_floor_policy]
IRR[image_rule_ref]
end
O -->|"树 PARENT_ID"| O
R -->|"ORG_ID"| O
R -->|"PERSON_ID"| P
L -->|"PERSON_ID"| P
L -->|"LABEL_ID"| LB
POL -.->|"business_id 对齐 BUSINESS_ID"| P
IRR -.->|"business_id"| P
IRR -.->|"person_id 常为访客"| P
3. 逻辑 ER(组织库)
组织侧表无权威 DDL 收于本仓库;下列字段来自导出脚本、测试文档与 export_catalog.py 中的 SQL 用法。
erDiagram
cw_is_organization {
string ID PK "组织节点"
string PARENT_ID FK "父节点 ID 可空"
string BUSINESS_ID "租户范围重复列"
string NAME "节点名称"
}
cw_is_person {
string ID PK "人员主键 API personId"
string BUSINESS_ID "租户"
string NAME "姓名"
int IS_DEL "是否删除"
}
cw_is_person_organization_ref {
string PERSON_ID FK "人员"
string ORG_ID FK "组织节点"
}
cw_is_organization ||--o{ cw_is_organization : "parent_child"
cw_is_person ||--o{ cw_is_person_organization_ref : "membership"
cw_is_organization ||--o{ cw_is_person_organization_ref : "org_node"
cw_is_person 列名与访客判定
- 仓库内导出示例 docs/testing/_cw_is_person__202604302030.csv 表头为
ID,BUSINESS_ID,IS_DEL等,与 2026-04-30 开发库一致。 - 开发库
cw_is_person不存在列:person_id、deleted、labels、business_name、organization_name。访客标签通过cw_is_person_label_ref(PERSON_ID、LABEL_ID)关联cw_is_label(含BUSINESS_ID、NAME);示例租户下NAME='访客'对应LABEL_ID=ed2dbab6d6234a7287106b80857c819e。
4. 逻辑 ER(电梯库)
依据 tenant_visitor_floor_policy.sql 与 ImageRuleRefMapper.xml。
erDiagram
tenant_visitor_floor_policy {
string id PK
string business_id "租户 UK 组成部分"
string policy_type "如 INTERSECT_ALLOWLIST"
text allow_zone_ids "JSON zoneId 数组"
string building_id "预留楼栋维度可空"
int enabled
bigint policy_version
}
image_rule_ref {
string id PK
string business_id
string zone_id "楼层区域"
string zone_name
string parent_rule "父规则"
string person_id "访客开通场景为访客"
int person_delete
string include_labels
string include_organizations
int is_default
}
访客默认楼层策略语义(UC-01,未传 floorIds)
- 启用且
allow_zone_ids非空时:生效楼层为PersonResult.floorList∩allow_zone_ids(保持floorList顺序)。 - 详见
PersonRuleServiceImpl#addVisitor与 租户访客默认楼层-数据库配置阶段技术设计。
5. 角色与派梯用例(电梯侧)
flowchart LR
actor Caller as Caller_BFF
participant API as AcsPersonController
participant PR as PersonRuleServiceImpl
participant Org as PersonService_detail
participant Pol as TenantVisitorFloorPolicyDao
participant IRR as ImageRuleRefDao
participant Img as ImageStorePersonService
Caller -->|"POST_add_visitor"| API --> PR
PR -->|"floorIds_empty"| Org
PR --> Pol
PR --> IRR
PR --> Img
flowchart TD
subgraph UC01 [UC01不传floorIds]
U1[add_visitor]
U2[detail_host_floorList]
U3[optional_policy_intersect]
U4[write_image_rule_ref_visitor]
U5[batchBind_visitor]
U1 --> U2 --> U3 --> U4 --> U5
end
subgraph UC02 [UC02显式floorIds]
V1[add_visitor]
V2[skip_detail_and_policy]
V3[write_rules_bind]
V1 --> V2 --> V3
end
subgraph UCRead [回读验收]
R1[passRule_image_personId_visitor]
end
6. 附录:现场核对 SQL 与纪要
6.1 开发库核对纪要(2026-04-30)
以下为使用 maven-cw-elevator-application/tools/visitor_floor_verification/.env.visitor_verify(主机、端口、账号由本地填写,勿将密钥写入 Git)连接所得摘要:
| 项目 | 结果 |
|---|---|
根机构 BUSINESS_ID=2524639890ba4f2cba9ba1a4eeaa4015 |
节点 NAME=星河湾中心,ID=d656e3ab3f61440bb7b9bc23b76834b9,与 BUSINESS_ID 字符串不相等 |
cw_is_person |
主键列 ID;删除 IS_DEL;无 person_id、deleted、labels、business_name、organization_name |
cw_is_organization |
含 ID、PARENT_ID、BUSINESS_ID、NAME、IS_DEL 等(大量 EXT*) |
cw_is_person_organization_ref |
ID、PERSON_ID、ORG_ID 及审计列 |
cw_is_person_label_ref / cw_is_label |
用于人员标签;访客标签 NAME='访客' 对应 LABEL_ID=ed2dbab6d6234a7287106b80857c819e(该租户) |
information_schema.TABLE_CONSTRAINTS |
上述组织表 仅有 PRIMARY KEY / UNIQUE,未声明 FOREIGN KEY |
cw-elevator-application.tenant_visitor_floor_policy |
列与仓库 DDL 一致;示例租户 enabled=1,allow_zone_ids 含 605560545117995008 |
6.2 INFORMATION_SCHEMA 模板(任意环境)
-- 组织库:核心表列一览
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'component-organization'
AND TABLE_NAME IN (
'cw_is_organization',
'cw_is_person',
'cw_is_person_organization_ref',
'cw_is_person_label_ref',
'cw_is_label'
)
ORDER BY TABLE_NAME, ORDINAL_POSITION;
-- 根节点与 BUSINESS_ID 是否相等(现场逐项核对)
SELECT ID, PARENT_ID, BUSINESS_ID, NAME
FROM cw_is_organization
WHERE BUSINESS_ID = '2524639890ba4f2cba9ba1a4eeaa4015'
ORDER BY ID
LIMIT 20;
-- 电梯库:策略表列
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'cw-elevator-application'
AND TABLE_NAME IN ('tenant_visitor_floor_policy', 'image_rule_ref')
ORDER BY TABLE_NAME, ORDINAL_POSITION;
7. 文档索引(与本模型一致)
| 文档 | 用途 |
|---|---|
| visitor-registration-business-flow.md | 被访人 / 访客 / 楼层源码链路 |
| visitor-registration-floor-validation.md | 测试矩阵与现场组织示例 |
| tenant-visitor-default-floor-isolation.md | business_id 粒度与隔离边界 |
| 租户访客默认楼层-数据库配置阶段技术设计.md | 求交语义与阶段范围 |