Files
starRiverProperty/docs/architecture/租户组织人员访客-数据模型与用例.md
T
反编译工作区 8b15445328 feat: add service config templates and extraction script
Former-commit-id: 1de24b7eb79676d1aba9d799a58c5a753290cf52
2026-05-01 19:38:01 +08:00

224 lines
9.4 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.
# 租户 / 组织 / 人员 / 访客 — 数据模型、表关系与用例
**文档性质**:架构梳理(电梯仓 + 组织组件约定)。
**校验状态**:已使用 [`tools/visitor_floor_verification/.env.visitor_verify`](../../maven-cw-elevator-application/tools/visitor_floor_verification/.env.visitor_verify) 所列主机(本地开发库)执行 **`INFORMATION_SCHEMA` + 抽样查询**,纪要见 **§6.1**(日期 **2026-04-30**)。其它环境仍以现场库为准。
**关联精读**[访客注册与派梯楼层 — 业务流程](../testing/visitor-registration-business-flow.md)、[租户访客默认楼层隔离边界](../testing/tenant-visitor-default-floor-isolation.md)。
---
## 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. 数据库边界(两库)
```mermaid
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`](../../maven-cw-elevator-application/tools/visitor_floor_verification/scripts/export_catalog.py) 中的 SQL 用法。
```mermaid
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](../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`](../../maven-cw-elevator-application/releases/v2.0.0/ddl/tenant_visitor_floor_policy.sql) 与 [`ImageRuleRefMapper.xml`](../../maven-cw-elevator-application/cw-elevator-application-data/src/main/java/cn/cloudwalk/elevator/record/mapper/ImageRuleRefMapper.xml)。
```mermaid
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`](../../maven-cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/person/impl/PersonRuleServiceImpl.java) 与 [租户访客默认楼层-数据库配置阶段技术设计](../business/租户访客默认楼层-数据库配置阶段技术设计.md)。
---
## 5. 角色与派梯用例(电梯侧)
```mermaid
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
```
```mermaid
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 模板(任意环境)
```sql
-- 组织库:核心表列一览
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](../testing/visitor-registration-business-flow.md) | 被访人 / 访客 / 楼层源码链路 |
| [visitor-registration-floor-validation.md](../testing/visitor-registration-floor-validation.md) | 测试矩阵与现场组织示例 |
| [tenant-visitor-default-floor-isolation.md](../testing/tenant-visitor-default-floor-isolation.md) | `business_id` 粒度与隔离边界 |
| [租户访客默认楼层-数据库配置阶段技术设计.md](../business/租户访客默认楼层-数据库配置阶段技术设计.md) | 求交语义与阶段范围 |