- 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.
18 KiB
访客注册与派梯楼层:完整业务流程走查
范围说明:本文基于本仓库内 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. 业务总览(从「默认楼层」到「指定楼层」)
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 声明):
@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):
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 |
| 用途 | 按楼栋展示树、按条件查分区;不替代人员已授权楼层列表 |
@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」不同维度 |
@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 楼层列表计算:
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 |
@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 |
@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 |
关键代码(补全楼层 + 循环写规则 + 绑图库):
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(与上表一致):
@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。用于从已有人员批量加通行权限的另一条业务线。
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 的端到端闭环,见 租户访客默认楼层技术产品方案(文中 §2)。
8. 风险与待确认项(走查结论)
PersonResult.defaultFloor与floorList:电梯addVisitor仅使用floorList。若产品「默认访问楼层」对应defaultFloor标量,需核对组织服务是否在detail中把二者对齐,否则存在语义偏差。floorIds.get(0):补全后若列表为空,会在取首元素时失败;第三方或组织数据需保证一致性。cwos-sdk-event等与本文无关的依赖问题不影响本业务链结论。- 访客注册主流程(表单、审批、写组织人员表)若在三方工程,需在对应仓库继续搜
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.* 为准。