From de642e6322e0f8e46f9ed41ac2ef9c942a1b309d Mon Sep 17 00:00:00 2001 From: dearLin <1261008090@qq.com> Date: Tue, 31 Mar 2026 15:25:14 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=8F=A3=E9=97=A8=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E5=BE=85=E5=8A=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 208 --- CLAUDE.md | 160 --- .../templates/primeport/static/package.json | 4 +- .../command/ClosedAreaCarApplyAddExe.java | 12 + .../command/ClosedAreaCarApplyUpdateExe.java | 7 + .../command/ClosedAreaPersonApplyAddExe.java | 13 + .../ClosedAreaPersonApplyUpdateExe.java | 6 + .../primeport/command/PersonApplyAddExe.java | 12 + .../command/PersonApplyUpdateExe.java | 1 + .../primeport/command/VehicleApplyAddExe.java | 11 +- .../command/VehicleApplyUpdateExe.java | 2 +- .../command/VehicleAuditUpdateExe.java | 6 + .../service/VehicleApplyServiceImpl.java | 2 +- .../gatewayimpl/PersonApplyGatewayImpl.java | 7 + .../gatewayimpl/VehicleAuditGatewayImpl.java | 1 + 口门信息管理 - 后端需求文档.md | 1273 ----------------- 16 files changed, 79 insertions(+), 1646 deletions(-) delete mode 100644 AGENTS.md delete mode 100644 CLAUDE.md delete mode 100644 口门信息管理 - 后端需求文档.md diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 98dc4cc..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,208 +0,0 @@ -# AGENTS.md - -This file provides guidance to agentic coding agents operating in this repository. - -## Project Overview - -**zcloud-gbs-primeport** - A Spring Boot application for port access control management built with COLA framework and DDD architecture. - -## Build Commands - -```bash -# Build the project -mvn clean install - -# Build without running tests -mvn clean install -DskipTests - -# Run the application -mvn spring-boot:run -pl start - -# Package for deployment -mvn clean package - -# Compile only -mvn compile -``` - -## Test Commands - -```bash -# Run all tests -mvn test - -# Run a single test class -mvn test -Dtest=ClassNameTest - -# Run a single test method -mvn test -Dtest=ClassNameTest#methodName - -# Run tests in a specific module -mvn test -pl web-app -``` - -## Code Style Guidelines - -### Architecture (COLA + DDD) - -This is a multi-module Maven project with strict layer separation: - -``` -start/ # Application entry point -web-adapter/ # Controllers (HTTP request handling) -web-client/ # DTOs + API interface definitions -web-app/ # Executors + Service implementations (business orchestration) -web-domain/ # Entities + Gateway interfaces (core business logic) -web-infrastructure/ # DOs + Mappers + Repository implementations (data persistence) -``` - -### Naming Conventions - -| Layer | Suffix | Example | -|-------|--------|---------| -| Entity | `E` | `MkmjE` | -| Data Object | `DO` | `MkmjDO` | -| Client Object | `CO` | `MkmjCO` | -| Command DTO | `Cmd` | `MkmjAddCmd`, `MkmjUpdateCmd` | -| Query DTO | `Qry` | `MkmjPageQry` | -| Service Interface | `ServiceI` | `MkmjServiceI` | -| Service Impl | `ServiceImpl` | `MkmjServiceImpl` | -| Gateway Interface | `Gateway` | `MkmjGateway` | -| Gateway Impl | `GatewayImpl` | `MkmjGatewayImpl` | -| Repository | `Repository` | `MkmjRepository` | -| Repository Impl | `RepositoryImpl` | `MkmjRepositoryImpl` | -| Mapper | `Mapper` | `MkmjMapper` | -| Add Executor | `AddExe` | `MkmjAddExe` | -| Update Executor | `UpdateExe` | `MkmjUpdateExe` | -| Remove Executor | `RemoveExe` | `MkmjRemoveExe` | -| Query Executor | `QueryExe` | `MkmjQueryExe` | -| Convertor | `CoConvertor` | `MkmjCoConvertor` | - -### Import Guidelines - -- Imports should be organized alphabetically -- Use `@AllArgsConstructor` for constructor injection (preferred over `@Autowired`) -- Example import order: -```java -import com.alibaba.cola.dto.PageResponse; -import com.zcloud.primeport.api.MkmjServiceI; -import com.zcloud.primeport.command.MkmjAddExe; -import lombok.AllArgsConstructor; -import org.springframework.stereotype.Service; -``` - -### Annotations - -- Use Lombok annotations: `@Data`, `@AllArgsConstructor`, `@NoArgsConstructor`, `@Builder`, `@RequiredArgsConstructor` -- Controller: `@RestController`, `@RequestMapping`, `@AllArgsConstructor`, `@Api` -- Service: `@Service`, `@AllArgsConstructor` -- Executor: `@Component`, `@AllArgsConstructor` -- Mapper: `@Mapper` (MyBatis) -- DO: `@Data`, `@TableName`, `@EqualsAndHashCode(callSuper = true)` - -### CQRS Pattern - -Write and read operations are separated: - -- **Write**: `XxxAddExe`, `XxxUpdateExe`, `XxxRemoveExe` in `web-app/command/` -- **Read**: `XxxQueryExe` in `web-app/command/query/` - -### Request Flow - -``` -Controller (web-adapter) - -> ServiceI (web-client) - -> ServiceImpl (web-app) - -> Executor (web-app/command) - -> Gateway (web-domain) - -> GatewayImpl -> Repository -> Mapper (web-infrastructure) -``` - -### MyBatis Plus Conventions - -1. **Non-database fields in DO**: Use `@TableField(exist = false)` -```java -@ApiModelProperty(value = "摄像头数量") -@TableField(exist = false) -private Integer videoCount; -``` - -2. **Field naming**: MyBatis Plus auto-converts snake_case to camelCase. Write SQL with underscore: -```xml -SELECT m.hg_auth_area AS hgAuthArea, m.mkmj_name AS mkmjName FROM mkmj m -``` - -3. **Default ordering**: Use `ORDER BY m.create_time DESC` or appropriate ordering in XML mappers. - -### Error Handling - -- Use `BizException` from COLA for business exceptions: -```java -if (!res) { - throw new BizException("保存失败"); -} -``` - -- Use `@Transactional(rollbackFor = Exception.class)` for transactional methods. - -### Validation - -- Use JSR-303 annotations in Cmd classes: -```java -@NotEmpty(message = "口门名称不能为空") -private String mkmjName; - -@NotNull(message = "口门级别不能为空") -private Integer mkmjLevel; -``` - -- Use `@Validated` in Controller methods: -```java -public SingleResponse add(@Validated @RequestBody MkmjAddCmd cmd) -``` - -### MapStruct Convertors - -Use MapStruct for DO to CO conversions: -```java -@Mapper(componentModel = "spring") -public interface MkmjCoConvertor { - List converDOsToCOs(List mkmjDOs); - MkmjCO converDOToCO(MkmjDO mkmjDOs); -} -``` - -### Adding New Features - -When adding a new entity, create files in this order: - -1. `web-client/dto/clientobject/XxxCO.java` -2. `web-client/dto/XxxAddCmd.java`, `XxxUpdateCmd.java`, `XxxPageQry.java` -3. `web-client/api/XxxServiceI.java` -4. `web-adapter/web/XxxController.java` -5. `web-domain/model/XxxE.java` -6. `web-domain/gateway/XxxGateway.java` -7. `web-infrastructure/dataobject/XxxDO.java` -8. `web-infrastructure/mapper/XxxMapper.java` -9. `web-infrastructure/resources/mapper/XxxDO.xml` -10. `web-infrastructure/repository/XxxRepository.java` -11. `web-infrastructure/repository/impl/XxxRepositoryImpl.java` -12. `web-infrastructure/gatewayimpl/XxxGatewayImpl.java` -13. `web-app/command/XxxAddExe.java`, `XxxUpdateExe.java`, `XxxRemoveExe.java` -14. `web-app/command/query/XxxQueryExe.java` -15. `web-app/command/convertor/XxxCoConvertor.java` -16. `web-app/service/XxxServiceImpl.java` - -### Database - -- PostgreSQL (driver version 42.6.0) -- DDL location: `web-infrastructure/src/main/resources/TableCreationDDL.sql` -- Multi-tenant support via `tenant_id` and `org_id` columns -- Soft delete via `delete_enum` column (use `'false'` for active records) - -### Response Types (COLA) - -- `Response` - Simple success/failure -- `SingleResponse` - Single object response -- `MultiResponse` - List response -- `PageResponse` - Paginated list response \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index cc8c45a..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,160 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -**zcloud-gbs-primeport** - 智慧云港-港口首进门禁管理系统 - -A Spring Boot application based on DDD (Domain-Driven Design) architecture using the COLA framework. Manages port/area access control with multi-level area management, vehicle approval, and personnel access control. - -## Build and Run - -```bash -# Build the project -mvn clean install - -# Run the application (main class: com.zcloud.primeport.Application) -mvn spring-boot:run -pl start - -# Package for deployment -mvn clean package -``` - -## DDD Architecture - -This is a COLA-based multi-module Maven project with strict layer separation: - -``` -start/ # Application entry point (main class, configuration) -web-adapter/ # Adapter layer (Controllers) - HTTP request handling -web-client/ # Client layer (DTOs + API interface definitions) -web-app/ # Application layer (Command/Query executors) - Business orchestration -web-domain/ # Domain layer (Entity + Gateway) - Core business logic -web-infrastructure/ # Infrastructure layer (DO + Mapper) - Data persistence -``` - -### Key Architecture Patterns - -**CQRS**: Read and write operations are separated -- Write operations: `XxxAddExe`, `XxxUpdateExe`, `XxxRemoveExe` in `web-app/command/` -- Read operations: `XxxQueryExe` in `web-app/command/query/` - -**Naming Conventions**: -- Entities: `XxxE` (domain entities in `web-domain`) -- DTOs: `XxxCmd` (commands), `XxxQry` (queries), `XxxCO` (client objects) -- Data Objects: `XxxDO` (database objects in `web-infrastructure`) -- Gateways: `XxxGateway` interfaces in `web-domain`, implemented in `web-infrastructure` - -**Request Flow**: -``` -Controller (web-adapter) - → ServiceI (web-client) - → ServiceImpl (web-app) - → Executor (web-app/command) - → Gateway (web-domain) - → Mapper (web-infrastructure) -``` - -## Database Schema - -Database DDL is located at: `web-infrastructure/src/main/resources/TableCreationDDL.sql` - -### Core Tables (9 main business entities) - -**门禁管理** -- `mkmj` - 门口信息管理表 (gate info: 一级/二级口门) -- `mkmj_gate` - 门口闸机表 (gate equipment) -- `mkmj_passage` - 口门门禁通道表 (passageways: 人行/车行/综合) -- `mkmj_approval_user` - 一级口门门禁审批人 -- `video` - 摄像头表 (video monitoring) - -**人员管理** -- `person_apply` - 人员申请审批信息 (personnel applications with audit workflow) -- `person_message` - 审批通过的人员信息 (approved personnel for access control sync) - -**车辆管理** -- `vehicle_apply` - 车辆申请审批信息 (vehicle applications with audit workflow) -- `vehicle_audit` - 车辆审批 -- `vehicle_message` - 审批通过的固化车辆信息 -- `vehicle_black` - 车辆黑名单管理 -- `vehicle_violations` - 车辆违规记录 - -### Key Business Concepts - -**审核状态** - audit_flag: -- 1: 审核中 -- 2: 审核通过 -- 3: 审核驳回 -- 4: 无需审批 (检查部门车辆/长期人员) - -**车辆/人员所属类型** - belong_type: -- 1: 股份员工车辆/人员 -- 2: 股份单位车辆 -- 3: 分公司员工车辆/人员 -- 4: 分公司单位车辆 -- 5: 相关方车辆 -- 6: 临时车辆/人员 -- 7: 检查部门车辆 - -**口门级别** - mkmj_level: -- 1: 一级口门 -- 2: 二级口门 - -**通道/闸机类型**: -- 1: 人行 -- 2: 车行 -- 3: 综合 - -## Configuration - -- Uses Nacos for centralized configuration -- Database: MySQL (Note: DDL shows MySQL syntax, but pom.xml has PostgreSQL driver - confirm actual DB) -- MyBatis Plus for ORM -- Main application config: `start/src/main/resources/bootstrap.yml` -- Nacos connection: `start/src/main/resources/nacos.yml` -- Multi-tenant support via `tenant_id` and `org_id` columns - -## Module Dependencies - -All modules depend on `web-client`. The `start` module only depends on `web-adapter` and pulls in transitive dependencies. - -Current git branch: `koumen` (门禁审批功能 - gate access approval) -Main branch: `master` - -## Code Generation Pattern - -When adding new features, follow the existing pattern across all layers: -1. Create CO in `web-client/src/main/java/com/zcloud/primeport/dto/clientobject/` -2. Create Cmd/Qry in `web-client/src/main/java/com/zcloud/primeport/dto/` -3. Create ServiceI in `web-client/src/main/java/com/zcloud/primeport/api/` -4. Create Controller in `web-adapter/src/main/java/com/zcloud/primeport/web/` -5. Create Entity in `web-domain/src/main/java/com/zcloud/primeport/domain/model/` -6. Create Gateway interface in `web-domain/src/main/java/com/zcloud/primeport/domain/gateway/` -7. Create DO in `web-infrastructure/src/main/java/com/zcloud/primeport/persistence/dataobject/` -8. Create Mapper in `web-infrastructure/src/main/java/com/zcloud/primeport/persistence/mapper/` -9. Create GatewayImpl in `web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/` -10. Create Executors in `web-app/src/main/java/com/zcloud/primeport/command/` -11. Create ServiceImpl in `web-app/src/main/java/com/zcloud/primeport/service/` - -## MyBatis Plus Development Conventions - -### DO (Data Object) Field Conventions - -1. **Non-database fields**: When adding a field to DO that does not exist in the database table (e.g., association query results), use `@TableField(exist = false)` annotation: - ```java - @ApiModelProperty(value = "摄像头数量") - @TableField(exist = false) - private Integer videoCount; - ``` - -2. **Field naming**: MyBatis Plus automatically converts between underscore (snake_case) and camelCase. Write SQL with underscore column names directly - no need to manually convert to camelCase: - ```xml - - SELECT m.hg_auth_area AS hgAuthArea, m.mkmj_name AS mkmjName FROM mkmj m - ``` - -3. **Default ordering**: Unless specified otherwise, order by `create_time DESC` for list/page queries: - ```xml - ORDER BY m.create_time DESC - ``` diff --git a/start/src/main/resources/templates/primeport/static/package.json b/start/src/main/resources/templates/primeport/static/package.json index d0c2fd0..80edce8 100644 --- a/start/src/main/resources/templates/primeport/static/package.json +++ b/start/src/main/resources/templates/primeport/static/package.json @@ -34,12 +34,12 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-signature-canvas": "^1.1.0-alpha.2", - "zy-react-library": "^1.2.9" + "zy-react-library": "^1.2.10" }, "devDependencies": { "@antfu/eslint-config": "^5.4.1", "@babel/plugin-proposal-decorators": "^7.19.3", - "@cqsjjb/scripts": "latest", + "@cqsjjb/scripts": "2.0.0", "@eslint-react/eslint-plugin": "^2.2.2", "cross-env": "^7.0.3", "eslint": "^9.37.0", diff --git a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyAddExe.java b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyAddExe.java index 49f45fe..47cf29a 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyAddExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyAddExe.java @@ -3,6 +3,8 @@ package com.zcloud.primeport.command; import com.alibaba.cola.dto.SingleResponse; import com.jjb.saas.framework.auth.model.SSOUser; import com.jjb.saas.framework.auth.utils.AuthContext; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.zclouduser.facade.ZcloudUserFacade; import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo; import com.zcloud.primeport.domain.enums.AuditEnum; @@ -29,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional; @AllArgsConstructor public class ClosedAreaCarApplyAddExe { private final ClosedAreaCarApplyGateway closedAreaCarApplyGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; @DubboReference private ZcloudUserFacade zcloudUserFacade; @@ -60,6 +63,15 @@ public class ClosedAreaCarApplyAddExe { 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); } diff --git a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyUpdateExe.java b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyUpdateExe.java index 6aadfb8..fd5ef1e 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaCarApplyUpdateExe.java @@ -1,6 +1,8 @@ package com.zcloud.primeport.command; import com.alibaba.cola.exception.BizException; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent; import com.zcloud.gbscommon.utils.DateUtil; import com.zcloud.primeport.domain.gateway.ClosedAreaCarApplyGateway; import com.zcloud.primeport.domain.model.ClosedAreaCarApplyE; @@ -24,6 +26,7 @@ import java.util.Date; @AllArgsConstructor public class ClosedAreaCarApplyUpdateExe { private final ClosedAreaCarApplyGateway closedAreaCarApplyGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; @Transactional(rollbackFor = Exception.class) public void execute(ClosedAreaCarApplyUpdateCmd closedAreaCarApplyUpdateCmd) { @@ -43,6 +46,10 @@ public class ClosedAreaCarApplyUpdateExe { closedAreaCarApplyE.setRefusalReason(auditCmd.getRefusalReason()); closedAreaCarApplyE.setAuditTime(DateUtil.date2Str(new Date())); closedAreaCarApplyGateway.update(closedAreaCarApplyE); + + TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent(); + todoListCompleteEvent.setForeignSubsidiaryKey(auditCmd.getId()); + todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent); } } diff --git a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyAddExe.java b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyAddExe.java index 3f6ca46..7ccc719 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyAddExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyAddExe.java @@ -3,6 +3,8 @@ package com.zcloud.primeport.command; import com.alibaba.cola.dto.SingleResponse; import com.jjb.saas.framework.auth.model.SSOUser; import com.jjb.saas.framework.auth.utils.AuthContext; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.zclouduser.facade.ZcloudUserFacade; import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo; import com.zcloud.primeport.domain.gateway.ClosedAreaPersonApplyGateway; @@ -27,6 +29,8 @@ import org.springframework.transaction.annotation.Transactional; @AllArgsConstructor public class ClosedAreaPersonApplyAddExe { private final ClosedAreaPersonApplyGateway closedAreaPersonApplyGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; + @DubboReference private ZcloudUserFacade zcloudUserFacade; @@ -54,6 +58,15 @@ public class ClosedAreaPersonApplyAddExe { 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); } diff --git a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyUpdateExe.java b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyUpdateExe.java index dafee80..9376b04 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/ClosedAreaPersonApplyUpdateExe.java @@ -1,6 +1,8 @@ package com.zcloud.primeport.command; import com.alibaba.cola.exception.BizException; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent; import com.zcloud.gbscommon.utils.DateUtil; import com.zcloud.primeport.domain.gateway.ClosedAreaFgsPersonAreaGateway; import com.zcloud.primeport.domain.gateway.ClosedAreaFgsPersonAuthGateway; @@ -33,6 +35,7 @@ public class ClosedAreaPersonApplyUpdateExe { private final ClosedAreaPersonApplyGateway closedAreaPersonApplyGateway; private final ClosedAreaFgsPersonAuthGateway areaFgsPersonAuthGateway; private final ClosedAreaFgsPersonAreaGateway areaFgsPersonAreaGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; @Transactional(rollbackFor = Exception.class) public void execute(ClosedAreaPersonApplyUpdateCmd closedAreaPersonApplyUpdateCmd) { @@ -52,6 +55,9 @@ 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); } @Transactional(rollbackFor = Exception.class) diff --git a/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyAddExe.java b/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyAddExe.java index a02cfc3..eedc9e8 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyAddExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyAddExe.java @@ -4,6 +4,8 @@ import com.alibaba.cola.dto.PageResponse; import com.alibaba.cola.dto.SingleResponse; import com.alibaba.cola.exception.BizException; import com.jjb.saas.framework.auth.utils.AuthContext; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.utils.DateUtil; import com.zcloud.primeport.domain.gateway.PersonApplyGateway; import com.zcloud.primeport.domain.gateway.XgfApplyPersonGateway; @@ -38,6 +40,7 @@ import java.util.List; public class PersonApplyAddExe { private final PersonApplyGateway personApplyGateway; private final XgfApplyPersonGateway xgfApplyPersonGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; @Transactional(rollbackFor = Exception.class) public boolean execute(PersonApplyAddCmd cmd) { @@ -72,6 +75,15 @@ 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); List personApplyList = cmd.getPersonApplyList(); // 相关方人员信息的保存 ArrayList personApplyES = new ArrayList<>(); diff --git a/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyUpdateExe.java b/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyUpdateExe.java index ca992d5..26b1ee1 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/PersonApplyUpdateExe.java @@ -50,6 +50,7 @@ public class PersonApplyUpdateExe { .reasonsRefusal(cmd.getReasonsRefusal()).build(); build.setId(cmd.getId()); personApplyGateway.xgfPersonAudit(build); + } @Transactional(rollbackFor = Exception.class) diff --git a/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyAddExe.java b/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyAddExe.java index 821c2b4..40a3b4e 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyAddExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyAddExe.java @@ -82,8 +82,17 @@ 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()); +// todoListEventPusherUtil.sendMessageAddEvent(build.getSendEventObj()); return add; } diff --git a/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyUpdateExe.java b/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyUpdateExe.java index 00f227d..209e4e0 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/VehicleApplyUpdateExe.java @@ -61,7 +61,7 @@ public class VehicleApplyUpdateExe { // 添加审批信息 vehicleAuditGateway.add(build); // 发送待审核待办 - todoListEventPusherUtil.sendMessageAddEvent(build.getSendEventObj()); +// todoListEventPusherUtil.sendMessageAddEvent(build.getSendEventObj()); if (!res) { throw new BizException("修改失败"); } diff --git a/web-app/src/main/java/com/zcloud/primeport/command/VehicleAuditUpdateExe.java b/web-app/src/main/java/com/zcloud/primeport/command/VehicleAuditUpdateExe.java index b670dd4..18f081a 100644 --- a/web-app/src/main/java/com/zcloud/primeport/command/VehicleAuditUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/primeport/command/VehicleAuditUpdateExe.java @@ -1,6 +1,8 @@ package com.zcloud.primeport.command; import com.alibaba.cola.exception.BizException; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent; import com.zcloud.gbscommon.utils.DateUtil; import com.zcloud.primeport.domain.gateway.VehicleApplyGateway; import com.zcloud.primeport.domain.gateway.VehicleAuditGateway; @@ -26,6 +28,7 @@ import java.util.Date; public class VehicleAuditUpdateExe { private final VehicleAuditGateway vehicleAuditGateway; private final VehicleApplyGateway vehicleApplyGateway; + private final TodoListEventPusherUtil todoListEventPusherUtil; @Transactional(rollbackFor = Exception.class) public void execute(VehicleAuditUpdateCmd vehicleAuditUpdateCmd) { @@ -54,6 +57,9 @@ public class VehicleAuditUpdateExe { vehicleApplyE.setStatusFlag(2); vehicleApplyGateway.update(vehicleApplyE); vehicleAuditGateway.update(vehicleAuditE); + TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent(); + todoListCompleteEvent.setForeignSubsidiaryKey(vehicleAuditE.getId()); + todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent); } } diff --git a/web-app/src/main/java/com/zcloud/primeport/service/VehicleApplyServiceImpl.java b/web-app/src/main/java/com/zcloud/primeport/service/VehicleApplyServiceImpl.java index 2d5d8fd..6deeaa2 100644 --- a/web-app/src/main/java/com/zcloud/primeport/service/VehicleApplyServiceImpl.java +++ b/web-app/src/main/java/com/zcloud/primeport/service/VehicleApplyServiceImpl.java @@ -91,7 +91,7 @@ public class VehicleApplyServiceImpl implements VehicleApplyServiceI { QueryWrapper queryBlackWrapper = new QueryWrapper<>(); queryBlackWrapper.eq("licence_no", licenceNo); queryBlackWrapper.eq("delete_enum", "false"); - if (blackRepository.count(queryBlackWrapper) == 0) { + if (blackRepository.count(queryBlackWrapper) != 0) { result.put("available", false); result.put("availableMessage", "车牌号已拉黑"); } diff --git a/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/PersonApplyGatewayImpl.java b/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/PersonApplyGatewayImpl.java index 8937ead..91bea0d 100644 --- a/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/PersonApplyGatewayImpl.java +++ b/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/PersonApplyGatewayImpl.java @@ -2,6 +2,9 @@ package com.zcloud.primeport.gatewayimpl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; +import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; +import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent; import com.zcloud.primeport.domain.gateway.PersonApplyGateway; import com.zcloud.primeport.domain.model.PersonApplyE; import com.zcloud.primeport.domain.model.XgfApplyPersonE; @@ -31,6 +34,7 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway { private final PersonApplyRepository personApplyRepository; private final XgfApplyPersonRepository xgfApplyPersonRepository; private final PersonMessageRepository personMessageRepository; + private final TodoListEventPusherUtil todoListEventPusherUtil; @Override public Boolean add(PersonApplyE personApplyE) { @@ -102,6 +106,9 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway { }); personMessageRepository.saveBatch(personMessageDOS); } + TodoListCompleteEvent todoListCompleteEvent = new TodoListCompleteEvent(); + todoListCompleteEvent.setForeignSubsidiaryKey(build.getId()); + todoListEventPusherUtil.sendMessageCompleteEvent(todoListCompleteEvent); } @Override diff --git a/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/VehicleAuditGatewayImpl.java b/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/VehicleAuditGatewayImpl.java index 015f334..eb86005 100644 --- a/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/VehicleAuditGatewayImpl.java +++ b/web-infrastructure/src/main/java/com/zcloud/primeport/gatewayimpl/VehicleAuditGatewayImpl.java @@ -27,6 +27,7 @@ public class VehicleAuditGatewayImpl implements VehicleAuditGateway { VehicleAuditDO d = new VehicleAuditDO(); BeanUtils.copyProperties(vehicleAuditE, d); vehicleAuditRepository.save(d); + vehicleAuditE.setId(d.getId()); return true; } diff --git a/口门信息管理 - 后端需求文档.md b/口门信息管理 - 后端需求文档.md deleted file mode 100644 index 7d74b20..0000000 --- a/口门信息管理 - 后端需求文档.md +++ /dev/null @@ -1,1273 +0,0 @@ -# 口门信息管理 - 后端需求文档 - -## 一、模块概述 - -### 1.1 模块名称 -口门信息管理(后端) - -### 1.2 所属模块 -监管端 → 一级口门管理 - -### 1.3 功能描述 -管理口门的基础信息,包括口门的增删改查、口门属性配置,以及口门关联的通道、闸机、摄像头设备的管理功能。 - -### 1.4 用户角色 -- 监管端超级管理员 -- 监管端系统管理员 - -### 1.5 数据表 -| 表名 | 说明 | -|------|------| -| `mkmj` | 门口信息管理表(主表) | -| `mkmj_passage` | 口门门禁通道表 | -| `mkmj_gate` | 门口闸机表 | -| `video` | 摄像头表 | - ---- - -## 二、数据字典(前端静态配置) - -以下数据字典由前端静态配置,无需后端提供接口: - -### 2.1 口门级别 (mkmj_level) -| 值 | 名称 | -|----|------| -| 1 | 一级 | -| 2 | 二级 | - -### 2.2 口门类型 (mkmj_type) -| 值 | 名称 | -|----|------| -| 1 | 人行 | -| 2 | 车行 | -| 3 | 综合 | - -### 2.3 口门状态 (mkmj_status) -| 值 | 名称 | -|----|------| -| 1 | 停用 | -| 2 | 正常 | -| 3 | 暂时管理 | - -### 2.4 所属港区 (hg_auth_area) -| 值 | 名称 | -|----|------| -| qianwan | 前湾港区 | -| dongjiakou | 董家口港区 | -| huangdao | 黄岛港区 | -| other | 其他港区 | - -### 2.5 闸机状态 (gate_status) -| 值 | 名称 | -|----|------| -| 1 | 停用 | -| 2 | 正常 | - -### 2.6 通道类型 (passage_type) -| 值 | 名称 | -|----|------| -| 1 | 人行 | -| 2 | 车行 | -| 3 | 综合 | - -### 2.7 通道状态 (passage_status) -| 值 | 名称 | -|----|------| -| 1 | 停用 | -| 2 | 正常 | - -### 2.8 摄像头类型 (video_type) -| 值 | 名称 | -|----|------| -| 1 | 移动 | -| 2 | 平台 | - -### 2.9 设备类型 (device_type) -| 值 | 名称 | -|----|------| -| 1 | 口门 | -| 2 | 闸机 | - ---- - -## 三、口门管理接口 - -### 3.1 查询口门列表 - -**接口:** `GET /api/mkmj/list` - -**描述:** 分页查询口门列表,支持条件筛选 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| page | int | 是 | 页码,默认 1 | -| pageSize | int | 是 | 每页条数,默认 20,最大 100 | -| mkmjName | String | 否 | 口门名称,模糊查询 | -| hgAuthArea | String | 否 | 所属港区编码 | -| mkmjStatus | Integer | 否 | 口门状态 | -| mkmjLevel | Integer | 否 | 口门级别 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "list": [ - { - "id": 101, - "mkmjName": "一号口门", - "hgAuthArea": "qianwan", - "hgAuthAreaName": "前湾港区", - "mkmjLevel": 1, - "mkmjType": "3", - "mkmjTypeName": "综合", - "mkmjStatus": 2, - "mkmjStatusName": "正常", - "longitude": "120.123456", - "latitude": "36.123456", - "passageCount": 5, - "gateCount": 10, - "videoCount": 8 - } - ], - "total": 50, - "page": 1, - "pageSize": 20 - } -} -``` - -**实现逻辑:** -1. 根据条件动态构建查询语句 -2. `hgAuthAreaName`、`mkmjTypeName`、`mkmjStatusName` 根据数据字典转换 -3. 仅查询 `delete_enum = 'FALSE'` 的记录 -4. passageCount、gateCount、videoCount 是统计的相关联的表统计出来的。 - ---- - -### 3.2 获取口门详情 - -**接口:** `GET /api/mkmj/detail/{id}` - -**描述:** 获取口门详细信息及关联设备统计 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 口门 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 101, - "mkmjName": "一号口门", - "hgAuthArea": "qianwan", - "hgAuthAreaName": "前湾港区", - "mkmjLevel": 1, - "mkmjLevelName": "一级", - "mkmjType": "3", - "mkmjTypeName": "综合", - "mkmjStatus": 2, - "mkmjStatusName": "正常", - "inDirectionArea": null, - "inDirectionAreaName": null, - "outDirectionArea": null, - "outDirectionAreaName": null, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00", - "updateName": "管理员", - "updateTime": "2026-03-05 14:30:00" - - } -} -``` - -**实现逻辑:** -1. 查询口门基本信息 -2. 统计关联的通道、闸机、摄像头数量(`delete_enum = 'FALSE'`) -3. 数据字典字段转换名称 - ---- - -### 3.3 新增口门 - -**接口:** `POST /api/mkmj/add` - -**描述:** 新增口门信息 - -**请求参数:** -```json -{ - "mkmjName": "一号口门", - "hgAuthArea": "qianwan", - "hgAuthAreaName": "前湾港区", - "mkmjLevel": 1, - "mkmjType": "3", - "mkmjStatus": 2, - "inDirectionArea": null, - "inDirectionAreaName": null, - "outDirectionArea": null, - "outDirectionAreaName": null, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息" -} -``` - -**请求参数说明:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| mkmjName | String | 是 | 口门名称,2-50 字符 | -| hgAuthArea | String | 是 | 所属港区编码 | -| hgAuthAreaName | String | 是 | 所属港区名称 | -| mkmjLevel | Integer | 是 | 口门级别:1-一级,2-二级 | -| mkmjType | String | 是 | 口门类型:1-人行,2-车行,3-综合 | -| mkmjStatus | Integer | 是 | 口门状态:1-停用,2-正常,3-暂时管理 | -| inDirectionArea | Long | 否 | 入方向区域 ID | -| inDirectionAreaName | String | 否 | 入方向区域名称 | -| outDirectionArea | Long | 否 | 出方向区域 ID | -| outDirectionAreaName | String | 否 | 出方向区域名称 | -| longitude | String | 是 | 经度,-180~180 | -| latitude | String | 是 | 纬度,-90~90 | -| remarks | String | 否 | 备注,≤255 字符 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 101 - } -} -``` - -**实现逻辑:** -1. 校验必填参数 - ---- - -### 3.4 编辑口门 - -**接口:** `PUT /api/mkmj/update` - -**描述:** 编辑口门信息 - -**请求参数:** -```json -{ - "id": 101, - "mkmjName": "一号口门", - "hgAuthArea": "qianwan", - "hgAuthAreaName": "前湾港区", - "mkmjLevel": 1, - "mkmjType": "3", - "mkmjStatus": 2, - "inDirectionArea": null, - "inDirectionAreaName": null, - "outDirectionArea": null, - "outDirectionAreaName": null, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "更新备注" -} -``` - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - -**实现逻辑:** -1. 校验 ID 存在性 -2. 校验口门名称唯一性(排除当前记录) -3. 校验经度、纬度范围 -4. 填充更新字段: - - `update_time` = 当前时间 - - `update_id` = 当前用户 ID - - `update_name` = 当前用户姓名 -5. 更新数据库 - ---- - -### 3.5 删除口门 - -**接口:** `DELETE /api/mkmj/delete/{id}` - -**描述:** 删除口门(软删除),同步停用关联设备 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 口门 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - -**实现逻辑:** -1. 校验 ID 存在性 -2. 检查关联数据: - - 查询关联通道数量(`mkmj_passage`,`mkmj_id = id`,`delete_enum = 'FALSE'`) - - 查询关联闸机数量(`mkmj_gate`,`mkmj_id = id`,`delete_enum = 'FALSE'`) - - 查询关联摄像头数量(`video`,`foreign_id = id`,`device_type = 1`,`delete_enum = 'FALSE'`) - - 查询关联审批人数量(`mkmj_approval_user`,`mkmj_id = id`,`delete_enum = 'FALSE'`) -3. 如存在关联数据,返回错误码 `2002` 及关联详情 -4. 执行软删除:`update mkmj set delete_enum = 'TRUE' where id = ?` -5. 同步停用关联的通道、闸机、摄像头(更新 `delete_enum = 'TRUE'`) -6. 记录操作日志 - -**错误响应(有关联数据时):** -```json -{ - "code": 2002, - "message": "该口门下有关联数据,无法删除", - "data": { - "passageCount": 5, - "gateCount": 10, - "videoCount": 8, - "approvalUserCount": 3 - } -} -``` - ---- - -### 3.6 口门名称唯一性校验 - -**接口:** `GET /api/mkmj/check-name` - -**描述:** 校验口门名称是否重复 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| mkmjName | String | 是 | 口门名称 | -| id | Long | 否 | 当前口门 ID(编辑时传) | - -**响应数据:** -```json -{ - "code": 200, - "data": { - "available": true - } -} -``` - -**实现逻辑:** -1. 查询 `mkmj` 表,条件:`mkmjName = ?` AND `delete_enum = 'FALSE'` -2. 如传入 `id`,则排除该记录:`AND id != ?` -3. 查询结果为空则 `available = true`,否则 `available = false` - ---- - -## 四、通道管理接口 - -### 4.1 查询通道列表 - -**接口:** `GET /api/mkmj/passage/list` - -**描述:** 分页查询通道列表,支持按口门筛选 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| page | int | 是 | 页码,默认 1 | -| pageSize | int | 是 | 每页条数,默认 20 | -| mkmjId | Long | 否 | 口门 ID | -| passageName | String | 否 | 通道名称,模糊查询 | -| passageType | Integer | 否 | 通道类型 | -| passageStatus | Integer | 否 | 通道状态 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "list": [ - { - "id": 1001, - "mkmjId": 101, - "mkmjName": "一号口门", - "passageName": "A 通道", - "passageType": 1, - "passageTypeName": "人行", - "passageStatus": 2, - "passageStatusName": "正常", - "longitude": "120.123456", - "latitude": "36.123456", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00" - } - ], - "total": 50, - "page": 1, - "pageSize": 20 - } -} -``` - ---- - -### 4.2 获取通道详情 - -**接口:** `GET /api/mkmj/passage/detail/{id}` - -**描述:** 获取通道详细信息 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 通道 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 1001, - "mkmjId": 101, - "mkmjName": "一号口门", - "passageName": "A 通道", - "passageType": 1, - "passageTypeName": "人行", - "passageStatus": 2, - "passageStatusName": "正常", - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00", - "updateName": "管理员", - "updateTime": "2026-03-05 14:30:00" - } -} -``` - ---- - -### 4.3 新增通道 - -**接口:** `POST /api/mkmj/passage/add` - -**描述:** 新增通道信息 - -**请求参数:** -```json -{ - "mkmjId": 101, - "passageName": "A 通道", - "passageType": 1, - "passageStatus": 2, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息" -} -``` - -**请求参数说明:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| mkmjId | Long | 是 | 所属口门 ID | -| passageName | String | 是 | 通道名称,2-50 字符 | -| passageType | Integer | 是 | 通道类型:1-人行,2-车行,3-综合 | -| passageStatus | Integer | 是 | 通道状态:1-停用,2-正常 | -| longitude | String | 否 | 经度 | -| latitude | String | 否 | 纬度 | -| remarks | String | 否 | 备注,≤255 字符 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 1001 - } -} -``` - -**实现逻辑:** -1. 校验必填参数 -2. 校验口门 ID 存在性(`mkmj` 表,`delete_enum = 'FALSE'`) -3. 校验通道名称在同一口门下唯一 -4. 填充公共字段 -5. 插入数据库 - ---- - -### 4.4 编辑通道 - -**接口:** `PUT /api/mkmj/passage/update` - -**描述:** 编辑通道信息 - -**请求参数:** -```json -{ - "id": 1001, - "mkmjId": 101, - "passageName": "A 通道", - "passageType": 1, - "passageStatus": 2, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "更新备注" -} -``` - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - ---- - -### 4.5 删除通道 - -**接口:** `DELETE /api/mkmj/passage/delete/{id}` - -**描述:** 删除通道(软删除),同步停用关联闸机 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 通道 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - -**实现逻辑:** -1. 校验 ID 存在性 -2. 检查关联的闸机数量(`mkmj_gate`,`passage_id = id`,`delete_enum = 'FALSE'`) -3. 如存在关联闸机,返回错误 -4. 执行软删除 -5. 同步停用关联的闸机 - ---- - -### 4.6 按口门查询通道列表(简化版) - -**接口:** `GET /api/mkmj/passage/by-mkmj/{mkmjId}` - -**描述:** 获取指定口门下的所有通道(用于下拉选择) - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| mkmjId | Long | 口门 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "id": 1001, - "passageName": "A 通道", - "passageType": 1, - "passageTypeName": "人行" - }, - { - "id": 1002, - "passageName": "B 通道", - "passageType": 2, - "passageTypeName": "车行" - } - ] -} -``` - ---- - -## 五、闸机管理接口 - -### 5.1 查询闸机列表 - -**接口:** `GET /api/mkmj/gate/list` - -**描述:** 分页查询闸机列表,支持按口门、通道筛选 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| page | int | 是 | 页码,默认 1 | -| pageSize | int | 是 | 每页条数,默认 20 | -| mkmjId | Long | 否 | 口门 ID | -| passageId | String | 否 | 通道 ID | -| gateName | String | 否 | 闸机名称,模糊查询 | -| gateType | String | 否 | 闸机类型 | -| gateStatus | Integer | 否 | 闸机状态 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "list": [ - { - "id": 2001, - "mkmjId": 101, - "mkmjName": "一号口门", - "passageId": "1001", - "passageName": "A 通道", - "gateNumber": "GATE-001", - "gateName": "1 号闸机", - "gateType": "1", - "gateTypeName": "人行闸机", - "gateStatus": 2, - "gateStatusName": "正常", - "gateCategory": "tripod", - "gateCategoryName": "三辊闸", - "gateModel": "ZK-100", - "gatePosition": "入口处", - "longitude": "120.123456", - "latitude": "36.123456", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00" - } - ], - "total": 100, - "page": 1, - "pageSize": 20 - } -} -``` - ---- - -### 5.2 获取闸机详情 - -**接口:** `GET /api/mkmj/gate/detail/{id}` - -**描述:** 获取闸机详细信息 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 闸机 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 2001, - "mkmjId": 101, - "mkmjName": "一号口门", - "passageId": "1001", - "passageName": "A 通道", - "gateNumber": "GATE-001", - "gateName": "1 号闸机", - "gateType": "1", - "gateTypeName": "人行闸机", - "gateStatus": 2, - "gateStatusName": "正常", - "gateCategory": "tripod", - "gateCategoryName": "三辊闸", - "gateModel": "ZK-100", - "gatePosition": "入口处", - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00", - "updateName": "管理员", - "updateTime": "2026-03-05 14:30:00" - } -} -``` - ---- - -### 5.3 新增闸机 - -**接口:** `POST /api/mkmj/gate/add` - -**描述:** 新增闸机信息 - -**请求参数:** -```json -{ - "mkmjId": 101, - "passageId": "1001", - "gateNumber": "GATE-001", - "gateName": "1 号闸机", - "gateType": "1", - "gateStatus": 2, - "gateCategory": "tripod", - "gateCategoryName": "三辊闸", - "gateModel": "ZK-100", - "gatePosition": "入口处", - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息" -} -``` - -**请求参数说明:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| mkmjId | Long | 是 | 所属口门 ID | -| passageId | String | 是 | 所属通道 ID | -| gateNumber | String | 是 | 闸机标识,唯一 | -| gateName | String | 是 | 闸机名称,2-50 字符 | -| gateType | String | 是 | 闸机类型 | -| gateStatus | Integer | 是 | 闸机状态:1-停用,2-正常 | -| gateCategory | String | 否 | 闸机类别编码 | -| gateCategoryName | String | 否 | 闸机类别名称 | -| gateModel | String | 否 | 闸机型号,≤255 字符 | -| gatePosition | String | 否 | 闸机位置,≤255 字符 | -| longitude | String | 否 | 经度 | -| latitude | String | 否 | 纬度 | -| remarks | String | 否 | 备注,≤255 字符 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 2001 - } -} -``` - -**实现逻辑:** -1. 校验必填参数 -2. 校验口门 ID 存在性 -3. 校验通道 ID 存在性(且属于该口门) -4. 校验闸机标识唯一性(`gateNumber`) -5. 填充公共字段 -6. 插入数据库 - ---- - -### 5.4 编辑闸机 - -**接口:** `PUT /api/mkmj/gate/update` - -**描述:** 编辑闸机信息 - -**请求参数:** -```json -{ - "id": 2001, - "mkmjId": 101, - "passageId": "1001", - "gateNumber": "GATE-001", - "gateName": "1 号闸机", - "gateType": "1", - "gateStatus": 2, - "gateCategory": "tripod", - "gateCategoryName": "三辊闸", - "gateModel": "ZK-100", - "gatePosition": "入口处", - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "更新备注" -} -``` - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - ---- - -### 5.5 删除闸机 - -**接口:** `DELETE /api/mkmj/gate/delete/{id}` - -**描述:** 删除闸机(软删除),同步停用关联摄像头 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 闸机 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - -**实现逻辑:** -1. 校验 ID 存在性 -2. 检查关联的摄像头数量(`video`,`foreign_id = id`,`device_type = 2`,`delete_enum = 'FALSE'`) -3. 如存在关联摄像头,返回错误 -4. 执行软删除 -5. 同步停用关联的摄像头 - ---- - -### 5.6 闸机标识唯一性校验 - -**接口:** `GET /api/mkmj/gate/check-number` - -**描述:** 校验闸机标识是否重复 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| gateNumber | String | 是 | 闸机标识 | -| id | Long | 否 | 当前闸机 ID(编辑时传) | - -**响应数据:** -```json -{ - "code": 200, - "data": { - "available": true - } -} -``` - ---- - -### 5.7 按口门/通道查询闸机列表(简化版) - -**接口:** `GET /api/mkmj/gate/by-passage` - -**描述:** 获取指定通道下的所有闸机(用于下拉选择) - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| passageId | String | 是 | 通道 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "id": 2001, - "gateNumber": "GATE-001", - "gateName": "1 号闸机", - "gateType": "1", - "gateTypeName": "人行闸机" - }, - { - "id": 2002, - "gateNumber": "GATE-002", - "gateName": "2 号闸机", - "gateType": "1", - "gateTypeName": "人行闸机" - } - ] -} -``` - ---- - -## 六、摄像头管理接口 - -### 6.1 查询摄像头列表 - -**接口:** `GET /api/mkmj/video/list` - -**描述:** 分页查询摄像头列表,支持按口门、闸机筛选 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| page | int | 是 | 页码,默认 1 | -| pageSize | int | 是 | 每页条数,默认 20 | -| foreignId | Long | 否 | 关联 ID(口门 ID 或闸机 ID) | -| deviceType | Integer | 否 | 设备类型:1-口门,2-闸机 | -| videoResourceName | String | 否 | 摄像头名称,模糊查询 | -| videoType | Integer | 否 | 摄像头类型 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "list": [ - { - "id": 3001, - "foreignId": 101, - "deviceType": 1, - "deviceTypeName": "口门", - "videoResourceId": "CAM-001", - "videoResourceName": "1 号口门摄像头", - "videoType": 2, - "videoTypeName": "平台", - "longitude": "120.123456", - "latitude": "36.123456", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00" - } - ], - "total": 200, - "page": 1, - "pageSize": 20 - } -} -``` - ---- - -### 6.2 获取摄像头详情 - -**接口:** `GET /api/mkmj/video/detail/{id}` - -**描述:** 获取摄像头详细信息 - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 摄像头 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 3001, - "foreignId": 101, - "deviceType": 1, - "deviceTypeName": "口门", - "mkmjName": "一号口门", - "gateName": null, - "videoResourceId": "CAM-001", - "videoResourceName": "1 号口门摄像头", - "videoType": 2, - "videoTypeName": "平台", - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息", - "createName": "管理员", - "createTime": "2026-03-01 10:00:00", - "updateName": "管理员", - "updateTime": "2026-03-05 14:30:00" - } -} -``` - ---- - -### 6.3 新增摄像头 - -**接口:** `POST /api/mkmj/video/add` - -**描述:** 新增摄像头信息 - -**请求参数:** -```json -{ - "foreignId": 101, - "deviceType": 1, - "videoResourceId": "CAM-001", - "videoResourceName": "1 号口门摄像头", - "videoType": 2, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "备注信息" -} -``` - -**请求参数说明:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| foreignId | Long | 是 | 关联 ID(口门 ID 或闸机 ID) | -| deviceType | Integer | 是 | 设备类型:1-口门,2-闸机 | -| videoResourceId | String | 是 | 摄像头 ID,唯一 | -| videoResourceName | String | 是 | 摄像头名称,2-50 字符 | -| videoType | Integer | 是 | 摄像头类型:1-移动,2-平台 | -| longitude | String | 否 | 经度 | -| latitude | String | 否 | 纬度 | -| remarks | String | 否 | 备注,≤255 字符 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": { - "id": 3001 - } -} -``` - -**实现逻辑:** -1. 校验必填参数 -2. 校验关联 ID 存在性(根据 `deviceType` 查询 `mkmj` 或 `mkmj_gate` 表) -3. 校验摄像头 ID 唯一性(`videoResourceId`) -4. 填充公共字段 -5. 插入数据库 - ---- - -### 6.4 编辑摄像头 - -**接口:** `PUT /api/mkmj/video/update` - -**描述:** 编辑摄像头信息 - -**请求参数:** -```json -{ - "id": 3001, - "foreignId": 101, - "deviceType": 1, - "videoResourceId": "CAM-001", - "videoResourceName": "1 号口门摄像头", - "videoType": 2, - "longitude": "120.123456", - "latitude": "36.123456", - "remarks": "更新备注" -} -``` - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - ---- - -### 6.5 删除摄像头 - -**接口:** `DELETE /api/mkmj/video/delete/{id}` - -**描述:** 删除摄像头(软删除) - -**路径参数:** -| 参数名 | 类型 | 说明 | -|--------|------|------| -| id | Long | 摄像头 ID | - -**响应数据:** -```json -{ - "code": 200, - "message": "success" -} -``` - -**实现逻辑:** -1. 校验 ID 存在性 -2. 执行软删除:`update video set delete_enum = 'TRUE' where id = ?` - ---- - -### 6.6 摄像头 ID 唯一性校验 - -**接口:** `GET /api/mkmj/video/check-id` - -**描述:** 校验摄像头 ID 是否重复 - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| videoResourceId | String | 是 | 摄像头 ID | -| id | Long | 否 | 当前摄像头 ID(编辑时传) | - -**响应数据:** -```json -{ - "code": 200, - "data": { - "available": true - } -} -``` - ---- - -### 6.7 按设备查询摄像头列表(简化版) - -**接口:** `GET /api/mkmj/video/by-device` - -**描述:** 获取指定设备下的所有摄像头(用于展示或下拉选择) - -**请求参数:** -| 参数名 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| foreignId | Long | 是 | 关联 ID(口门 ID 或闸机 ID) | -| deviceType | Integer | 是 | 设备类型:1-口门,2-闸机 | - -**响应数据:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "id": 3001, - "videoResourceId": "CAM-001", - "videoResourceName": "1 号摄像头", - "videoType": 2, - "videoTypeName": "平台" - }, - { - "id": 3002, - "videoResourceId": "CAM-002", - "videoResourceName": "2 号摄像头", - "videoType": 2, - "videoTypeName": "平台" - } - ] -} -``` - ---- - -## 七、数据校验规则 - -### 7.1 通用校验 -| 字段 | 规则 | 错误码 | 错误提示 | -|------|------|--------|----------| -| 名称类字段 | 必填,2-50 字符 | 400 | 名称长度为 2-50 个字符 | -| 备注 | ≤255 字符 | 400 | 备注长度不能超过 255 字符 | -| 经度 | -180~180,支持小数 | 400 | 请输入有效的经度(-180~180) | -| 纬度 | -90~90,支持小数 | 400 | 请输入有效的纬度(-90~90) | - -### 7.2 口门校验 -| 字段 | 规则 | 错误码 | 错误提示 | -|------|------|--------|----------| -| mkmjName | 唯一性 | 2001 | 该口门名称已存在 | -| mkmjLevel | 固定值校验 | 400 | 口门级别无效 | -| hgAuthArea | 有效性 | 400 | 所属港区无效 | - -### 7.3 通道校验 -| 字段 | 规则 | 错误码 | 错误提示 | -|------|------|--------|----------| -| mkmjId | 存在性 | 2003 | 所属口门不存在 | -| passageName | 同口门下唯一 | 2004 | 该口门下通道名称已存在 | - -### 7.4 闸机校验 -| 字段 | 规则 | 错误码 | 错误提示 | -|------|------|--------|----------| -| mkmjId | 存在性 | 2003 | 所属口门不存在 | -| passageId | 存在性且属于该口门 | 2005 | 所属通道不存在或不属于该口门 | -| gateNumber | 唯一性 | 2006 | 该闸机标识已存在 | - -### 7.5 摄像头校验 -| 字段 | 规则 | 错误码 | 错误提示 | -|------|------|--------|----------| -| foreignId | 存在性(根据 deviceType) | 2007 | 关联设备不存在 | -| videoResourceId | 唯一性 | 2008 | 该摄像头 ID 已存在 | - ---- - -## 八、删除关联检查逻辑 - -### 8.1 删除口门检查 -```sql --- 检查关联通道 -SELECT COUNT(*) FROM mkmj_passage WHERE mkmj_id = ? AND delete_enum = 'FALSE'; - --- 检查关联闸机 -SELECT COUNT(*) FROM mkmj_gate WHERE mkmj_id = ? AND delete_enum = 'FALSE'; - --- 检查关联摄像头(口门类) -SELECT COUNT(*) FROM video WHERE foreign_id = ? AND device_type = 1 AND delete_enum = 'FALSE'; - --- 检查关联审批人 -SELECT COUNT(*) FROM mkmj_approval_user WHERE mkmj_id = ? AND delete_enum = 'FALSE'; -``` - -### 8.2 删除通道检查 -```sql --- 检查关联闸机 -SELECT COUNT(*) FROM mkmj_gate WHERE passage_id = ? AND delete_enum = 'FALSE'; -``` - -### 8.3 删除闸机检查 -```sql --- 检查关联摄像头(闸机类) -SELECT COUNT(*) FROM video WHERE foreign_id = ? AND device_type = 2 AND delete_enum = 'FALSE'; -``` - ---- - -## 九、错误码定义 - ---- - -## 十、公共字段处理 - -### 10.1 查询条件 -所有列表查询必须附加条件:`delete_enum = 'FALSE'` - ---- - -## 十一、实现注意事项 - -### 11.1 事务处理 -- 新增、编辑、删除操作需使用事务 -- 删除口门时,同步停用关联数据需在同一事务中完成 - -### 11.2 级联删除 -- 删除口门 → 停用通道、闸机、摄像头、审批人 -- 删除通道 → 停用闸机 -- 删除闸机 → 停用摄像头 - -### 11.4 性能优化 -- 列表查询使用分页 - -### 11.5 日志记录 -- 关键操作(新增、编辑、删除)记录操作日志 -- 日志内容:操作人、操作时间、操作类型、操作对象 ID、变更内容 - ---- - -## 十二、附录 - -### 12.1 相关文档 - - -### 12.2 表结构参考 -- `mkmj` - 门口信息管理表 -- `mkmj_passage` - 口门门禁通道表 -- `mkmj_gate` - 门口闸机表 -- `video` - 摄像头表 - ---- - -**文档版本:** V1.0 -**最后更新:** 2026-03-09