mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 08:20:31 +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.
324 lines
18 KiB
Markdown
324 lines
18 KiB
Markdown
# 访客注册与派梯楼层:完整业务流程走查
|
||
|
||
> **范围说明**:本文基于本仓库内 Maven 工程源码(`maven-cw-elevator-application`、`maven-intelligent-cwoscomponent` 等)梳理**接口调用链、业务逻辑与用例**。
|
||
> **访客业务后台**(如「轻舟 / intelligent/three」访客注册、审批流)若不在本仓库,文中以「第三方业务系统」统称,并标明本仓库可见的**被调接口**与**出站 Feign/HTTP**。
|
||
|
||
---
|
||
|
||
## 1. 术语与角色
|
||
|
||
| 术语 | 含义 |
|
||
|------|------|
|
||
| 第三方业务系统 | 访客注册、邀约、审批等上层应用;可经 intelligent 组件或直接调电梯服务 |
|
||
| 组织人员服务 | `ninca-common-component-organization`(可配置),提供人员详情、图库人员绑定等 |
|
||
| 空间/区域服务 | `ninca-common` 的 `/sysetting/zone`,提供楼栋-楼层树、分区 page |
|
||
| 电梯应用 | `cw-elevator-application`,维护派梯规则 `image_rule_ref`、设备图库绑定等 |
|
||
| 被访人 | `personId`,组织侧人员主键 |
|
||
| 访客 | `visitorId`,组织侧访客人员主键 |
|
||
| 楼层 | 以 **分区/空间 ID**(`zoneId` / `floorId`)表示,与 `PersonResult.floorList` 元素一致 |
|
||
|
||
---
|
||
|
||
## 2. 业务总览(从「默认楼层」到「指定楼层」)
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph third [第三方业务系统]
|
||
A[访客注册/邀约完成]
|
||
B{是否已知具体楼层 zoneId 列表?}
|
||
C[调组织服务拉人员详情]
|
||
D[组装 floorIds 显式列表]
|
||
end
|
||
|
||
subgraph org [组织人员服务 ninca-common-component-organization]
|
||
P["POST /component/person/detail"]
|
||
I["POST /component/imagestore/person/batchBind 等"]
|
||
end
|
||
|
||
subgraph intel [intelligent-cwoscomponent-rest 可选]
|
||
E["ElevatorPersonService.addVisitor → Feign"]
|
||
end
|
||
|
||
subgraph elev [电梯 cw-elevator-application]
|
||
F["POST /elevator/person/add/visitor"]
|
||
G["PersonRuleServiceImpl.addVisitor"]
|
||
end
|
||
|
||
A --> B
|
||
B -->|否 需默认| C
|
||
C --> P
|
||
P -->|PersonResult.floorList| third
|
||
B -->|是 或 已补全| D
|
||
D --> E
|
||
C --> E
|
||
E --> F
|
||
F --> G
|
||
G -->|缺 floorIds 时内部再调 P 取 floorList| P
|
||
G --> I
|
||
```
|
||
|
||
**要点**:
|
||
|
||
- 「**默认有哪些楼层**」在本仓库电梯侧的实现是:**未传 `floorIds` 时**,调用 **`PersonService.detail`**(Feign → **`POST /component/person/detail`**),取 **`PersonResult.getFloorList()`**,**不是** `PersonResult.defaultFloor` 单字段。
|
||
- 「**第三方设定具体楼层**」:**在请求体中携带非空的 `floorIds`** 调用 **`POST /elevator/person/add/visitor`**(或经 `ElevatorPersonService` 转发),电梯侧**不再**调人员详情补楼层。
|
||
|
||
---
|
||
|
||
## 3. 流程 A:第三方如何获知「默认」楼层(可走的接口)
|
||
|
||
第三方若**自行**在注册前展示「被访人默认可达楼层」,应在**组织侧**完成数据拉取;本仓库可见的**权威数据源**为人员详情返回的 **`floorList`**(及可能同时返回的 `defaultFloor`、`floorInfoList` 等,但电梯访客派梯**仅用** `floorList` 补全逻辑)。
|
||
|
||
### 3.1 推荐:人员详情(与电梯补全逻辑一致)
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| 调用方 | 任意有权限的服务;intelligent 中为 `RestPersonServiceImpl` → `PersonFeignClient` |
|
||
| 服务名配置 | `${feign.component-organization.name:ninca-common-component-organization}` |
|
||
| HTTP | **`POST /component/person/detail`** |
|
||
| 请求体 | `PersonDetailParam`:`id` = 被访人 `personId`,`businessId` = 机构 |
|
||
| 响应 | `CloudwalkResult<PersonResult>`,关注 **`floorList`**(`List<String>` 楼层/分区 ID) |
|
||
|
||
代码位置(Feign 声明):
|
||
|
||
```19:32:maven-intelligent-cwoscomponent/intelligent-cwoscomponent-rest/src/main/java/cn/cloudwalk/rest/cwoscomponent/intelligent/person/feign/PersonFeignClient.java
|
||
@FeignClient(name = "${feign.component-organization.name:ninca-common-component-organization}",
|
||
path = "/component/person", fallback = PersonFeignClientFallback.class)
|
||
public interface PersonFeignClient {
|
||
...
|
||
@RequestMapping(value = {"/detail"}, method = {RequestMethod.POST})
|
||
CloudwalkResult<PersonResult> detail(@RequestBody PersonDetailParam paramPersonDetailParam);
|
||
```
|
||
|
||
`PersonResult` 中与楼层相关的字段(电梯 `addVisitor` **补全时只用 `floorList`**):
|
||
|
||
```27:34:maven-intelligent-cwoscomponent/intelligent-cwoscomponent-interface/src/main/java/cn/cloudwalk/client/cwoscomponent/intelligent/person/result/PersonResult.java
|
||
private String defaultFloor;
|
||
private String chooseFloor;
|
||
private List<String> floorList;
|
||
private List<AcsPassRuleImageResultDto> floorInfoList;
|
||
...
|
||
private String defaultChooseFloor;
|
||
```
|
||
|
||
### 3.2 辅助:空间树 / 楼层分页(电梯网关或管理端常用)
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| Feign | `ZoneFeignClient` → `${feign.ninca-common.name:ninca-common}` |
|
||
| HTTP | **`POST /sysetting/zone/tree`**、**`POST /sysetting/zone/page`** |
|
||
| 用途 | 按楼栋展示树、按条件查分区;**不替代**人员已授权楼层列表 |
|
||
|
||
```16:23:maven-cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/zone/client/ZoneFeignClient.java
|
||
@FeignClient(name = "${feign.ninca-common.name:ninca-common}", path = "/sysetting/zone",
|
||
fallback = ZoneFeignClientFallback.class)
|
||
public interface ZoneFeignClient {
|
||
@RequestMapping(value = {"/tree"}, method = {RequestMethod.POST})
|
||
...
|
||
@RequestMapping(value = {"/page"}, method = {RequestMethod.POST})
|
||
CloudwalkResult<CloudwalkPageAble<ZoneResult>> page(ZoneQueryParam paramZoneQueryParam) throws ServiceException;
|
||
}
|
||
```
|
||
|
||
### 3.3 辅助:通行规则-楼层列表(管理派梯规则维度)
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| Controller | `AcsPassRuleController` |
|
||
| HTTP | **`POST /elevator/passRule/floor`** 等 |
|
||
| 用途 | 规则/图库与楼层关系维护与查询;与「人员 floorList」不同维度 |
|
||
|
||
```45:55:maven-cw-elevator-application/cw-elevator-application-web/src/main/java/cn/cloudwalk/elevator/passrule/controller/AcsPassRuleController.java
|
||
@RequestMapping({"/floor"})
|
||
public CloudwalkResult<CloudwalkPageAble<AcsPassRuleFloorResult>>
|
||
listFloor(@RequestBody AcsPassRuleFloorForm form) {
|
||
...
|
||
return this.imageRuleRefService.listFloor(param, getCloudwalkContext());
|
||
```
|
||
|
||
### 3.4 访客记录查询(识别访客身份,非楼层来源)
|
||
|
||
电梯乘梯记录中通过 **RestTemplate** 调 **`intelligent/three/visitor/record/query`**,用于判断是否访客及被访人,**不参与** `addVisitor` 楼层列表计算:
|
||
|
||
```262:274:maven-cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/record/impl/AcsElevatorRecordServiceImpl.java
|
||
URI uri =
|
||
combineAuthClientURI("intelligent/three/visitor/record/query", (MultiValueMap<String, String>)null);
|
||
VisitorRecordQueryParam form = new VisitorRecordQueryParam();
|
||
form.setVisitorId(addDTO.getRecognitionFaceId());
|
||
...
|
||
```
|
||
|
||
另有 Feign **`VisitorFeignClient`**:`ninca-crk-std` 的 **`/intelligent/visitor/record/query`**,与上为不同网关路径,同属访客记录查询能力。
|
||
|
||
---
|
||
|
||
## 4. 流程 B:第三方设定「具体楼层」并开通访客派梯
|
||
|
||
### 4.1 对外 HTTP(电梯应用)
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| Method / Path | **`POST /elevator/person/add/visitor`** |
|
||
| Controller | `AcsPersonController#addVisitor` |
|
||
| Body | `AcsPersonAddVisitorForm` → `AcsPersonAddVisitorParam` |
|
||
|
||
```53:62:maven-cw-elevator-application/cw-elevator-application-web/src/main/java/cn/cloudwalk/elevator/person/controller/AcsPersonController.java
|
||
@RequestMapping({"/add/visitor"})
|
||
public CloudwalkResult<Boolean> addVisitor(@RequestBody AcsPersonAddVisitorForm form) {
|
||
AcsPersonAddVisitorParam param =
|
||
(AcsPersonAddVisitorParam)BeanCopyUtils.copyProperties(form, AcsPersonAddVisitorParam.class);
|
||
try {
|
||
return this.personRuleService.addVisitor(param, getCloudwalkContext());
|
||
```
|
||
|
||
### 4.2 经 intelligent 的 Feign(业务方 SDK 式调用)
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| 接口 | `ElevatorPersonService.addVisitor` |
|
||
| 实现 | `RestElevatorPersonServiceImpl` |
|
||
| Feign | `ElevatorPersonFeignClient` |
|
||
| 目标 | `${feign.elevator.name:elevator-app}` **`POST /elevator/person/add/visitor`** |
|
||
|
||
```11:15:maven-intelligent-cwoscomponent/intelligent-cwoscomponent-rest/src/main/java/cn/cloudwalk/rest/cwoscomponent/intelligent/elevator/feign/ElevatorPersonFeignClient.java
|
||
@FeignClient(name = "${feign.elevator.name:elevator-app}", path = "/elevator/person",
|
||
fallback = ElevatorPersonFeignClientFallback.class)
|
||
public interface ElevatorPersonFeignClient {
|
||
@RequestMapping(value = {"/add/visitor"}, method = {RequestMethod.POST})
|
||
CloudwalkResult<Boolean> addVisitor(@RequestBody AcsPersonAddVisitorParam paramAcsPersonAddVisitorParam);
|
||
```
|
||
|
||
### 4.3 请求字段语义(用例输入)
|
||
|
||
| 字段 | 必填性 | 说明 |
|
||
|------|--------|------|
|
||
| `visitorId` | 是 | 访客在组织侧人员 ID |
|
||
| `personId` | 是 | 被访人 ID;**补全楼层时**用于 `detail` |
|
||
| `begVisitorTime` / `endVisitorTime` | 视图库接口 | 传入图库绑定有效期 |
|
||
| `floorIds` | 否 | **非空**:第三方显式指定可派梯楼层;**空/缺省**:由电梯侧按被访人 **`floorList`** 补全 |
|
||
|
||
---
|
||
|
||
## 5. 电梯侧核心业务逻辑:`PersonRuleServiceImpl.addVisitor`
|
||
|
||
实现类:`PersonRuleServiceImpl`(`maven-cw-elevator-application/.../PersonRuleServiceImpl.java`)。
|
||
|
||
### 5.1 步骤分解
|
||
|
||
| 步骤 | 逻辑 | 外部依赖 |
|
||
|------|------|----------|
|
||
| 1 | 若 `floorIds` 为空 → `PersonDetailParam(personId, businessId)` → **`personService.detail`** | Feign → **`POST /component/person/detail`**,取 **`getFloorList()`** 赋给 `floorIds` |
|
||
| 2 | 用 **`floorIds.get(0)`** 构造 `ZoneQueryParam`,**`zoneService.page`** 查分区页,取首条 `ZoneResult` 得 **`parentId`(楼栋)** | Feign → **`POST /sysetting/zone/page`** |
|
||
| 3 | **`deviceImageStoreDao.getByBuildingId(parentId)`** 得图库 `imageStoreId` | 本地 DAO |
|
||
| 4 | 对 **每个 `floorId`**:`imageRuleRefDao.getDefaultByZoneId(floorId)` 取默认通行规则,组装 **`ImageRuleRefAddDto`**(访客 `visitorId` 挂父规则) | 本地 DAO |
|
||
| 5 | **`imageRuleRefDao.insertList`** 批量写入派梯规则引用 | 本地 DAO |
|
||
| 6 | 组装 **`ImageStorePersonBindParam`**(图库、访客 ID、有效期),**`imageStorePersonService.batchBind`** | Feign → **`POST /component/imagestore/person/batchBind`** |
|
||
| 7 | **`imageStorePersonService.updateGroupPersonRef`** 更新组与人员引用 | Feign → **`POST /component/imagestore/person/updateGroupPersonRef`** |
|
||
|
||
关键代码(补全楼层 + 循环写规则 + 绑图库):
|
||
|
||
```170:223:maven-cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/person/impl/PersonRuleServiceImpl.java
|
||
if (CollectionUtils.isEmpty(param.getFloorIds())) {
|
||
PersonDetailParam detailParam = new PersonDetailParam();
|
||
detailParam.setId(param.getPersonId());
|
||
detailParam.setBusinessId(context.getCompany().getCompanyId());
|
||
CloudwalkResult<PersonResult> detail = this.personService.detail(detailParam, context);
|
||
param.setFloorIds(((PersonResult)detail.getData()).getFloorList());
|
||
}
|
||
ZoneQueryParam zoneQueryParam = new ZoneQueryParam();
|
||
zoneQueryParam.setId(param.getFloorIds().get(0));
|
||
...
|
||
for (String floorId : param.getFloorIds()) {
|
||
ImageRuleRefResultDto defaultRule = this.imageRuleRefDao.getDefaultByZoneId(floorId);
|
||
...
|
||
addDto.setPersonId(param.getVisitorId());
|
||
...
|
||
}
|
||
...
|
||
CloudwalkResult<ImgStoreBatchBindPersonResult> bindResult =
|
||
this.imageStorePersonService.batchBind(imageStorePersonBindParam, context);
|
||
...
|
||
this.imageStorePersonService.updateGroupPersonRef(refParam, context);
|
||
```
|
||
|
||
图库 Feign(与上表一致):
|
||
|
||
```19:41:maven-intelligent-cwoscomponent/intelligent-cwoscomponent-rest/src/main/java/cn/cloudwalk/rest/cwoscomponent/intelligent/imagestore/feign/ImageStorePersonFeignClient.java
|
||
@FeignClient(name = "${feign.component-organization.name:ninca-common-component-organization}",
|
||
path = "/component/imagestore/person", fallback = ImageStorePersonFeignClientFallback.class)
|
||
public interface ImageStorePersonFeignClient {
|
||
...
|
||
@RequestMapping(value = {"/batchBind"}, method = {RequestMethod.POST})
|
||
CloudwalkResult<ImgStoreBatchBindPersonResult>
|
||
batchBind(@RequestBody ImageStorePersonBindParam paramImageStorePersonBindParam);
|
||
@RequestMapping(value = {"/updateGroupPersonRef"}, method = {RequestMethod.POST})
|
||
CloudwalkResult<Boolean>
|
||
updateGroupPersonRef(@RequestBody UpdateGroupPersonRefParam paramUpdateGroupPersonRefParam);
|
||
```
|
||
|
||
### 5.2 与「内部员工」派梯开通的对比(非访客)
|
||
|
||
**`POST /elevator/person/add`** → `PersonRuleServiceImpl.add`:按**单个** `zoneId`(楼层)与 `parentId`(楼栋)给多名 **`personIds`** 写规则并绑图库;**不**调人员 `detail` 取 `floorList`。用于从已有人员批量加通行权限的另一条业务线。
|
||
|
||
```79:136:maven-cw-elevator-application/cw-elevator-application-service/src/main/java/cn/cloudwalk/elevator/person/impl/PersonRuleServiceImpl.java
|
||
public CloudwalkResult<Boolean> add(AcsPersonAddParam param, CloudwalkCallContext context) throws ServiceException {
|
||
...
|
||
ImageRuleRefResultDto defaultRule = this.imageRuleRefDao.getDefaultByZoneId(param.getZoneId());
|
||
...
|
||
for (String personId : param.getPersonIds()) {
|
||
...
|
||
addDto.setZoneId(param.getZoneId());
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 接口调用流转汇总表
|
||
|
||
| 序号 | 调用方向 | 协议与路径 | 典型触发 |
|
||
|------|----------|------------|----------|
|
||
| 1 | 第三方 / intelligent → 电梯 | `POST /elevator/person/add/visitor` | 访客开通派梯 |
|
||
| 2 | 电梯 → 组织 | `POST /component/person/detail` | `floorIds` 为空时补全 |
|
||
| 3 | 电梯 → 空间 | `POST /sysetting/zone/page` | 取楼层所属楼栋 |
|
||
| 4 | 电梯 → 组织 | `POST /component/imagestore/person/batchBind` | 访客绑图库 |
|
||
| 5 | 电梯 → 组织 | `POST /component/imagestore/person/updateGroupPersonRef` | 更新组人关系 |
|
||
| 6 | 第三方自行(可选) | `POST /component/person/detail` | 注册前展示默认可达楼层 |
|
||
| 7 | 管理端(可选) | `POST /elevator/passRule/floor` 等 | 规则/楼层维护 |
|
||
| 8 | 电梯 → 网关 HTTP | `POST intelligent/three/visitor/record/query` | 乘梯记录识别访客 |
|
||
|
||
---
|
||
|
||
## 7. 用例(UC)说明
|
||
|
||
| 用例 ID | 名称 | 前置条件 | 主流程 | 期望结果 |
|
||
|---------|------|----------|--------|----------|
|
||
| UC-01 | 访客派梯-使用被访人默认楼层列表 | 被访人 `personId` 在组织侧 `detail` 返回**非空** `floorList`;访客已注册 | 调 `add/visitor` 且 **不传 `floorIds`** | 电梯取 `floorList` 为访客写入各层默认规则并绑图库 |
|
||
| UC-02 | 访客派梯-第三方指定楼层 | `floorIds` 为合法 zoneId 列表 | 调 `add/visitor` 且 **传入 `floorIds`** | **不再**调 `person/detail` 补楼层;按列表写规则 |
|
||
| UC-03 | 注册前展示「可访楼层」 | 需与被访人授权一致 | 第三方先调 **`/component/person/detail`**,展示 `floorList`(或产品定义的 `defaultFloor` 映射) | UI 与电梯补全逻辑对齐(若仅用 `defaultFloor` 需与产品确认是否与 `floorList` 一致) |
|
||
| UC-04 | `floorList` 为空 | 被访人无派梯楼层 | `add/visitor` 不传 `floorIds` | `floorIds` 仍为空 → 后续 `get(0)` 等**可能异常**;第三方应校验或传显式楼层 |
|
||
| UC-05 | 内部人员加单层派梯 | 已知 `zoneId`、楼栋 `parentId` | `POST /elevator/person/add` | 单层规则 + 图库绑定 |
|
||
| UC-06 | 乘梯记录标记访客 | 识别到人脸 | 记录服务调 **`visitor/record/query`** | 回填 `isVisitor`、被访人 |
|
||
|
||
**扩展(租户访客默认楼层)**:若需「在 UC-01 不传 `floorIds` 的前提下,按租户策略收敛访客楼层(如默认仅开放某接待层)」的产品与技术设计,以及**从第三方登记页初始化数据项、接口编排到 `add/visitor` 的端到端闭环**,见 [租户访客默认楼层技术产品方案](租户访客默认楼层技术产品方案.md)(文中 **§2**)。
|
||
|
||
---
|
||
|
||
## 8. 风险与待确认项(走查结论)
|
||
|
||
1. **`PersonResult.defaultFloor` 与 `floorList`**:电梯 `addVisitor` **仅使用 `floorList`**。若产品「默认访问楼层」对应 `defaultFloor` 标量,需核对组织服务是否在 `detail` 中把二者对齐,否则存在**语义偏差**。
|
||
2. **`floorIds.get(0)`**:补全后若列表为空,会在取首元素时失败;第三方或组织数据需保证一致性。
|
||
3. **`cwos-sdk-event` 等**与本文无关的依赖问题不影响本业务链结论。
|
||
4. **访客注册主流程**(表单、审批、写组织人员表)若在三方工程,需在对应仓库继续搜 **`ElevatorPersonService`**、**`addVisitor`**、**`/elevator/person/add/visitor`** 的引用以闭合「从注册到派梯」的端到端文档。
|
||
|
||
---
|
||
|
||
## 9. 文档版本信息
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| 输出路径 | `docs/business/访客注册与派梯楼层业务流程走查.md` |
|
||
| 依据代码根目录 | `maven-cw-elevator-application`、`maven-intelligent-cwoscomponent` |
|
||
| 说明 | 外部服务行为以接口契约为准,组织服务内部如何组装 `floorList` 需在 **ninca-common-component-organization** 源码中二次走查 |
|
||
|
||
---
|
||
|
||
*本文档由代码走查自动生成梳理,若接口路径随部署配置变化,请以运行环境 `application*.yml` 中 `feign.*` 为准。*
|