Files
starRiverProperty/docs/testing/tenant-visitor-default-floor-isolation.md
T
反编译工作区 8b15445328 feat: add service config templates and extraction script
Former-commit-id: 1de24b7eb79676d1aba9d799a58c5a753290cf52
2026-05-01 19:38:01 +08:00

5.2 KiB
Raw Blame History

租户访客默认楼层(广发及后续租户定制)与「不影响其他公司」的边界说明

1. 目标表述

诉求 含义
定制 某租户希望:访客在 不传 floorIds 时,仅开通 接待层等默认楼层(与员工本人多层权限区分)。
不影响未定义公司 未启用该能力的租户 / 机构,行为与改造前一致:不因他人策略误伤

实现落点在本仓库:PersonRuleServiceImpl#addVisitor + 表 tenant_visitor_floor_policy(详见 visitor-registration-business-flow.md)。


2. 当前实现下的真实隔离粒度(必读)

2.1 策略生效键:business_id(机构/租户 ID

  • DAOTenantVisitorFloorPolicyDao#selectEnabledTenantDefault(businessId)
  • SQL(节选):WHERE business_id = ? AND enabled = 1 AND policy_type = 'INTERSECT_ALLOWLIST' AND (building_id IS NULL OR building_id = '')
  • 含义:一行策略绑定的是 Cloudwalk 上下文里的 companyId(即 Header businessid,不是单个「公司名称字符串」,也不是单个部门 org_id

2.2 「未定义」租户的行为 — 不受影响

flowchart LR
  subgraph T1["租户 A:库中无策略行"]
    A1[addVisitor floorIds 空]
    A2[detail 取 host floorList]
    A3[selectEnabledTenantDefault → null]
    A4[effectiveFloors = hostFloors 全集]
    A1 --> A2 --> A3 --> A4
  end
  subgraph T2["租户 B:有启用策略"]
    B1[detail 取 host floorList]
    B2[与 allow_zone_ids 求交]
    B1 --> B2
  end
  • 无策略行enabled≠1:代码分支 不执行求交,访客楼层等同于 被访人 floorList(在「不传 floorIds」前提下)。
    其他未配置策略的 business_id:逻辑 不变,满足「未定义则不收紧」。

2.3 「广发定制」与同一 business_id 下其他部门 — 当前同属租户级策略

  • 星河湾中心广发基金等业务共用一个 business_id(现场组织库 cw_is_organization.BUSINESS_ID 相同),则 库中一条租户默认策略会对该 ID 下全部主体生效无法仅靠配置表做到「只收紧广发公司、不收紧同租户下其他公司」。
  • 产品级隔离选项(需实施选型,超出当前表结构默认能力)
    • 拆租户:广发使用 独立 business_id(独立机构树),策略只插入该行;或
    • 演进能力:使用/扩展 building_id 维度的策略行(表已预留列,需扩展 Mapper 查询与产品规则);或
    • 调用方传 floorIds:由 BFF 按公司算出楼层,电梯不再依赖默认求交。

3. 业务流程图(有 / 无策略)

flowchart TD
  Start([POST /elevator/person/add/visitor]) --> Empty{floorIds 空?}
  Empty -- 否 --> UseIn[使用传入 floorIds]
  Empty -- 是 --> Det[PersonService.detail 被访人 personId]
  Det --> HF{floorList 非空?}
  HF -- 否 --> E31[76260531]
  HF -- 是 --> Pol{存在启用租户默认策略且 allow 非空?}
  Pol -- 否 --> UseIn2[effectiveFloors = floorList]
  Pol -- 是 --> Xsect[floorList ∩ allow_zone_ids]
  Xsect --> Xe{交集非空?}
  Xe -- 否 --> E32[76260532]
  Xe -- 是 --> UseIn3[effectiveFloors = 交集]
  UseIn --> Zone[首层→楼栋→imageStoreId]
  UseIn2 --> Zone
  UseIn3 --> Zone
  Zone --> IRR[写 image_rule_ref personId=visitorId]
  IRR --> Bind[图库 batchBind visitorId]
  Bind --> OK([成功])

4. 时序图(不传 floorIds + 有策略)

sequenceDiagram
  participant Caller as 调用方/BFF
  participant API as AcsPersonController
  participant PR as PersonRuleServiceImpl
  participant PS as PersonService 组件
  participant Pol as TenantVisitorFloorPolicyDao
  participant Ir as ImageRuleRefDao
  participant IS as ImageStorePersonService

  Caller->>API: visitorId, personId(被访人), floorIds=[]
  API->>PR: addVisitor
  PR->>PS: detail(personId, businessId)
  PS-->>PR: PersonResult.floorList
  PR->>Pol: selectEnabledTenantDefault(businessId)
  Pol-->>PR: allow_zone_ids JSON
  Note over PR: effectiveFloors = intersect(floorList, allow)
  PR->>Ir: insertList 每层默认规则 visitorId
  PR->>IS: batchBind(visitorId, 访期)
  IS-->>PR: ok
  PR-->>API: success

5. 与测试矩阵的关系

  • 自动化快照business_id 拉策略与人员;若需验证「无策略租户」,使用 第二 business_id 套件或 空策略库
  • 每部门 10 名员工:验证「同一策略下不同被访人 floorList」与求交结果多样性;等价于「按公司隔离策略」。

6. 文档索引

  • 租户 / 组织 / 人员 / 访客 ER、表关系与用例:docs/architecture/租户组织人员访客-数据模型与用例.md
  • 楼层与 API 字段:docs/testing/visitor-registration-business-flow.md
  • 服务层逐步说明:cw-elevator-application-service/docs/08-visitor-registration-and-elevator-auth.md
  • 测试方案:docs/testing/visitor-registration-floor-validation.md