# 广发基金 28F 硬编码方案 — 组件/模块/位置细化设计 **日期**: 2026-05-09 **分支**: `feature/guangfa-28f-hardcoded` **状态**: 方案细化完成,待实施 --- ## 1. 涉及组件与模块总览 ``` source/backend/ ├── ninca-common-component-organization/ ★ 唯一变更组件 │ ├── cwos-component-organization-service/ ★ 代码变更 │ │ └── src/main/java/cn/cloudwalk/service/organization/service/ │ │ └── ImgPersonServiceImpl.java ★ 唯一变更 Java 文件 │ │ │ ├── cwos-component-organization-starter/ ★ 配置变更 │ │ └── deploy/run-verify/ │ │ └── application.properties ★ 唯一变更配置文件 │ │ │ └── (其余模块不变: data, interface, web) │ ├── cw-elevator-application/ ☆ 仅增强日志 │ └── cw-elevator-application-service/ │ └── .../impl/PersonRuleServiceImpl.java ☆ +2 行日志 │ └── intelligent-cwoscomponent/ 不变 (仅 Feign 接口定义) ``` --- ## 2. 变更点详细定位 ### 2.1 模块: `cwos-component-organization-service` **文件**: `backend/ninca-common-component-organization/cwos-component-organization-service/src/main/java/cn/cloudwalk/service/organization/service/ImgPersonServiceImpl.java` **包**: `cn.cloudwalk.service.organization.service` **类**: `ImgPersonServiceImpl` (1414 行) #### 位置 A — 依赖注入区 (第 157-158 行后,新增 2 行) **原代码**: ```java 157: @Value("${xhwSixFloorId}") 158: private String xhwSixFloorId; 159: 160: private static final String imageBase64 = ``` **改为**: ```java 157: @Value("${xhwSixFloorId}") 158: private String xhwSixFloorId; 159: 160: @Value("${gfOrgId}") 161: private String gfOrgId; 162: 163: @Value("${gfDefaultFloorId}") 164: private String gfDefaultFloorId; 165: 166: private static final String imageBase64 = ``` #### 位置 B — `listByPage()` 访客列表分支 (第 354-370 行,插入 else-if) **当前代码** (精确): ```java 354: if (imgStorePersonResult.getOrganizationIds().contains(this.xhwId)) { 355: imgStorePersonResult.setDefaultChooseFloor(this.xhwDefaultFloorId); 356: List floorInfoList = new ArrayList<>(); 357: AcsPassRuleImageResultDto resultDto = new AcsPassRuleImageResultDto(); 358: resultDto.setZoneId(this.xhwDefaultFloorId); 359: resultDto.setZoneName("40F"); 360: floorInfoList.add(resultDto); 361: imgStorePersonResult.setFloorInfoList(floorInfoList); 362: } else { 363: imgStorePersonResult.setDefaultChooseFloor(this.xhwSixFloorId); 364: List floorInfoList = new ArrayList<>(); 365: AcsPassRuleImageResultDto resultDto = new AcsPassRuleImageResultDto(); 366: resultDto.setZoneId(this.xhwSixFloorId); 367: resultDto.setZoneName("6F"); 368: floorInfoList.add(resultDto); 369: imgStorePersonResult.setFloorInfoList(floorInfoList); 370: } ``` **改为**: ```java 354: if (imgStorePersonResult.getOrganizationIds().contains(this.xhwId)) { 355: imgStorePersonResult.setDefaultChooseFloor(this.xhwDefaultFloorId); 356: List floorInfoList = new ArrayList<>(); 357: AcsPassRuleImageResultDto resultDto = new AcsPassRuleImageResultDto(); 358: resultDto.setZoneId(this.xhwDefaultFloorId); 359: resultDto.setZoneName("40F"); 360: floorInfoList.add(resultDto); 361: imgStorePersonResult.setFloorInfoList(floorInfoList); 362: } else if (imgStorePersonResult.getOrganizationIds().contains(this.gfOrgId)) { 363: imgStorePersonResult.setDefaultChooseFloor(this.gfDefaultFloorId); 364: List floorInfoList = new ArrayList<>(); 365: AcsPassRuleImageResultDto resultDto = new AcsPassRuleImageResultDto(); 366: resultDto.setZoneId(this.gfDefaultFloorId); 367: resultDto.setZoneName("28F"); 368: floorInfoList.add(resultDto); 369: imgStorePersonResult.setFloorInfoList(floorInfoList); 370: imgStorePersonResult.setIsAcrossDay(Integer.valueOf(0)); 371: this.logger.info("[GF-28F] listByPage MATCH orgId={} in orgIds={} → default 28F", 372: this.gfOrgId, imgStorePersonResult.getOrganizationIds()); 373: } else { 374: imgStorePersonResult.setDefaultChooseFloor(this.xhwSixFloorId); 375: List floorInfoList = new ArrayList<>(); 376: AcsPassRuleImageResultDto resultDto = new AcsPassRuleImageResultDto(); 377: resultDto.setZoneId(this.xhwSixFloorId); 378: resultDto.setZoneName("6F"); 379: floorInfoList.add(resultDto); 380: imgStorePersonResult.setFloorInfoList(floorInfoList); 381: } ``` **注意**: 行号偏移 (+5 行,因上方注入区新增)。实际编辑以内容匹配为准。 #### 位置 C — `detail()` 邀约+派梯核心路径 (第 643-651 行,在策略替代块后插入) **当前代码** (精确): ```java 643: Optional> replacementFloors = 644: this.tenantVisitorFloorPolicyService.replacementZoneIdsIfPolicyActive( 645: result.getOrganizationIds()); 646: if (replacementFloors.isPresent()) { 647: floorList = new ArrayList<>(replacementFloors.get()); 648: zoneNames = buildCommaSeparatedFloorNames(businessId, floorList); 649: } 650: result.setFloorNames(zoneNames); 651: result.setFloorList(floorList); ``` **改为**: ```java 643: Optional> replacementFloors = 644: this.tenantVisitorFloorPolicyService.replacementZoneIdsIfPolicyActive( 645: result.getOrganizationIds()); 646: if (replacementFloors.isPresent()) { 647: floorList = new ArrayList<>(replacementFloors.get()); 648: zoneNames = buildCommaSeparatedFloorNames(businessId, floorList); 649: } 650: // 广发基金: 邀约 + UC-01 派梯 floorList 限制为 28F 651: if (!CollectionUtils.isEmpty(result.getOrganizationIds()) 652: && result.getOrganizationIds().contains(this.gfOrgId)) { 653: List originalFloors = new ArrayList<>(floorList); 654: floorList = Collections.singletonList(this.gfDefaultFloorId); 655: zoneNames = "28F"; 656: this.logger.info("[GF-28F] detail MATCH orgId={} in orgIds={} → floor restricted: {}→[28F]", 657: this.gfOrgId, result.getOrganizationIds(), originalFloors); 658: } else { 659: this.logger.debug("[GF-28F] detail NO-MATCH orgId={} not in orgIds={}", 660: this.gfOrgId, result.getOrganizationIds()); 661: } 662: result.setFloorNames(zoneNames); 663: result.setFloorList(floorList); ``` **注意**: `Collections.singletonList` 需要 `import java.util.Collections;` — 检查是否已存在(当前代码 `listByPage` 中使用了 `Collections.singletonList`,import 应已存在)。 #### 位置 D — `detail()` 入口日志 (在第 600 行附近,`detail()` 方法体内) 在 `detail()` 方法体的早期(如第 570-600 行区间,根据实际方法体定位),新增: ```java this.logger.info("[GF-DETAIL] entry personId={} businessId={} orgIds={}", param.getId(), businessId, result.getOrganizationIds()); ``` #### 位置 E — `detail()` listByImageId 返回日志 (在第 630 行附近) 在 `listByImageId` 调用成功后、循环组装 `floorList` 前: ```java this.logger.info("[GF-DETAIL] listByImageId returned {} zones: {}", acsPassRuleImageResultDtoList.size(), acsPassRuleImageResultDtoList.stream() .map(AcsPassRuleImageResultDto::getZoneId).collect(Collectors.toList())); ``` --- ### 2.2 模块: `cw-elevator-application-service` **文件**: `backend/cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/person/impl/PersonRuleServiceImpl.java` **包**: `cn.cloudwalk.elevator.person.impl` **类**: `PersonRuleServiceImpl` #### 位置 F — addVisitor() 日志增强 (第 187-194 行附近) **当前代码** (精确): ```java 187: boolean callerProvidedFloors = !CollectionUtils.isEmpty(param.getFloorIds()); 188: if (callerProvidedFloors) { 189: effective = param.getFloorIds(); 190: this.logger.info("UC-02:调用方显式楼层 effective={}", effective); 191: } else { 192: effective = personResult.getFloorList(); 193: if (CollectionUtils.isEmpty(effective)) { 194: this.logger.warn("UC-01:被访人 detail.floorList 为空 personId={}", param.getPersonId()); ``` **改为**: ```java 187: boolean callerProvidedFloors = !CollectionUtils.isEmpty(param.getFloorIds()); 188: if (callerProvidedFloors) { 189: effective = param.getFloorIds(); 190: this.logger.info("[GF-ADDV] UC-02 effective={}", effective); 191: } else { 192: effective = personResult.getFloorList(); 193: if (CollectionUtils.isEmpty(effective)) { 194: this.logger.warn("[GF-ADDV] UC-01 floorList empty personId={}", param.getPersonId()); ``` --- ### 2.3 模块: `cwos-component-organization-starter` (配置) **文件**: `backend/ninca-common-component-organization/cwos-component-organization-starter/deploy/run-verify/application.properties` **位置**: 第 172 行后(`xhwSixFloorId` 之后),新增 2 行: ```properties # 第 170-172 行 (现有): xhwId=21474e012cd14e26bc62771873b22562 xhwDefaultFloorId=605560547135455232 xhwSixFloorId=605560541473144832 # 第 173-174 行 (新增): gfOrgId=488b8ad049bb43408a6fbcc50bcb89ac gfDefaultFloorId=605560545117995008 ``` --- ### 2.4 数据层: 禁用原表驱动策略 **数据库**: `component-organization` (组织库) **表**: `tenant_visitor_floor_policy` ```sql UPDATE tenant_visitor_floor_policy SET enabled = 0, remark = CONCAT(remark, ' [DISABLED 2026-05-09: migrated to hardcoded 28F in ImgPersonServiceImpl]'), updated_at = UNIX_TIMESTAMP(NOW()) * 1000 WHERE id = 'gf_vstr_policy_guangfa_fund_001x' AND enabled = 1; ``` **数据库**: `cw-elevator-application` (电梯库,如果存在同步表) ```sql -- 仅当电梯库也有 tenant_visitor_floor_policy 表时执行 UPDATE tenant_visitor_floor_policy SET enabled = 0 WHERE id = 'gf_vstr_policy_guangfa_fund_001x' AND enabled = 1; ``` --- ## 3. 不变更清单 | 组件 | 模块 | 文件 | 原因 | |------|------|------|------| | intelligent-cwoscomponent | interface | PersonService.java | Feign 接口定义,不变 | | intelligent-cwoscomponent | rest | PersonFeignClient.java | HTTP 路径映射,不变 | | ninca-common-component-organization | data | TenantVisitorFloorPolicyMapper.java | 仍服务物业策略,不删 | | ninca-common-component-organization | service | TenantVisitorFloorPolicyService.java | 仍服务物业策略,不删 | | ninca-common-component-organization | web | PersonController.java | REST 入口,不变 | | ninca-common-component-organization | starter | bootstrap.properties | 启动配置,不变 | | cw-elevator-application | web | AcsPersonController.java | REST 入口,不变 | | cw-elevator-application | data | ImageRuleRefDao.java | DAO 层,不变 | | scripts/test-env | config | component-org.properties | 测试模板(最小配置),不变 | | ninca-common-component-organization | releases/ | 所有 `releases/` 下文件 | 历史发布快照,不变 | --- ## 4. 汇总 | # | 组件 | Maven 模块 | 文件 | 变更类型 | 行数 | |---|------|-----------|------|---------|------| | A | component-org | cwos-component-organization-**service** | `ImgPersonServiceImpl.java` | 注入 `@Value` ×2 | +4 | | B | component-org | cwos-component-organization-**service** | `ImgPersonServiceImpl.java` | `listByPage` else-if 分支 | +11 | | C | component-org | cwos-component-organization-**service** | `ImgPersonServiceImpl.java` | `detail()` floorList 截断 | +13 | | D | component-org | cwos-component-organization-**service** | `ImgPersonServiceImpl.java` | `detail()` 入口日志 | +2 | | E | component-org | cwos-component-organization-**service** | `ImgPersonServiceImpl.java` | listByImageId 返回日志 | +3 | | F | elevator-app | cw-elevator-application-**service** | `PersonRuleServiceImpl.java` | addVisitor 日志前缀 | ~0 (替换) | | — | component-org | cwos-component-organization-**starter** | `application.properties` | 配置 ×2 | +2 | | — | (数据库) | — | `tenant_visitor_floor_policy` | UPDATE enabled=0 | 1 行 | **总计: 2 个组件, 3 个模块, 3 个文件, ~35 行新增**