# 租户访客默认楼层(数据库配置阶段)— 变更记录 > **用途**:记录本仓库内已落地的代码与脚本变更,便于评审、发版说明与运维回溯。 > **设计依据**:[租户访客默认楼层-数据库配置阶段技术设计](租户访客默认楼层-数据库配置阶段技术设计.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` | --- *本文档随该功能后续提交持续更新;合并主干后建议在提交说明中引用本路径。*