diff --git a/docs/business/租户访客默认楼层-数据库配置阶段技术设计.md b/docs/business/租户访客默认楼层-数据库配置阶段技术设计.md index ae0b206c..3cac8e61 100644 --- a/docs/business/租户访客默认楼层-数据库配置阶段技术设计.md +++ b/docs/business/租户访客默认楼层-数据库配置阶段技术设计.md @@ -283,6 +283,7 @@ VALUES | 项目 | 内容 | |------|------| | 路径 | `docs/business/租户访客默认楼层-数据库配置阶段技术设计.md` | +| **变更记录** | [租户访客默认楼层-数据库阶段变更记录](租户访客默认楼层-数据库阶段变更记录.md)(发版/评审用) | | 修订触发 | `add/visitor` 契约变更;策略表字段变更;决定 UC-02 是否参与求交 | | 关联 PR | 实现类、`Mapper.xml`、DDL 脚本与错误码资源文件 | diff --git a/docs/business/租户访客默认楼层-数据库阶段变更记录.md b/docs/business/租户访客默认楼层-数据库阶段变更记录.md new file mode 100644 index 00000000..e0348022 --- /dev/null +++ b/docs/business/租户访客默认楼层-数据库阶段变更记录.md @@ -0,0 +1,133 @@ +# 租户访客默认楼层(数据库配置阶段)— 变更记录 + +> **用途**:记录本仓库内已落地的代码与脚本变更,便于评审、发版说明与运维回溯。 +> **设计依据**:[租户访客默认楼层-数据库配置阶段技术设计](租户访客默认楼层-数据库配置阶段技术设计.md) +> **产品依据**:[租户访客默认楼层技术产品方案](租户访客默认楼层技术产品方案.md) +> **流程依据**:[访客注册与派梯楼层业务流程走查](访客注册与派梯楼层业务流程走查.md) + +--- + +## 1. 版本信息 + +| 项目 | 内容 | +|------|------| +| **Git 分支** | `feature/tenant-visitor-floor-policy-db` | +| **主提交** | `25cff4d` — `feat(elevator): 租户访客默认楼层策略表与 UC-01 求交` | +| **涉及工程** | `maven-cw-elevator-application`(`cw-elevator-application-data`、`cw-elevator-application-service`) | +| **对外接口** | 无新增 HTTP;行为变更集中在 **`POST /elevator/person/add/visitor`**(`PersonRuleServiceImpl.addVisitor`) | + +--- + +## 2. 变更摘要 + +1. **新增数据库表** `tenant_visitor_floor_policy`:按租户(`business_id`)配置访客允许 `zoneId` 列表(JSON),本阶段仅支持 **`INTERSECT_ALLOWLIST`** 与 **租户级**(`building_id` 为空)策略行。 +2. **电梯服务 `addVisitor`**:当请求 **未携带非空 `floorIds`**(走查 **UC-01**)时,在取得组织侧被访人 **`floorList`** 后,若存在启用策略且 `allow_zone_ids` 解析为非空数组,则 **`effective = floorList ∩ allow`**(**保持 `floorList` 原有顺序**);无交集则失败;无表/停用/允许列表为空或 JSON 无效则 **与现网一致** 使用全量 `floorList`。 +3. **当请求已携带非空 `floorIds`**(**UC-02**):**不读策略表**、不对入参求交,行为与变更前一致。 +4. **健壮性**:组织 `detail` 失败透传错误码;`PersonResult` / `floorList` 为空返回 **`76260531`**;策略求交为空返回 **`76260532`**;最终 `floorIds` 仍为空时返回 **`76260531`**;`addVisitor` 中 **`ServiceException` 不再被泛化 `catch` 吞掉**,避免一律映射为 `76260530`。 + +--- + +## 3. 文件清单 + +### 3.1 新增 + +| 路径 | 说明 | +|------|------| +| `docs/sql/tenant_visitor_floor_policy.sql` | 建表 DDL(`CREATE TABLE IF NOT EXISTS`)及注释示例 | +| `maven-cw-elevator-application/cw-elevator-application-data/.../person/dto/TenantVisitorFloorPolicyDto.java` | 策略行 DTO | +| `maven-cw-elevator-application/cw-elevator-application-data/.../person/mapper/TenantVisitorFloorPolicyMapper.java` | MyBatis Mapper 接口 | +| `maven-cw-elevator-application/cw-elevator-application-data/.../person/mapper/TenantVisitorFloorPolicyMapper.xml` | `selectEnabledTenantDefault` SQL | +| `maven-cw-elevator-application/cw-elevator-application-data/.../person/dao/TenantVisitorFloorPolicyDao.java` | DAO 接口 | +| `maven-cw-elevator-application/cw-elevator-application-data/.../person/impl/TenantVisitorFloorPolicyDaoImpl.java` | DAO 实现 | +| `docs/business/租户访客默认楼层-数据库配置阶段技术设计.md` | 技术设计(含实现分支与 DDL 路径说明) | + +### 3.2 修改 + +| 路径 | 说明 | +|------|------| +| `maven-cw-elevator-application/cw-elevator-application-service/.../person/impl/PersonRuleServiceImpl.java` | `addVisitor` 主流程;注入 `TenantVisitorFloorPolicyDao`;新增 `parseAllowZoneIds`、`intersectPreserveHostOrder` | + +--- + +## 4. 行为对照表(验收速查) + +| 场景 | `floorIds` 请求体 | 库中策略 | 期望 | +|------|-------------------|----------|------| +| UC-01 基线 | 空 / 未传 | 无行或 `enabled=0` 或 `allow_zone_ids` 空/无效 JSON | 与变更前一致:使用组织 **`floorList` 全集** | +| UC-01 + 策略 | 空 / 未传 | 有启用行且 allow 非空 | **`floorList ∩ allow`**(保序) | +| 策略无交集 | 空 / 未传 | allow 与 `floorList` 无共同元素 | **`CloudwalkResult.fail("76260532", ...)`** | +| 被访人无楼层 | 空 / 未传 | 任意 | **`76260531`**(`floorList` 空或 null) | +| 组织 detail 失败 | 空 / 未传 | 任意 | **透传** `detail` 的 code/message | +| UC-02 | **非空** `floorIds` | 任意 | **不读表**,按请求列表后续处理(与变更前一致) | + +--- + +## 5. 数据库与配置 + +### 5.1 执行顺序 + +1. 在电梯应用(或与电梯同数据源)库执行 **`docs/sql/tenant_visitor_floor_policy.sql`**。 +2. 对目标租户 **`INSERT`** 策略行(`business_id`、`allow_zone_ids` JSON、`enabled=1`、`policy_type='INTERSECT_ALLOWLIST'`、`building_id` 为 **NULL**)。 +3. 发布包含本分支的 **`cw-elevator-application`** 制品。 + +### 5.2 `allow_zone_ids` 格式 + +- JSON 数组字符串,例如:`["zoneId1","zoneId2"]`。 +- 解析失败或解析结果为空:**按无有效策略处理**(不打断 UC-01,避免误配导致全租户不可用);并打 **WARN** 日志。 + +### 5.3 查询规则(与 Mapper 一致) + +- `business_id = ?` +- `enabled = 1` +- `policy_type = 'INTERSECT_ALLOWLIST'` +- `building_id IS NULL OR building_id = ''` +- `ORDER BY updated_at DESC, policy_version DESC LIMIT 1` + +**运维约定**:同一租户、租户级策略(`building_id` 为空)**仅维护一行**,避免多行时仅命中最新一条。 + +--- + +## 6. 错误码与文案(待资源文件补全) + +| 错误码 | 触发条件 | 建议中文文案(需在统一 messages 中配置) | +|--------|----------|------------------------------------------| +| `76260531` | 被访人无 `floorList`;或经处理后仍无可用楼层 | 无法为访客开通派梯:被访人无授权楼层或无可生效楼层 | +| `76260532` | 租户允许列表与被访人 `floorList` 交集为空 | 无法为访客开通派梯:租户访客楼层策略与被访人授权楼层不一致,请联系管理员 | + +若未配置文案,`getMessage` 可能回退为码或占位,**发版前请在现网 i18n 资源中登记**。 + +--- + +## 7. 日志 + +- 当发生 **策略求交且结果非空** 时,打 **INFO**:`businessId`、`personId`、`visitorId`、`policyId`、`policyVersion`、**生效楼层数量** `effectiveSize`(不落全量 zoneId,减少日志敏感面;若排障需要可临时调高或改为 DEBUG)。 + +--- + +## 8. 集成与运行依赖 + +| 项 | 说明 | +|----|------| +| **MyBatis** | 启动类需能扫描到 **`cn.cloudwalk.elevator.person.mapper`**(或与现有 `cn.cloudwalk.elevator` 下 Mapper 扫描策略一致);`Mapper.xml` 位于 `cw-elevator-application-data` 的 `src/main/java/.../mapper/*.xml`(与现有模块一致)。 | +| **表不存在** | 未执行 DDL 时访问表会抛 SQL 异常,通常落入 `76260530` 包装;**须先 DDL 再发应用**。 | +| **本地编译** | 聚合工程要求 **JDK 8** 跑 Maven(enforcer);若 `cw-elevator-application-common` 等模块因私服依赖未解析失败,与本次新增类无直接关系,需在完整依赖环境编译。 | + +--- + +## 9. 明确未包含(后续迭代) + +- 物业管理端页面、策略 CRUD REST、审计与 `policy_version` 写入登记快照。 +- 登记页 / BFF **预览接口**与电梯开通结果的 **展示同源**(见技术设计 §8)。 +- 按 **`building_id`** 的多套策略(表字段已预留,查询与产品未定前不启用)。 + +--- + +## 10. 修订历史 + +| 日期 | 修订内容 | +|------|----------| +| 2026-04-24 | 初稿:对应分支 `feature/tenant-visitor-floor-policy-db`、提交 `25cff4d` | + +--- + +*本文档随该功能后续提交持续更新;合并主干后建议在提交说明中引用本路径。*