mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 08:20:31 +08:00
7b2bd307f1
- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.) - frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts - scripts/: build, test-env, tools (Docker Compose, service templates, API parity) - docs/: AGENTS.md, superpowers specs, architecture docs - .gitignore: standard Java/Maven exclusions Moved from legacy maven-*/ root layout to backend/ organized structure.
124 lines
6.6 KiB
Markdown
124 lines
6.6 KiB
Markdown
# 访客注册与派梯:被访人、访客与楼层 — 源码级业务流程
|
||
|
||
> 本文与 `**cw-elevator-application-service/docs/08-visitor-registration-and-elevator-auth.md**` 互补:08 偏「接口步骤清单」,本文强调 **被访人 / 访客 / 楼层** 三者关系与 **类方法落点**。电梯应用不负责完整「访客档案登记 UI」,但 `**add/visitor` 显式依赖两条人员主键**。
|
||
|
||
---
|
||
|
||
## 1. 术语(避免混用)
|
||
|
||
|
||
| 称呼 | HTTP / 参数字段 | 含义 | 数据哪里来 |
|
||
| ----------- | ----------------------------- | ----------------------------------------------------- | -------------------------------------------- |
|
||
| **访客** | `visitorId` | 已在**平台人员体系**存在的档案 ID(登记/同步发生在访客业务或 CWOS 组件侧) | 组织库 `cw_is_person` 等;常打 **「访客」标签** |
|
||
| **被访人(员工)** | `personId` | **接待访客的员工**,用于在 **未传 `floorIds`** 时拉取其可派梯楼层 | 同库在职人员,与 `cw_is_person_organization_ref` 挂组织 |
|
||
| **生效楼层** | 内部 `param.floorIds`(可能由服务端改写) | 最终写入 `**image_rule_ref`**、绑定图库的 **楼层 zoneId 列表**(雪花串) | 见 §3 |
|
||
|
||
|
||
**易错点**:`personId` **不是**访客 ID,而是**被访员工** ID。
|
||
|
||
---
|
||
|
||
## 2. 端到端角色关系(产品语义)
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph 登记域["登记域(多在外部/组件)"]
|
||
V["访客档案 visitorId"]
|
||
H["员工档案 personId\n被访人"]
|
||
end
|
||
subgraph 电梯域["电梯应用"]
|
||
A["POST /elevator/person/add/visitor"]
|
||
R["image_rule_ref\npersonId=visitorId"]
|
||
end
|
||
H -->|Feign detail 取 floorList| A
|
||
V --> A
|
||
A --> R
|
||
```
|
||
|
||
|
||
|
||
- **访客要访问的是员工(被访人)** → API 上体现为:用 `**personId`** 定位被访人,用 `**visitorId**` 定位访客档案。
|
||
- **电梯侧写规则**:按 `**visitorId`** 在各区写入规则引用(`ImageRuleRefAddDto.personId = visitorId`),**不是**写在被访人名下。
|
||
|
||
---
|
||
|
||
## 3. 楼层从哪里来(核心业务逻辑)
|
||
|
||
实现类:`**PersonRuleServiceImpl#addVisitor`**(`person/impl/PersonRuleServiceImpl.java`)。
|
||
|
||
### 3.1 调用方 **传入非空 `floorIds`**
|
||
|
||
- **跳过**被访人详情与租户策略整段。
|
||
- **直接使用**调用方给出的楼层列表作为 `**effectiveFloors`**(需非空,否则 `76260531`)。
|
||
- **责任**:楼层合法性、是否仍应受租户策略约束,由调用方或上游 BFF 保证(产品文档另有说明)。
|
||
|
||
### 3.2 调用方 **未传 / 空 `floorIds`(常见访客路径)**
|
||
|
||
1. `**PersonService#detail`**(Feign,组件 `**/component/person/detail**`)
|
||
- 入参:`PersonDetailParam.id = param.getPersonId()`(**被访人**)、`businessId = context.getCompany().getCompanyId()`。
|
||
- 出参:`**PersonResult.getFloorList()`** → 记为 `**hostFloors**`(字符串列表,元素为电梯域认可的 **zoneId**,雪花形态,与 `**image_rule_ref.zone_id`** 一致)。
|
||
2. **失败分支**
|
||
- detail 失败 / 无数据 / `**hostFloors` 为空** → `**76260531`**(无可用楼层依据)。
|
||
3. **租户默认策略(可选收窄)**
|
||
- `**TenantVisitorFloorPolicyDao#selectEnabledTenantDefault(companyId)`** → 表 `**tenant_visitor_floor_policy**`。
|
||
- 条件:`enabled=1`、`policy_type=INTERSECT_ALLOWLIST`、租户级默认(`building_id` 空)。
|
||
- `**allow_zone_ids**`:JSON 字符串数组,解析为 `**allowSet**`。
|
||
- **生效楼层**:`**effectiveFloors = hostFloors 按原顺序过滤,仅保留 ∈ allowSet`**(`intersectPreserveHostOrder`)。
|
||
- 若交集 **为空** → `**76260532`**(与租户允许楼层无交集)。
|
||
4. **首层 → 楼栋 → 图库**
|
||
- 取 `**effectiveFloors.get(0)`**,`**ZoneService#page**` 得 `**ZoneResult**`,再 `**deviceImageStoreDao.getByBuildingId(首层 parentId)**` → `**imageStoreId**`。
|
||
5. **逐层写规则 + 绑访客图库**
|
||
- 对每个 floorId:`**imageRuleRefDao.getDefaultByZoneId`** → 组装 `**ImageRuleRefAddDto**`,`**personId = param.getVisitorId()**`(访客)。
|
||
- `**imageStorePersonService.batchBind**`:把 **访客** 绑到该楼栋图库,访期 `**begVisitorTime` / `endVisitorTime`**。
|
||
- `**updateGroupPersonRef**`:同步组人员引用。
|
||
|
||
### 3.3 小结公式
|
||
|
||
- **无显式 floorIds 时**:
|
||
|
||
\text{effectiveFloors} = \begin{cases}
|
||
\text{hostFloors} & \text{无启用策略或 allow 为空}
|
||
\text{hostFloors} \cap \text{allowzoneids} & \text{策略启用且 allow 非空}
|
||
\end{cases}
|
||
|
||
- **交集为空** → `**76260532`**;**hostFloors 为空** → `**76260531`**。
|
||
|
||
---
|
||
|
||
## 4. 与「访客注册」一词的边界
|
||
|
||
|
||
| 步骤 | 是否在电梯仓实现 |
|
||
| ------------------------------------ | ------------------ |
|
||
| 访客姓名/证件/人脸建档、预约单 | **否**(外部系统 / 组件) |
|
||
| 拿到 `**visitorId` + 被访员工 `personId`** | 前置条件 |
|
||
| **派梯授权**(写规则 + 绑图库) | **是**,`addVisitor` |
|
||
|
||
|
||
因此:**完整「访客注册」业务** = 外部登记 + **本接口授权**;本文楼层逻辑仅覆盖授权链。
|
||
|
||
---
|
||
|
||
## 5. 关键源码索引
|
||
|
||
|
||
| 步骤 | 类 / 方法 |
|
||
| ------- | ---------------------------------------------------------- |
|
||
| HTTP 入口 | `AcsPersonController` → `/elevator/person/add/visitor` |
|
||
| 聚合逻辑 | `PersonRuleServiceImpl#addVisitor` |
|
||
| 被访人楼层 | `PersonService#detail` → `PersonResult#getFloorList` |
|
||
| 租户策略 | `TenantVisitorFloorPolicyDao#selectEnabledTenantDefault` |
|
||
| 策略表 | `tenant_visitor_floor_policy` |
|
||
| 规则落库 | `ImageRuleRefDao#getDefaultByZoneId` / `insertList` |
|
||
| 图库 | `ImageStorePersonService#batchBind`、`updateGroupPersonRef` |
|
||
|
||
|
||
---
|
||
|
||
## 6. 测试数据在建模上的要求
|
||
|
||
- **每条用例**应能指向:**组织 / 部门**、**一名被访员工(host)**、**一名访客(visitor)**。
|
||
- 导出脚本从 DB 解析:**员工** = 部门下在职人员;**访客** = 带「访客」标签的人员池,按套件 `**business_id`** 过滤,与用例 **轮询配对**(避免同源语义缺失)。
|
||
- 详见 `**tools/visitor_floor_verification/config/test_matrix.json`** 与导出快照 `**host_employee` / `visitor_for_api**` 字段。
|
||
|