mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-11 01:10:29 +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.
189 lines
7.9 KiB
Markdown
189 lines
7.9 KiB
Markdown
# 租户访客默认楼层策略 — 业务逻辑重设计
|
||
|
||
> **废止 / 仅作历史归档(2026-05-06)**
|
||
> **现行规范**以 **[租户访客默认楼层策略 — 迁入组织组件](./2026-05-06-tenant-visitor-policy-organization-implementation.md)** 为准:租户策略 **`allow_zone_ids` 只能在组织 `PersonService.detail` 以「**替代**」写入 `floorList`**;**禁止**将策略定义为与被访人楼层 **「求交(∩)」**。电梯 `addVisitor` **不再**读取策略表、**不再**做 ∩。
|
||
> 下文保留 **2026-05-05** 草稿中的电梯侧求交流程图,**仅供对照旧表述**,勿作为实现或验收依据。
|
||
|
||
**日期**:2026-05-05
|
||
**状态**:已废止(见上)
|
||
**设计依据**:产品方案 [租户访客默认楼层技术产品方案](../../business/租户访客默认楼层技术产品方案.md)
|
||
**涉及代码**:`PersonRuleServiceImpl.addVisitor`(现行代码已按 2026-05-06 规范移除电梯侧策略 ∩)
|
||
|
||
---
|
||
|
||
## 1. 业务规则(核心不变量)—— **历史草案,已被「替代语义」取代**
|
||
|
||
| 规则 | 说明(历史) |
|
||
|------|------|
|
||
| ~~**策略全时生效**~~ | **废止**:电梯侧不再全时查策略表;策略在组织 detail **替代** `floorList`。 |
|
||
| **策略即安全边界** | `allow_zone_ids` 仍表达租户允许的 zone 集合;落实方式为 **替代写入 detail**,而非 ∩。 |
|
||
| **无策略不禁锢** | 组织未命中策略时,`floorList` 仍为 `listByImageId` 遍历结果。 |
|
||
| ~~**交集为空必须拒绝**~~ | **废止**:不再使用 `candidate ∩ allow`;空 `floorList`/effective 走 **`76260531`**。 |
|
||
|
||
---
|
||
|
||
## 2. 总流程
|
||
|
||
### 2.1 UC-01:调用方未传 floorIds
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Caller as 调用方/BFF
|
||
participant Elevator as 电梯应用<br/>cw-elevator-application
|
||
participant Org as 组织服务<br/>ninca-common-component-organization
|
||
participant PolicyDB as 策略表<br/>tenant_visitor_floor_policy
|
||
|
||
Caller->>Elevator: POST /elevator/person/add/visitor<br/>{personId, visitorId}<br/>(不传 floorIds)
|
||
|
||
Note over Elevator: 阶段1:查被访人信息
|
||
Elevator->>Org: POST /component/person/detail<br/>{personId, businessId}
|
||
Org-->>Elevator: PersonResult<br/>{floorList, organizationIds}
|
||
|
||
Note over Elevator: 阶段2:候选楼层 = floorList
|
||
Note over Elevator: floorList 来自组织服务
|
||
|
||
Note over Elevator: 阶段3:查策略
|
||
Elevator->>PolicyDB: SELECT * FROM tenant_visitor_floor_policy<br/>WHERE org_id IN (organizationIds) AND enabled=1
|
||
PolicyDB-->>Elevator: policy 行 / 空
|
||
|
||
alt 策略存在且生效
|
||
Note over Elevator: 最终楼层 = floorList ∩ allow_zone_ids
|
||
alt 交集为空
|
||
Elevator-->>Caller: 失败 76260532<br/>(租户策略与被访人授权无交集)
|
||
else 交集非空
|
||
Note over Elevator: 继续开通流程
|
||
Elevator-->>Caller: 成功,仅开通交集内楼层
|
||
end
|
||
else 无策略或未启用
|
||
Note over Elevator: 最终楼层 = floorList(原值)
|
||
Elevator-->>Caller: 成功
|
||
end
|
||
```
|
||
|
||
### 2.2 UC-02:调用方传入 floorIds
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Caller as 调用方/BFF
|
||
participant Elevator as 电梯应用<br/>cw-elevator-application
|
||
participant Org as 组织服务<br/>ninca-common-component-organization
|
||
participant PolicyDB as 策略表<br/>tenant_visitor_floor_policy
|
||
|
||
Caller->>Elevator: POST /elevator/person/add/visitor<br/>{personId, visitorId, floorIds:[...]}
|
||
|
||
Note over Elevator: 阶段1:查被访人信息(仅取 organizationIds)
|
||
Elevator->>Org: POST /component/person/detail<br/>{personId, businessId}
|
||
Org-->>Elevator: PersonResult<br/>{organizationIds}
|
||
|
||
Note over Elevator: 阶段2:候选楼层 = 调用方传入的 floorIds
|
||
|
||
Note over Elevator: 阶段3:查策略(ALWAYS)
|
||
Elevator->>PolicyDB: SELECT * FROM tenant_visitor_floor_policy<br/>WHERE org_id IN (organizationIds) AND enabled=1
|
||
PolicyDB-->>Elevator: policy 行 / 空
|
||
|
||
alt 策略存在且生效
|
||
Note over Elevator: 最终楼层 = callerFloorIds ∩ allow_zone_ids
|
||
alt 交集为空
|
||
Elevator-->>Caller: 失败 76260532<br/>(请求楼层不在策略允许范围内)
|
||
else 交集非空
|
||
Elevator-->>Caller: 成功,仅开通交集内楼层
|
||
end
|
||
else 无策略或未启用
|
||
Note over Elevator: 最终楼层 = callerFloorIds(原值)
|
||
Elevator-->>Caller: 成功
|
||
end
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 控制流伪代码
|
||
|
||
```
|
||
addVisitor(param, context):
|
||
// === 阶段1:查被访人组织信息(ALWAYS)===
|
||
detailResult = personService.detail(personId, businessId)
|
||
if failed: return detailResult.error
|
||
person = detailResult.data
|
||
|
||
// === 阶段2:确定候选楼层 ===
|
||
if param.floorIds 非空: ← UC-02
|
||
candidate = param.floorIds
|
||
else: ← UC-01
|
||
candidate = person.floorList
|
||
if candidate 为空: return 76260531
|
||
|
||
// === 阶段3:ALWAYS 查策略 ===
|
||
policy = findEnabledPolicy(person.organizationIds)
|
||
if policy != null:
|
||
effective = intersect(candidate, policy.allow_zone_ids)
|
||
if effective 为空: return 76260532
|
||
else:
|
||
effective = candidate
|
||
|
||
// === 阶段4:空集校验 ===
|
||
if effective 为空: return 76260531
|
||
param.floorIds = effective
|
||
|
||
// === 阶段5:开通流程(不变)===
|
||
zoneService.page → image_rule_ref → batchBind → ...
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 场景对照矩阵
|
||
|
||
| 场景 | 调用方 floorIds | 策略状态 | 候选楼层 | 最终结果 |
|
||
|------|----------------|---------|---------|---------|
|
||
| UC-01 无策略 | 空 | 无策略行 | `floorList` | `floorList` ✅ |
|
||
| UC-01 + 策略通过 | 空 | 有且生效 | `floorList` | `floorList ∩ allow` ✅ |
|
||
| UC-01 + 策略无交集 | 空 | allow 与 floorList 无交集 | `floorList` | 失败 76260532 ✅ |
|
||
| UC-01 被访人无楼层 | 空 | 任意 | `floorList`=空 | 失败 76260531 ✅ |
|
||
| UC-02 无策略 | [A,B] | 无策略行 | [A,B] | [A,B] ✅ |
|
||
| UC-02 + 策略包含 | [A,B] | allow=[A,C] | [A,B] | [A] ✅ |
|
||
| UC-02 + 策略不包含 | [A,B] | allow=[C,D] | [A,B] | 失败 76260532 ✅ |
|
||
|
||
### 与当前实现的差异
|
||
|
||
| 场景 | 当前实现 | 重设计后 |
|
||
|------|---------|---------|
|
||
| UC-02 + 策略存在 | 绕过策略,按请求楼层开通 ❌ | 策略求交 ✅ |
|
||
| UC-02 + 策略不包含请求楼层 | 成功开通(本应拒绝)❌ | 失败 76260532 ✅ |
|
||
|
||
---
|
||
|
||
## 5. 错误码
|
||
|
||
| 错误码 | 触发条件 | 说明 |
|
||
|--------|---------|------|
|
||
| 76260531 | 候选楼层为空 | 被访人 `floorList` 为空,或有效楼层为空 |
|
||
| 76260532 | `candidate ∩ allow` 无交集 | 策略约束了可访楼层,但候选楼层全部不在允许范围内 |
|
||
| 76260533 | 策略配置错误 | `allow_zone_ids` 包含被访人无权限的 zoneId |
|
||
|
||
---
|
||
|
||
## 6. 日志规范
|
||
|
||
| 关键路径 | 日志内容 |
|
||
|---------|---------|
|
||
| 入口 | `businessId, personId, visitorId, requestFloorSize` |
|
||
| UC-01 | `调用方未传楼层,取被访人默认楼层 floorList=xxx` |
|
||
| UC-02 | `调用方已指定楼层,候选楼层=candidate` |
|
||
| 策略查询 | `查询组织 orgIds=xxx` |
|
||
| 策略命中 | `找到启用策略 policyId=xxx allow=xxx` |
|
||
| 策略未命中 | `未找到启用策略,使用候选楼层原值` |
|
||
| 求交成功 | `策略生效,最终楼层=effective` |
|
||
| 求交为空 | `候选楼层与策略无交集,返回 76260532` |
|
||
| 空楼层 | `无可用楼层,返回 76260531` |
|
||
|
||
---
|
||
|
||
## 7. 实施范围
|
||
|
||
| 变更点 | 影响 | 风险 |
|
||
|--------|------|------|
|
||
| UC-02 增加 `personService.detail()` 调用 | 多一次 RPC(数百微秒) | 低 |
|
||
| UC-02 增加策略求交逻辑 | 对传入楼层做过滤 | 中——调用方可能不符合预期 |
|
||
| 删除 `callerProvidedFloors` 分支 | 简化代码结构 | 低 |
|
||
|
||
> **兼容性提醒**:UC-02 行为改变意味着:之前能开通的请求(传入策略允许范围外的楼层)现在会失败。需通知集成方。
|