0706 - bug修改+增加消息推送和待办的公共执行器
parent
2847068115
commit
7667276c30
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,373 @@
|
|||
# zcloud-gbs-primeport 项目梳理文档
|
||||
|
||||
## 一、项目概览
|
||||
|
||||
**系统名称**:港口口门门禁管理系统(primeport),应用名 `zcloud-gbs-primeport`,网关前缀 `/primeport`
|
||||
|
||||
**技术栈**:
|
||||
- Spring Boot 2.6.6 + Spring Cloud Alibaba(Nacos 配置中心/服务发现)
|
||||
- COLA 4.0 分层架构 + MyBatis-Plus + Druid + MySQL/PostgreSQL 双数据源
|
||||
- Redis、RocketMQ、XXL-JOB、Flyway、Swagger、Hutool、fastjson
|
||||
- 自研 jjb-saas 框架(网关/认证/系统客户端)
|
||||
- 大华 ICC SDK(`com.dahuatech.icc:java-sdk-oauth:1.0.13.15`)
|
||||
|
||||
**分层架构**(6 个 Maven 模块):
|
||||
|
||||
```
|
||||
start(启动) ──> web-adapter(控制器) ──> web-app(业务编排) ──> web-client(API契约+DTO) ──> web-domain(领域模型)
|
||||
│ │ │
|
||||
└──────────────────────┴──> web-infrastructure(基础设施+第三方对接) ──> web-domain
|
||||
```
|
||||
|
||||
调用链路示例:`Controller → ServiceImpl → Exe(命令执行器) → Gateway(领域接口) → GatewayImpl(基础设施) → Repository → Mapper → DB`
|
||||
|
||||
---
|
||||
|
||||
## 二、业务模块总览
|
||||
|
||||
系统按 **三类角色** 组织功能:监管端(JGD)、分公司端(FGS)、相关方/驻港单位端(XGF/ZGDW),通过 `MenuEnum` 控制约 60 项菜单权限。
|
||||
|
||||
### 1. 一级口门基础管理
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| 口门信息 | MkmjController | 口门名称、级别(1一级/2二级)、类型(人行/车行/综合)、所属港区、经纬度 |
|
||||
| 门禁通道 | MkmjPassageController | 通道类型、所属口门、状态 |
|
||||
| 闸机管理 | MkmjGateController | 闸机标识、型号、所属通道 |
|
||||
| 审批人 | MkmjApprovalUserController | 审批人企业/部门/岗位,人员/车辆/临时三类审核权限 |
|
||||
| 摄像头 | VideoController | 绑定口门或闸机,移动/平台类型 |
|
||||
| 刷卡记录 | MkmjSwipeCardRecordController | 接收大华推送的刷卡记录(`/dockSave`),分页查询 |
|
||||
|
||||
### 2. 封闭区域管理(二级口门)
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| 封闭区域 | ClosedAreaController | 树级结构(parentId)、按港区/管辖单位查询、统计 |
|
||||
| 人员申请 | ClosedAreaPersonApplyController | 申请/审批/授权(含二级门禁)、随行人员管理 |
|
||||
| 车辆申请 | ClosedAreaCarApplyController | 新增/分页/审批(auditFlag=2通过/3驳回) |
|
||||
| 临时申请 | ClosedTmpApplyController | 统一入口,按 TmpApplyEnum 路由到4种申请类型 |
|
||||
|
||||
### 3. 车辆管理
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| 车辆申请 | VehicleApplyController | 9种车辆归属、长期录入、车牌校验、相关方授权 |
|
||||
| 车辆审批 | VehicleAuditController | 待审批/审批记录/审批操作 |
|
||||
| 车辆黑名单 | VehicleBlackController | 新增/分页/删除 |
|
||||
| 车辆违规 | VehicleViolationsController | 违规记录,超阈值自动拉黑 |
|
||||
| 车辆门禁信息 | VehicleMessageController | 审批通过的固化信息,用于门禁对接 |
|
||||
| 车辆对接日志 | VehicleDockLogController | 一级/二级口门对接日志 |
|
||||
|
||||
### 4. 人员管理
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| 人员申请 | PersonApplyController | 相关方人员申请/审批/授权、临时访客H5申请、分公司人员管理 |
|
||||
| 人员门禁信息 | PersonMessageController | 审批通过的人员信息,用于门禁对接 |
|
||||
|
||||
### 5. 电动车数据接入
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| 电动车基础信息 | EVehicleBasicInfoController | 车辆备案(长期/一次性/内部/临时)、EDW数据溯源 |
|
||||
| 到离港信息 | EVehicleArrivalDepartureInfoController | 到达/离开闸口与时间记录 |
|
||||
|
||||
### 6. App 统计
|
||||
|
||||
| 模块 | Controller | 核心职责 |
|
||||
|------|-----------|---------|
|
||||
| App角标 | AppCountController | App端统计角标数据 |
|
||||
|
||||
---
|
||||
|
||||
## 三、核心业务流程
|
||||
|
||||
### 流程 A:口门车辆申请全链路
|
||||
|
||||
```
|
||||
申请提交 → VehicleApplyAddExe
|
||||
├─ 按归属类型回填(股份个人车直接 mkmjPermission=1)
|
||||
├─ 初始状态: auditFlag=1(待审), mkmjPermission=2(无权限)
|
||||
├─ 插入 VehicleAuditE 审批记录(changeAfter快照)
|
||||
└─ 推待办给审批人(RocketMQ)
|
||||
↓
|
||||
修改 → VehicleApplyUpdateExe (锁定车型/车牌/归属不可改, 重置auditFlag=1, 记录变更对比)
|
||||
↓
|
||||
审核 → VehicleAuditUpdateExe.audit
|
||||
├─ 通过(2): mkmjPermission=1 → CarDockUtil同步一级车行
|
||||
│ ├─ 临时/相关方车 → tmpVehicleSave(按港区portId)
|
||||
│ └─ 内部车 → executeInternalVehicle(先删后存)
|
||||
└─ 驳回(3): mkmjPermission=2
|
||||
```
|
||||
|
||||
### 流程 B:封闭区域车辆通行全链路
|
||||
|
||||
```
|
||||
申请 → ClosedAreaCarApplyAddExe (回填用户信息, auditFlag=1, 推待办)
|
||||
↓
|
||||
审批 → ClosedAreaCarApplyUpdateExe.auditCarApply
|
||||
└─ 通过时 → TwoCarUtil.levelTwoCarCompanyByApplyId
|
||||
├─ 二级海康: HKDeviceUtil.saveOrUpdCar + vehicleTopUp(当日有效)
|
||||
└─ 一级车行: 先查vehicle_apply是否已有有效权限,无则新增(不覆盖)
|
||||
```
|
||||
|
||||
### 流程 C:封闭区域人员授权链路(最复杂)
|
||||
|
||||
```
|
||||
申请 → ClosedAreaPersonApplyAddExe (auditFlag=1, 推待办)
|
||||
↓
|
||||
审核 → ClosedAreaPersonApplyUpdateExe.auditPersonApply
|
||||
└─ 通过时 → TwoPersonUtil.levelTwoPeopleCompanyByApplyId (海康+大华同步)
|
||||
↓
|
||||
授权 → ClosedAreaPersonApplyUpdateExe.authPerson
|
||||
├─ 删旧auth+area,重建auth+area(区域关联)
|
||||
└─ mkmjPermission=1时 → OnePersonUtil:
|
||||
├─ 查大华是否已有该身份证用户
|
||||
├─ 无 → dockLongTermUserByUserCardAndFaceImg (账号hbqa+身份证, 当日有效)
|
||||
└─ 有 → 保留不覆盖
|
||||
```
|
||||
|
||||
### 流程 D:车辆违规自动拉黑链路
|
||||
|
||||
```
|
||||
违规录入 → VehicleViolationsAddExe
|
||||
├─ 查历史违规数,若 (历史+1) >= 配置上限 → 自动拉黑
|
||||
│ ├─ vehicleBlackGateway.saveIfAbsent
|
||||
│ └─ vehicleApplyGateway.updateEvehicleBlockedByLicenceNo(...,1)
|
||||
└─ 新增违规记录(处理状态=2未处理)
|
||||
```
|
||||
|
||||
### 流程 E:相关方人员申请链路
|
||||
|
||||
```
|
||||
PersonApplyAddExe.xgfPersonSave
|
||||
├─ personBelongType∈{1,2} → auditFlag=2(自动通过) + mkmjPermission=1
|
||||
├─ 其他 → auditFlag=1(待审) + mkmjPermission=2
|
||||
├─ 推待办
|
||||
└─ 子表PersonApplyE批量保存(绑定主表XgfApplyPersonE)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、第三方接口对接
|
||||
|
||||
### 对接系统总览
|
||||
|
||||
| # | 第三方系统 | 对接方式 | 用途 | 级别 |
|
||||
|---|----------|---------|------|-----|
|
||||
| 1 | 大华 ICC 门禁 | SDK + HTTP(RSA加密) | 一级人员门禁:用户创建/有效期/冻结 | 一级 |
|
||||
| 2 | 海康威视门禁 | SDK(静态工具类) | 二级口门人员/车辆授权 | 二级 |
|
||||
| 3 | 秦皇岛港车行系统 | Hutool HTTP POST | 一级口门车辆(内部/临时/黑名单) | 一级 |
|
||||
| 4 | zcloud 用户中心 | Dubbo RPC | 用户信息、人脸图片base64 | 平台内 |
|
||||
| 5 | 待办列表 MQ | RocketMQ | 审批待办推送/完成 | 平台内 |
|
||||
| 6 | 大华刷卡推送 | HTTP 被动接收 | 刷卡记录入库 | 一级 |
|
||||
|
||||
### 1. 大华 ICC 对接(一级人员门禁)
|
||||
|
||||
**配置类**:
|
||||
- `web-domain/.../config/DaHuaOauthProperties.java`(`@ConfigurationProperties(prefix = "dahua.oauth")`:host / clientId / clientSecret / username / password / http / port)
|
||||
- `web-domain/.../config/DaHuaSdkConfig.java`(注入 `OauthConfigUserPwdInfo` Bean)
|
||||
- `start/src/main/resources/sdk.yml` 中 `dahua.oauth` 配置
|
||||
|
||||
**对接工具类**:
|
||||
- `web-infrastructure/.../plan/mjDevice/OnePersonUtil.java`
|
||||
- `web-infrastructure/.../plan/mjDevice/TwoPersonUtil.java`
|
||||
- `web-infrastructure/.../plan/mjDevice/OauthUtil.java`
|
||||
|
||||
**核心方法**:
|
||||
- `dockLongTermUserByUserCardAndFaceImg` - 按身份证查用户,不存在则新增(含人脸图片、有效期)
|
||||
- `expirationDateRefreshedUserCard` - 刷新用户门禁有效期
|
||||
- `freezeByUserCard` - 用户冻结(2)/解冻(1)
|
||||
- `getMkmjUserInfoByUserCard` - 按身份证批量查询用户
|
||||
|
||||
**OauthUtil 调用流程**:
|
||||
1. `getPublicKey()` - GET 公钥接口(忽略SSL证书的 RestTemplate)
|
||||
2. `getToken()` - POST 获取 Token(密码通过 RSA 加密)
|
||||
3. `getGenerateId() / getGenerateIdList(idCount)` - 获取全局用户ID(单个/批量)
|
||||
4. `getDepartmentId() / getDepartmentIdList(idCount)` - 获取部门ID
|
||||
5. `imgInspect(map)` - 图片质量检测,支持文件/URL/base64 三种格式
|
||||
|
||||
**配置项**(Nacos 下发,`icc.*`):
|
||||
- `icc.clientId` / `icc.clientSecret` / `icc.username` / `icc.password`
|
||||
- `icc.url` - ICC 基础地址
|
||||
- `icc.publicKeyUrl` - 公钥获取地址
|
||||
- `icc.request.getGenerateIdUrl` / `icc.request.getGenerateIdListUrl` - 全局用户ID接口
|
||||
- `icc.request.imgInspectUrl` - 图片质检接口
|
||||
- `icc.request.getDepartmentIdUrl` - 部门ID接口
|
||||
|
||||
### 2. 海康威视对接(二级口门)
|
||||
|
||||
**对接工具类**:
|
||||
- `web-infrastructure/.../plan/mjDevice/TwoCarUtil.java`
|
||||
- `web-infrastructure/.../plan/mjDevice/TwoPersonUtil.java`
|
||||
|
||||
**核心方法**:
|
||||
- 车辆:
|
||||
- `HKDeviceUtil.saveOrUpdCar(licenceNo, 0)` - 新增/更新车辆
|
||||
- `HKDeviceUtil.vehicleTopUp(licenceNo, 0, hkIndexCode, khParkSysCode, startDate, endDate)` - 车辆授权充值
|
||||
- 人员:
|
||||
- `HKDeviceUtil.getUserListByPhone(phoneList)` - 按手机号查人(限20人/次)
|
||||
- `HKDeviceUtil.getUserListByUserCard(userCard)` - 按身份证查人
|
||||
- `HKDeviceUtil.saveUser(name, cardNo, faceBase64, phone)` - 新增人员
|
||||
- `HKDeviceUtil.authPersonArea(personIds, resourceInfos, startTime, endTime)` - 授权门禁范围(限1000人/次)
|
||||
|
||||
**业务要点**:
|
||||
- 同步前通过 Dubbo `listBase64ByUrl` 把人脸URL转base64
|
||||
- 随行人员一并同步授权
|
||||
- 手机号查不到再用身份证查(处理手机号变更场景)
|
||||
|
||||
### 3. 秦皇岛港车行系统对接(一级口门车辆)
|
||||
|
||||
**对接工具类**:
|
||||
- `web-infrastructure/.../plan/mjDevice/OneLevelCarUtil.java`
|
||||
- `web-infrastructure/.../plan/mjDevice/CarDockUtil.java`
|
||||
|
||||
**配置**:
|
||||
- `${kmmj.dockflag}` - 对接开关(1=启用)
|
||||
- `${oneLevelCar.prefix}` - 服务前缀
|
||||
|
||||
**接口列表**(HTTP POST,前缀 `HD_QHD_IGATE_1.0`):
|
||||
|
||||
| 方法 | URL后缀 | 用途 |
|
||||
|------|--------|------|
|
||||
| internalVehicleSave | `/webresources/login/CTruck/qaSaveInternal` | 内部车辆保存 |
|
||||
| internalVehicleRemove | `/webresources/login/CTruck/qaDeleteInternal` | 内部车辆删除 |
|
||||
| tmpVehicleSave | `/webresources/login/CTruck/qaSaveTemp` | 临时车辆保存 |
|
||||
| tmpVehicleRemove | `/webresources/login/CTruck/qaDeleTemp` | 临时车辆删除 |
|
||||
| blackVehicleSave | `/webresources/login/CTruck/qaSaveBlack` | 黑名单新增 |
|
||||
| blackVehicleRemove | `/webresources/login/CTruck/qaDeleteBlack` | 黑名单删除 |
|
||||
|
||||
**CarDockUtil 协调器**:
|
||||
- `execute(licenceNo)` - 临时/相关方车走 `tmpVehicleSave`
|
||||
- `executeInternalVehicle(applyE)` - 内部车先 `internalVehicleRemove` 再 `internalVehicleSave`(覆盖更新)
|
||||
- `executeBlackSave / executeBlackRemove` - 黑名单新增/删除
|
||||
|
||||
每次对接写入 `VehicleDockLogDO` 日志表(level=1一级、dockFlag=2已对接、dockStatus=返回code、reasonsRefusal=返回msg)。
|
||||
|
||||
### 4. zcloud 用户中心(Dubbo)
|
||||
|
||||
通过 `@DubboReference ZcloudUserFacade`:
|
||||
|
||||
| 调用位置 | 方法 | 用途 |
|
||||
|---------|------|------|
|
||||
| TwoPersonUtil | `listBase64ByUrl(zcloudUserImgQry)` | 根据人脸URL列表批量获取 base64 |
|
||||
| ClosedAreaCarApplyAddExe | Dubbo 引用 | 闭区车辆申请新增时回填用户信息 |
|
||||
| ClosedAreaPersonApplyAddExe | Dubbo 引用 | 闭区人员申请新增时回填用户信息 |
|
||||
| ClosedAreaPersonApplyUpdateExe.authPerson | `getInfoByUserId(userId)` | 授权时获取用户身份证/姓名/人脸URL |
|
||||
|
||||
### 5. 待办列表 MQ(RocketMQ)
|
||||
|
||||
依赖:`spring-cloud-starter-stream-rocketmq`,工具类 `TodoListEventPusherUtil`
|
||||
|
||||
| 触发时机 | 事件类型 | 场景 |
|
||||
|---------|---------|------|
|
||||
| 申请提交 | TodoListAddEvent | 车辆/闭区车辆/闭区人员申请 |
|
||||
| 审批完成 | TodoListCompleteEvent | 车辆/闭区车辆/闭区人员审批 |
|
||||
|
||||
### 6. 大华刷卡记录推送(被动接收)
|
||||
|
||||
- **接收入口**:`POST /primeport/mkmjSwipeCardRecord/dockSave`
|
||||
- **数据结构**:`SwipeRecordPushVo`(外层)→ `SwipeRecordPushInfo`(info,含节点编码/设备编号/报警时间/报警状态)→ `SwipeRecordPushExtend`(extend,含刷卡人详细信息/进出/开门结果/抓拍图/卡信息)
|
||||
- **处理逻辑**:Controller 将三层嵌套结构扁平化为 `MkmjSwipeCardRecordAddCmd`,调用 Service 入库到 `mkmj_swipe_card_record` 表
|
||||
|
||||
---
|
||||
|
||||
## 五、定时任务(XXL-JOB)
|
||||
|
||||
全部位于 `web-infrastructure/plan/` 目录,每日凌晨执行:
|
||||
|
||||
| 任务类 | Cron | 职责 | 调用 |
|
||||
|-------|------|------|------|
|
||||
| VehicleExpiredExpirationXxlJob | `0 10 0 * * ?` | 车辆过期处理(更新状态+关闭门禁权限) | 仅更新数据库,门禁移除已注释 |
|
||||
| OneLevelUserXxlJon | `0 14 0 * * ?` | 一级人员门禁当日授权(相关方/临时访客) | `onePersonUtil.execute()` |
|
||||
| VehicleXgfVehicleXxlJob | `0 15 0 * * ?` | 相关方/临时车辆当日可进港区判断+推送一级门禁 | `carDockUtil.execute(param)` |
|
||||
| TwoLevelPersonXxlJob | `0 20 0 * * ?` | 二级门禁人员同步(含一级大华) | `twoPersonUtil.scheduledPeopleCompany()` |
|
||||
| TwoLevelCarXxlJob | `0 25 0 * * ?` | 二级门禁车辆同步(含一级车行) | `twoCarUtil.scheduledCarCompany()` |
|
||||
|
||||
> 二级任务支持"单个异常跳过不影响其他"模式。
|
||||
|
||||
---
|
||||
|
||||
## 六、领域模型
|
||||
|
||||
| 实体 | 中文 | 关键字段 |
|
||||
|------|------|---------|
|
||||
| MkmjE | 门口信息 | mkmjName、mkmjLevel(1一级/2二级)、mkmjType(人行/车行/综合)、hgAuthArea、出入方向区域、经纬度、closedAreaId |
|
||||
| MkmjPassageE | 通道 | passageName、passageType、mkmjId |
|
||||
| MkmjGateE | 闸机 | gateNumber、gateName、gateType、passageId、mkmjId |
|
||||
| MkmjApprovalUserE | 门禁审批人 | corpId/deptId/userId、人员/车辆/临时审核权限 |
|
||||
| MkmjSwipeCardRecordE | 刷卡记录 | 节点/报警/通道/人员/卡号/进出/开门结果/抓拍图 |
|
||||
| ClosedAreaE | 封闭区域 | parentId、hgAuthArea、closedAreaName、jurisdictionalCorpId、location |
|
||||
| ClosedAreaPersonApplyE | 封闭区域人员申请 | personBelongType、一级/二级口门、closedAreaId、申请/审批信息、随行人员 |
|
||||
| ClosedAreaCarApplyE | 封闭区域车辆申请 | carBelongType、车牌、一级/二级口门、行驶证、随行人员 |
|
||||
| ClosedAreaFgsPersonAreaE | 分公司人员区域授权 | fgsPersonAuthId、closedAreaId |
|
||||
| ClosedAreaFgsPersonAuthE | 分公司人员授权 | corpId、departmentId、userId、mkmjPermission |
|
||||
| VehicleApplyE | 车辆申请 | 车牌/类型/所属类型(1-9)、授权范围、审核状态、访问时间、企业/部门/申请人/审批人 |
|
||||
| VehicleAuditE | 车辆审批 | vehicleApplyId、batchType(普通/危化)、审批人、审批状态、变更前后 |
|
||||
| VehicleBlackE | 车辆黑名单 | licenceNo、blockReason |
|
||||
| VehicleViolationsE | 车辆违规 | vehicleId、violationType、location、illegalImagesId、processingStatus |
|
||||
| VehicleMessageE | 车辆门禁对接信息 | vehicleApplyId、syncStatus、syncRemarks |
|
||||
| VehicleDockLogE | 车辆对接日志 | level(1一级/2二级)、portArea(0全部/1东港/2西港)、dockFlag/dockStatus |
|
||||
| PersonApplyE | 人员申请 | 企业/部门/人员、头像/手机/身份证 |
|
||||
| XgfApplyPersonE | 相关方人员申请 | personBelongType、mkmjId、gateLevelAuthArea、审批/驳回信息 |
|
||||
| PersonMessageE | 人员门禁对接信息 | personApplyId、syncStatus、syncRemarks |
|
||||
| VideoE | 摄像头 | foreignId、deviceType(1口门/2闸机)、videoType(移动/平台) |
|
||||
| EVehicleBasicInfoE | 一级口门车辆基础信息 | vehicleRecordId、备案字段、EDW数据溯源字段 |
|
||||
| EVehicleArrivalDepartureInfoE | 一级口门车辆到离信息 | 到达/离开闸口与时间、车辆序列号 |
|
||||
|
||||
---
|
||||
|
||||
## 七、关键状态枚举
|
||||
|
||||
| 枚举类 | 值 | 说明 |
|
||||
|-------|---|------|
|
||||
| **AuditEnum** | 1审核中 / 2通过 / 3驳回 / 4无需审批(检查部门车) | 审批状态 |
|
||||
| **VehicleBelongTypeEnum** | 1股份员工 / 2股份单位 / 3分公司员工 / 4分公司单位 / 5相关方 / 6临时 / 7检查部门 / 8驻港单位员工 / 9驻港单位公车 | 车辆归属类型 |
|
||||
| **CloseCarBelongTypeEnum** | 1股份 / 2分公司 / 3相关方 / 4临时车 / 5分公司内部车 | 封闭区域车辆申请归属 |
|
||||
| **TmpApplyEnum** | CAR_APPLY/PERSON_APPLY × 一级/二级 | 临时申请类型 |
|
||||
| **FileTypeEnum** | File / url / base64 | 文件格式 |
|
||||
| **SaveTypeEnum** | 保留 / 删除 / 检测通过保留 | 图片保存策略 |
|
||||
| **MenuEnum** | 约60项(JGD_*/FGS_*/XGS_*/ZGDW_*) | 菜单与权限枚举 |
|
||||
|
||||
---
|
||||
|
||||
## 八、审批触发对接入口汇总
|
||||
|
||||
| 执行类 | 方法 | 触发对接 |
|
||||
|-------|------|---------|
|
||||
| VehicleAuditUpdateExe.audit | 车辆审批通过(auditStatus=2) | 临时/相关方车 → `carDockUtil.execute`;其他 → `carDockUtil.executeInternalVehicle` |
|
||||
| VehicleBlackAddExe.execute | 车辆拉黑 | `carDockUtil.executeBlackSave` |
|
||||
| VehicleBlackRemoveExe.execute | 车辆解除黑名单 | `carDockUtil.executeBlackRemove` |
|
||||
| ClosedAreaCarApplyUpdateExe.auditCarApply | 闭区车辆审批通过 | `twoCarUtil.levelTwoCarCompanyByApplyId`(先二级海康,再一级车行) |
|
||||
| ClosedAreaPersonApplyUpdateExe.auditPersonApply | 闭区人员审批通过 | `twoPersonUtil.levelTwoPeopleCompanyByApplyId`(二级海康+一级大华) |
|
||||
| ClosedAreaPersonApplyUpdateExe.authPerson | 人员授权开启(mkmjPermission=1) | 查大华已有权限,没有则 `onePersonUtil.dockLongTermUserByUserCardAndFaceImg` |
|
||||
|
||||
---
|
||||
|
||||
## 九、配置文件结构
|
||||
|
||||
| 文件 | 作用 |
|
||||
|------|------|
|
||||
| bootstrap.yml | 主入口,import prodnacos.yml + sdk.yml + swagger.yml |
|
||||
| prodnacos.yml | 生产 Nacos 配置(prod-nacos:8848,namespace=jjb-dragon,profile=prod) |
|
||||
| nacos.yml | 测试 Nacos 配置(192.168.20.100:30290,profile=test) |
|
||||
| ds.yml | 多数据源配置:MySQL(Druid) + PostgreSQL |
|
||||
| sdk.yml | SDK网关路由、开放平台OpenAPI(SM2加密)、大华oauth配置 |
|
||||
| swagger.yml | Swagger 文档开关与路径 |
|
||||
|
||||
**Nacos 共享配置**:`config-common.yml`、`config-port.yml`、`config-mq.yml`、`config-log.yml`、`config-sdk-server.yml`、`config-actuator.yml`、`config-job.yml`、`config-mysql.yml`、`config-redis.yml`、`config-cache.yml`、`config-spring.yml`、`config-mybatis.yml`、`config-sdk.yml`、`config-flyway.yml` 以及 `${application.name}-conf.yml`
|
||||
|
||||
---
|
||||
|
||||
## 十、关键风险点
|
||||
|
||||
1. **硬编码凭据**:OnePersonUtil/TwoPersonUtil 中大华 URL、用户名、密码、clientId/clientSecret 全部硬编码(`https://skqhdg.porthebei.com:9008/yjkmRy/`、`shuangkong`、`qinan@202604`),存在安全隐患
|
||||
2. **对接开关失效**:`dockFlag` 是 static 字段且默认 0,`@Value` 注解被注释掉,无法通过配置切换对接开关
|
||||
3. **有效期仅当日**:大华用户新增时有效期仅 `今天 00:00~23:59`,依赖每日定时任务刷新,任务中断则权限失效
|
||||
4. **事务边界风险**:外部调用(Dubbo/HK/大华/MQ)在 `@Transactional` 内执行,外部系统已写入的数据无法回滚,存在数据不一致风险
|
||||
5. **不覆盖策略**:一级门禁对接普遍采用"先查再决定是否新增",避免覆盖已有长期权限;但二级海康按当日有效期充值
|
||||
6. **电动车模块薄弱**:两个 Exe 均为纯 CRUD,到离港记录未与基本信息做关联校验,无状态机
|
||||
7. **残留代码**:ClosedAreaPersonApplyAddExe 含 main 方法(Base64 测试);ClosedAreaCountExe 的 corpId 过滤被注释
|
||||
8. **架构不一致**:MkmjApprovalUserAddExe 直接注入 Repository 而非 Gateway,绕过了领域层抽象
|
||||
9. **硬编码状态值**:部分 Exe 使用字面量(如 `1`、`equals(2)`)而非 AuditEnum 枚举,可读性差
|
||||
10. **DaHuaSdkUtil 是占位类**:login() 返回 null,实际大华调用走的是 gbscommon 包中的 DaHuaDeviceCommon
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 14:46:37] App_Identifier[primeport]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>临时访客申请</title><script>(function () {
|
||||
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 15:26:15] App_Identifier[primeport-h5]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>临时访客申请</title><script>(function () {
|
||||
const APP_ENV = {
|
||||
antd: {
|
||||
'ant-prefix': 'micro-temp',
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
borderRadius: parseInt('2')
|
||||
},
|
||||
appKey: '',
|
||||
basename: 'primeport',
|
||||
basename: 'primeport-h5',
|
||||
API_HOST: ''
|
||||
};
|
||||
APP_ENV.API_HOST = sessionStorage.API_HOST || APP_ENV.API_HOST || window.location.origin;
|
||||
|
|
@ -20,4 +20,4 @@
|
|||
redirect: '',
|
||||
FRAMEWORK: APP_ENV.antd
|
||||
};
|
||||
})();</script><script defer="defer" src="/primeport/static/js/942.000313a5011c30f5.js"></script><script defer="defer" src="/primeport/static/js/98.90d75146a9ca149f.js"></script><script defer="defer" src="/primeport/static/js/main.4a9b58a5b07ec8b5.js"></script><link href="/primeport/static/css/main.de5125c7f5780dd6.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 14:46:37] App_Identifier[primeport] Frontend_Branch[master] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>
|
||||
})();</script><script defer="defer" src="/primeport-h5/static/js/942.02e830144bca35fa.js"></script><script defer="defer" src="/primeport-h5/static/js/98.d3878dfe7429795b.js"></script><script defer="defer" src="/primeport-h5/static/js/main.d66f2eb7e011fd76.js"></script><link href="/primeport-h5/static/css/main.de5125c7f5780dd6.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 15:26:15] App_Identifier[primeport-h5] Frontend_Branch[master] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/1 10:52:34] App_Identifier[primeport]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>--</title><script>(function () {
|
||||
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 17:57:46] App_Identifier[primeport]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>临时访客申请</title><script>(function () {
|
||||
const APP_ENV = {
|
||||
antd: {
|
||||
'ant-prefix': 'micro-temp',
|
||||
|
|
@ -20,4 +20,4 @@
|
|||
redirect: '',
|
||||
FRAMEWORK: APP_ENV.antd
|
||||
};
|
||||
})();</script><script defer="defer" src="/primeport/static/js/942.000313a5011c30f5.js"></script><script defer="defer" src="/primeport/static/js/98.90d75146a9ca149f.js"></script><script defer="defer" src="/primeport/static/js/main.fd83071fcc1ae30e.js"></script><link href="/primeport/static/css/main.de5125c7f5780dd6.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/1 10:52:34] App_Identifier[primeport] Frontend_Branch[master] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>
|
||||
})();</script><script defer="defer" src="/primeport/static/js/942.000313a5011c30f5.js"></script><script defer="defer" src="/primeport/static/js/98.90d75146a9ca149f.js"></script><script defer="defer" src="/primeport/static/js/main.4228da465de98de9.js"></script><link href="/primeport/static/css/main.de5125c7f5780dd6.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/3 17:57:46] App_Identifier[primeport] Frontend_Branch[master] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -20,6 +20,9 @@ import org.springframework.beans.BeanUtils;
|
|||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* web-app
|
||||
|
|
@ -31,7 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
@AllArgsConstructor
|
||||
public class ClosedAreaCarApplyAddExe {
|
||||
private final ClosedAreaCarApplyGateway closedAreaCarApplyGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
@DubboReference
|
||||
private ZcloudUserFacade zcloudUserFacade;
|
||||
|
||||
|
|
@ -61,24 +64,20 @@ public class ClosedAreaCarApplyAddExe {
|
|||
} else {
|
||||
// closedAreaCarApplyE.setUserCard(Base64.encodeToString(cmd.getUserCard()));
|
||||
}
|
||||
boolean res = false;
|
||||
try {
|
||||
res = closedAreaCarApplyGateway.add(closedAreaCarApplyE);
|
||||
TodoListAddEvent todoListAddEvent = new TodoListAddEvent();
|
||||
todoListAddEvent.setForeignKey(closedAreaCarApplyE.getId());
|
||||
todoListAddEvent.setForeignSubsidiaryKey(closedAreaCarApplyE.getId());
|
||||
todoListAddEvent.setTitle("您有一条封闭区域审核,请及时进行审核。");
|
||||
todoListAddEvent.setContent("待审核");
|
||||
todoListAddEvent.setReceiveUser(cmd.getAuditPersonUserId());
|
||||
todoListAddEvent.setPcFlag(1);
|
||||
todoListAddEvent.setAppFlag(1);
|
||||
todoListEventPusherUtil.sendMessageAddEvent(todoListAddEvent);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
boolean res = closedAreaCarApplyGateway.add(closedAreaCarApplyE);
|
||||
if (!res) {
|
||||
throw new BizException("保存失败");
|
||||
}
|
||||
|
||||
// 发送消息通知 和 待办
|
||||
if (cmd.getAuditPersonUserId() != null) {
|
||||
// 发送消息提醒
|
||||
Map <String, Object> sendParams = new HashMap <>();
|
||||
messageNoticeExe.sendMessageNotice(cmd.getAuditPersonUserId(), "封闭区域审核", sendParams);
|
||||
// 发送待办
|
||||
messageNoticeExe.sendMessageTodoEvent(cmd.getAuditPersonUserId(), "您有一条封闭区域审核,请及时进行审核。", "待审核", closedAreaCarApplyE.getId(), closedAreaCarApplyE.getId(), 1, 1);
|
||||
}
|
||||
|
||||
return closedAreaCarApplyE.getId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import java.util.Date;
|
|||
@AllArgsConstructor
|
||||
public class ClosedAreaCarApplyUpdateExe {
|
||||
private final ClosedAreaCarApplyGateway closedAreaCarApplyGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
private final TwoCarUtil twoCarUtil;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
|
@ -49,9 +49,9 @@ public class ClosedAreaCarApplyUpdateExe {
|
|||
closedAreaCarApplyE.setAuditTime(DateUtil.date2Str(new Date()));
|
||||
closedAreaCarApplyGateway.update(closedAreaCarApplyE);
|
||||
|
||||
TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent();
|
||||
todoListCompleteEvent.setForeignSubsidiaryKey(auditCmd.getId());
|
||||
todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent);
|
||||
// 完成待办
|
||||
messageNoticeExe.sendMessageCompleteEvent(auditCmd.getId());
|
||||
|
||||
// 审批通过 → 同步门禁权限(二级海康 + 一级车行)
|
||||
// 根据carBelongType判断车辆类型,内部车不走临时接口,不覆盖一级原有权限
|
||||
if (auditCmd.getAuditFlag().equals(2)) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ import org.springframework.beans.BeanUtils;
|
|||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* web-app
|
||||
|
|
@ -29,7 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
@AllArgsConstructor
|
||||
public class ClosedAreaPersonApplyAddExe {
|
||||
private final ClosedAreaPersonApplyGateway closedAreaPersonApplyGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
|
||||
@DubboReference
|
||||
private ZcloudUserFacade zcloudUserFacade;
|
||||
|
|
@ -55,24 +58,21 @@ public class ClosedAreaPersonApplyAddExe {
|
|||
}else {
|
||||
// closedAreaPersonApplyE.setUserCard(Base64.encodeToString(cmd.getUserCard()));
|
||||
}
|
||||
boolean res = false;
|
||||
try {
|
||||
res = closedAreaPersonApplyGateway.add(closedAreaPersonApplyE);
|
||||
TodoListAddEvent todoListAddEvent = new TodoListAddEvent();
|
||||
todoListAddEvent.setForeignKey(closedAreaPersonApplyE.getId());
|
||||
todoListAddEvent.setForeignSubsidiaryKey(closedAreaPersonApplyE.getId());
|
||||
todoListAddEvent.setTitle("您有一条封闭区域审核,请及时进行审核。");
|
||||
todoListAddEvent.setContent("待审核");
|
||||
todoListAddEvent.setReceiveUser(cmd.getAuditPersonUserId());
|
||||
todoListAddEvent.setPcFlag(1);
|
||||
todoListAddEvent.setAppFlag(1);
|
||||
todoListEventPusherUtil.sendMessageAddEvent(todoListAddEvent);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
boolean res = closedAreaPersonApplyGateway.add(closedAreaPersonApplyE);
|
||||
if (!res) {
|
||||
throw new BizException("保存失败");
|
||||
}
|
||||
|
||||
// 发送 消息通知 和 待办
|
||||
// 发送消息通知 和 待办
|
||||
if (cmd.getAuditPersonUserId() != null) {
|
||||
// 发送消息提醒
|
||||
Map <String, Object> sendParams = new HashMap <>();
|
||||
messageNoticeExe.sendMessageNotice(cmd.getAuditPersonUserId(), "封闭区域审核", sendParams);
|
||||
// 发送待办
|
||||
messageNoticeExe.sendMessageTodoEvent(cmd.getAuditPersonUserId(), "您有一条封闭区域审核,请及时进行审核。", "待审核", closedAreaPersonApplyE.getId(), closedAreaPersonApplyE.getId(), 1, 1);
|
||||
}
|
||||
|
||||
return closedAreaPersonApplyE.getId();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class ClosedAreaPersonApplyUpdateExe {
|
|||
private final ClosedAreaPersonApplyGateway closedAreaPersonApplyGateway;
|
||||
private final ClosedAreaFgsPersonAuthGateway areaFgsPersonAuthGateway;
|
||||
private final ClosedAreaFgsPersonAreaGateway areaFgsPersonAreaGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
private final TwoPersonUtil twoPersonUtil;
|
||||
private final OnePersonUtil onePersonUtil;
|
||||
|
||||
|
|
@ -68,9 +68,10 @@ public class ClosedAreaPersonApplyUpdateExe {
|
|||
closedAreaPersonApplyE.setRefusalReason(auditCmd.getRefusalReason());
|
||||
closedAreaPersonApplyE.setAuditTime(DateUtil.date2Str(new Date()));
|
||||
closedAreaPersonApplyGateway.update(closedAreaPersonApplyE);
|
||||
TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent();
|
||||
todoListCompleteEvent.setForeignSubsidiaryKey(auditCmd.getId());
|
||||
todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent);
|
||||
|
||||
// 完成待办
|
||||
messageNoticeExe.sendMessageCompleteEvent(auditCmd.getId());
|
||||
|
||||
// 审批通过 → 同步门禁权限(二级海康 + 一级大华)
|
||||
// 内部会先查大华系统判断是否已有权限,不覆盖原有权限
|
||||
if (auditCmd.getAuditFlag().equals(2)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
package com.zcloud.primeport.command;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.cola.dto.SingleResponse;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.jjb.saas.message.client.message.facede.MessageFacade;
|
||||
import com.jjb.saas.message.client.message.request.MessageSendCmd;
|
||||
import com.jjb.saas.message.client.message.request.MessageTargetCmd;
|
||||
import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil;
|
||||
import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent;
|
||||
import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent;
|
||||
import com.zcloud.gbscommon.todolistmq.event.TodoListDeleteEvent;
|
||||
import com.zcloud.gbscommon.utils.Tools;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* web-app
|
||||
*
|
||||
* @Author txl
|
||||
* @Date 2026-07-06 16:05:38
|
||||
*/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class MessageNoticeExe {
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
@DubboReference
|
||||
private MessageFacade messageFacade;
|
||||
|
||||
public void sendMessageNotice(Long userId, String sourceCode,Map<String, Object> sendParams) {
|
||||
//消息通知
|
||||
try{
|
||||
|
||||
MessageSendCmd messageSendCmd = new MessageSendCmd();
|
||||
messageSendCmd.setBusinessId(Tools.get32UUID());
|
||||
MessageTargetCmd messageTargetCmd = new MessageTargetCmd();
|
||||
messageTargetCmd.setUserId(userId);
|
||||
messageSendCmd.setTargetCmd(messageTargetCmd);
|
||||
messageSendCmd.setSourceCode(sourceCode);
|
||||
messageSendCmd.setNeedTokenEnum(false);
|
||||
messageSendCmd.setParams(sendParams);
|
||||
|
||||
log.info("{},消息提醒发送消息参数:messageSendCmd: {}",sourceCode, JSONUtil.toJsonStr(messageSendCmd));
|
||||
SingleResponse<Boolean> d = messageFacade.send(messageSendCmd);
|
||||
log.info("{},消息提醒发送消息结果:d: {}", sourceCode,JSONUtil.toJsonStr(d));
|
||||
}catch (Exception e) {
|
||||
log.error("{},消息提醒发送消息异常:", sourceCode,e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId 接收人ID
|
||||
* @param title 标题
|
||||
* @param content 内容
|
||||
* @param foreignKey 业务表ID
|
||||
* @param foreignSubsidiaryKey 业务附表ID
|
||||
* @param pcFlag 是否是PC端待办
|
||||
* @param appFlag 是否是APP端待办
|
||||
*/
|
||||
@Async("asyncExecutor")
|
||||
public void sendMessageTodoEvent(Long userId, String title,String content, Long foreignKey, Long foreignSubsidiaryKey, Integer pcFlag, Integer appFlag) {
|
||||
//消息通知
|
||||
try{
|
||||
// 发送待办
|
||||
TodoListAddEvent event = new TodoListAddEvent();
|
||||
event.setTitle(title);
|
||||
event.setContent(content);
|
||||
event.setForeignKey(foreignKey); // 业务表ID -申请
|
||||
event.setForeignSubsidiaryKey(foreignSubsidiaryKey); // 业务附表ID 没有附表时为foreignKey的值
|
||||
event.setReceiveUser(userId);// user表ID
|
||||
event.setPcFlag(pcFlag); // 是否PC端待办 1是 0否
|
||||
event.setAppFlag(appFlag); // 是否APP端待办 1是 0否
|
||||
event.setOtherParams(new JSONObject());
|
||||
log.info("待办,请求:{}",event);
|
||||
//为了防止先被完成
|
||||
Thread.sleep(2000L);
|
||||
boolean b = todoListEventPusherUtil.sendMessageAddEvent(event);
|
||||
log.info("待办,结果:{}",b);
|
||||
}catch (Exception e) {
|
||||
log.error("消息待办,{},发送消息异常:", title,e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessageCompleteEvent(Long foreignKey) {
|
||||
//消息通知
|
||||
try{
|
||||
// 发送待办
|
||||
TodoListCompleteEvent event = new TodoListCompleteEvent();
|
||||
event.setForeignSubsidiaryKey(foreignKey);// 业务附表ID 没有附表时为foreignKey的值
|
||||
log.info("完成待办,请求:{}",foreignKey);
|
||||
boolean b = todoListEventPusherUtil.sendMessageCompleteEvent(event);
|
||||
log.info("完成待办,结果:{}",b);
|
||||
}catch (Exception e) {
|
||||
log.error("完成待办失败",e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessageDeleteEvent(Long foreignKey) {
|
||||
try{
|
||||
TodoListDeleteEvent event2 = new TodoListDeleteEvent();
|
||||
event2.setForeignSubsidiaryKey(foreignKey);// 业务附表ID 没有附表时为foreignKey的值
|
||||
|
||||
log.info("删除待办,请求:{}",foreignKey);
|
||||
boolean b = todoListEventPusherUtil.sendMessageDeleteEvent(event2);
|
||||
log.info("删除待办,结果:{}",b);
|
||||
}catch (Exception e) {
|
||||
log.error("完成待办失败",e);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -24,9 +24,7 @@ import org.springframework.stereotype.Component;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -40,7 +38,7 @@ import java.util.List;
|
|||
public class PersonApplyAddExe {
|
||||
private final PersonApplyGateway personApplyGateway;
|
||||
private final XgfApplyPersonGateway xgfApplyPersonGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean execute(PersonApplyAddCmd cmd) {
|
||||
|
|
@ -75,15 +73,17 @@ public class PersonApplyAddExe {
|
|||
.applyCorpName(cmd.getPersonBelongType() != 4 ? AuthContext.getCurrentUser().getTenantName() : null)
|
||||
.projectId(cmd.getProjectId()).projectName(cmd.getProjectName()).informSignId(cmd.getInformSignId()).build();
|
||||
xgfApplyPersonGateway.save(build);
|
||||
TodoListAddEvent todoListAddEvent = new TodoListAddEvent();
|
||||
todoListAddEvent.setForeignKey(build.getId());
|
||||
todoListAddEvent.setForeignSubsidiaryKey(build.getId());
|
||||
todoListAddEvent.setTitle("您有一条口门审核,请及时进行审核。");
|
||||
todoListAddEvent.setContent("待审核");
|
||||
todoListAddEvent.setReceiveUser(cmd.getAuditUserId());
|
||||
todoListAddEvent.setPcFlag(1);
|
||||
todoListAddEvent.setAppFlag(1);
|
||||
todoListEventPusherUtil.sendMessageAddEvent(todoListAddEvent);
|
||||
|
||||
|
||||
// 发送 消息提醒 和 待办
|
||||
if (cmd.getAuditUserId() != null) {
|
||||
// 发送消息提醒
|
||||
Map <String, Object> sendParams = new HashMap <>();
|
||||
messageNoticeExe.sendMessageNotice(cmd.getAuditUserId(), "口门审核", sendParams);
|
||||
// 发送待办
|
||||
messageNoticeExe.sendMessageTodoEvent(cmd.getAuditUserId(), "您有一条口门审核,请及时进行审核。", "待审核", build.getId(), build.getId(), 1, 1);
|
||||
}
|
||||
|
||||
List<XgfPersonApplyAddCmd.PersonApplyAddCmdExt> personApplyList = cmd.getPersonApplyList();
|
||||
// 相关方人员信息的保存
|
||||
ArrayList<PersonApplyE> personApplyES = new ArrayList<>();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import java.util.Date;
|
|||
public class PersonApplyUpdateExe {
|
||||
private final PersonApplyGateway personApplyGateway;
|
||||
private final XgfApplyPersonGateway xgfApplyPersonGateway;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(PersonApplyUpdateCmd personApplyUpdateCmd) {
|
||||
|
|
@ -51,6 +52,8 @@ public class PersonApplyUpdateExe {
|
|||
build.setId(cmd.getId());
|
||||
personApplyGateway.xgfPersonAudit(build);
|
||||
|
||||
// 完成待办
|
||||
messageNoticeExe.sendMessageCompleteEvent(build.getId());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import org.springframework.stereotype.Component;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +38,7 @@ import java.util.Date;
|
|||
public class VehicleApplyAddExe {
|
||||
private final VehicleApplyGateway vehicleApplyGateway;
|
||||
private final VehicleAuditGateway vehicleAuditGateway;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public VehicleApplyE execute(VehicleApplyAddCmd cmd) {
|
||||
|
|
@ -81,17 +83,15 @@ public class VehicleApplyAddExe {
|
|||
.auditDeptId(examTypeE.getAuditDeptId()).auditDeptName(examTypeE.getAuditDeptName()).auditCorpId(examTypeE.getAuditCorpId()).auditCorpName(examTypeE.getAuditCorpName()).auditStatus(AuditEnum.WAITING.getCode()).changeAfter(JSON.toJSONString(examTypeE)).build();
|
||||
// 添加审批信息
|
||||
vehicleAuditGateway.add(build);
|
||||
TodoListAddEvent todoListAddEvent = new TodoListAddEvent();
|
||||
todoListAddEvent.setForeignKey(build.getId());
|
||||
todoListAddEvent.setForeignSubsidiaryKey(build.getId());
|
||||
todoListAddEvent.setTitle("您有一条口门审核,请及时进行审核。");
|
||||
todoListAddEvent.setContent("待审核");
|
||||
todoListAddEvent.setReceiveUser(cmd.getAuditUserId());
|
||||
todoListAddEvent.setPcFlag(1);
|
||||
todoListAddEvent.setAppFlag(1);
|
||||
todoListEventPusherUtil.sendMessageAddEvent(todoListAddEvent);
|
||||
// 发送待审核消息
|
||||
// todoListEventPusherUtil.sendMessageAddEvent(build.getSendEventObj());
|
||||
|
||||
// 发送 消息通知 和 待办
|
||||
if (cmd.getAuditUserId() != null) {
|
||||
// 发送消息提醒
|
||||
Map <String, Object> sendParams = new HashMap <>();
|
||||
messageNoticeExe.sendMessageNotice(cmd.getAuditUserId(), "口门审核", sendParams);
|
||||
// 发送待办
|
||||
messageNoticeExe.sendMessageTodoEvent(cmd.getAuditUserId(), "您有一条口门审核,请及时进行审核。", "待审核", build.getId(), build.getId(), 1, 1);
|
||||
}
|
||||
|
||||
return add;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class VehicleAuditUpdateExe {
|
|||
private final VehicleAuditGateway vehicleAuditGateway;
|
||||
private final VehicleApplyGateway vehicleApplyGateway;
|
||||
private final CarDockUtil carDockUtil;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final MessageNoticeExe messageNoticeExe;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(VehicleAuditUpdateCmd vehicleAuditUpdateCmd) {
|
||||
|
|
@ -64,16 +64,16 @@ public class VehicleAuditUpdateExe {
|
|||
// 审批通过 进行数据对接。
|
||||
if (cmd.getAuditStatus().equals(2)) {
|
||||
VehicleApplyE vehicleApplyE1 = vehicleApplyGateway.getById(cmd.getVehicleApplyId());
|
||||
if (vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.TEMP_VEHICLES.getCode()) ||
|
||||
vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.XGF_VEHICLES.getCode())) {
|
||||
if (vehicleApplyE1 != null && (vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.TEMP_VEHICLES.getCode()) ||
|
||||
vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.XGF_VEHICLES.getCode()))) {
|
||||
carDockUtil.execute(vehicleApplyE1.getLicenceNo());
|
||||
} else {
|
||||
carDockUtil.executeInternalVehicle(vehicleApplyE1);
|
||||
}
|
||||
}
|
||||
TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent();
|
||||
todoListCompleteEvent.setForeignSubsidiaryKey(vehicleAuditE.getId());
|
||||
todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent);
|
||||
|
||||
// 完成待办
|
||||
messageNoticeExe.sendMessageCompleteEvent(vehicleAuditE.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ public class ClosedAreaCountExe {
|
|||
for (ClosedAreaCountCO closedAreaCountCO : examCenterCOS) {
|
||||
closedAreaCountCO.setChildren(treeChildren(closedAreaCountCO.getId(), pageResponse));
|
||||
}
|
||||
// 递归汇总子节点的人员数和车辆数到父节点
|
||||
for (ClosedAreaCountCO closedAreaCountCO : examCenterCOS) {
|
||||
sumChildrenCount(closedAreaCountCO);
|
||||
}
|
||||
return MultiResponse.of(examCenterCOS);
|
||||
}
|
||||
|
||||
|
|
@ -74,5 +78,26 @@ public class ClosedAreaCountExe {
|
|||
}
|
||||
return childList.isEmpty() ? null : childList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归汇总子节点的人员数和车辆数到父节点
|
||||
* 父节点自身可能有直接关联的申请,加上所有子节点的数量
|
||||
*/
|
||||
private void sumChildrenCount(ClosedAreaCountCO node) {
|
||||
List<ClosedAreaCountCO> children = node.getChildren();
|
||||
if (children == null || children.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int personSum = 0;
|
||||
int carSum = 0;
|
||||
for (ClosedAreaCountCO child : children) {
|
||||
sumChildrenCount(child);
|
||||
personSum += (child.getPersonCount() != null ? child.getPersonCount() : 0);
|
||||
carSum += (child.getCarCount() != null ? child.getCarCount() : 0);
|
||||
}
|
||||
// 父节点自身直接关联的数量 + 所有子节点的汇总
|
||||
node.setPersonCount((node.getPersonCount() != null ? node.getPersonCount() : 0) + personSum);
|
||||
node.setCarCount((node.getCarCount() != null ? node.getCarCount() : 0) + carSum);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.zcloud.primeport.dto;
|
||||
|
||||
import com.alibaba.cola.dto.PageQuery;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* web-client
|
||||
*
|
||||
* @Author makejava
|
||||
* @Date 2026-03-05 11:33:24
|
||||
*/
|
||||
@Data
|
||||
public class VehicleApplyCountPageQry extends PageQuery {
|
||||
|
||||
@ApiModelProperty(value = "封闭区域名称", name = "closedAreaName")
|
||||
private String closedAreaName;
|
||||
private String menuPath;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -2,6 +2,7 @@ package com.zcloud.primeport.gatewayimpl;
|
|||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.alibaba.cola.exception.BizException;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil;
|
||||
|
|
@ -38,7 +39,6 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway {
|
|||
private final PersonApplyRepository personApplyRepository;
|
||||
private final XgfApplyPersonRepository xgfApplyPersonRepository;
|
||||
private final PersonMessageRepository personMessageRepository;
|
||||
private final TodoListEventPusherUtil todoListEventPusherUtil;
|
||||
private final OnePersonUtil onePersonUtil;
|
||||
|
||||
@Override
|
||||
|
|
@ -110,7 +110,11 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway {
|
|||
messageDO.setVisitStartTime(byId.getVisitStartTime());
|
||||
messageDO.setVisitEndTime(byId.getVisitEndTime());
|
||||
personMessageDOS.add(messageDO);
|
||||
try {
|
||||
userCardHashSet.add(Base64.decodeToString(item.getUserCard()));
|
||||
} catch (Exception e) {
|
||||
throw new BizException("用户身份证解析错误");
|
||||
}
|
||||
JSONObject entries = new JSONObject();
|
||||
entries.set("name", item.getEmployeePersonUserName());
|
||||
entries.set("code", "hbqa" + Base64.decodeToString(item.getUserCard()));
|
||||
|
|
@ -133,9 +137,6 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway {
|
|||
personMessageRepository.saveBatch(personMessageDOS);
|
||||
dcokDoorEquipment(userCardHashSet, stringJSONObjectHashMap);
|
||||
}
|
||||
TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent();
|
||||
todoListCompleteEvent.setForeignSubsidiaryKey(build.getId());
|
||||
todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent);
|
||||
}
|
||||
|
||||
// 对接口门设备
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public interface VehicleApplyRepository extends BaseRepository<VehicleApplyDO> {
|
|||
|
||||
PageResponse<FgsVehicleCountDto> fgsCount(HashMap<String, String> qry);
|
||||
|
||||
|
||||
PageResponse<VehicleApplyDO> getCarByVehicleBelongType(Map<String, Object> params);
|
||||
|
||||
VehicleApplyDO getInfoById(Long id);
|
||||
|
|
|
|||
Loading…
Reference in New Issue