From 2e4432e51b6e70a83b3470316eaa8df7d568f7fe Mon Sep 17 00:00:00 2001 From: lzh Date: Wed, 11 Mar 2026 17:33:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(ops):=20=E6=96=B0=E5=A2=9E=E5=AE=89?= =?UTF-8?q?=E4=BF=9D=E5=B7=A5=E5=8D=95=20Controller=20=E4=B8=8E=E5=BC=80?= =?UTF-8?q?=E6=94=BE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 包含 SecurityOrderController(创建/确认/完单/自动完单)、 SecurityAreaUserController(区域人员绑定)、 SecurityOrderOpenController(外部回调), 以及对应的 VO 和权限配置。 Co-Authored-By: Claude Opus 4.6 --- .../security/SecurityAreaUserController.java | 88 ++++++++++++++++++ .../security/SecurityOrderController.java | 93 +++++++++++++++++++ .../vo/OpsAreaSecurityUserBindReqVO.java | 33 +++++++ .../vo/OpsAreaSecurityUserRespVO.java | 41 ++++++++ .../vo/OpsAreaSecurityUserUpdateReqVO.java | 29 ++++++ .../vo/SecurityOrderAutoCompleteReqVO.java | 23 +++++ .../vo/SecurityOrderCompleteReqVO.java | 30 ++++++ .../vo/SecurityOrderConfirmReqVO.java | 24 +++++ .../security/vo/SecurityOrderCreateReqVO.java | 54 +++++++++++ .../security/SecurityOrderOpenController.java | 72 ++++++++++++++ .../config/SecurityConfiguration.java | 4 +- 11 files changed, 490 insertions(+), 1 deletion(-) create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityAreaUserController.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityOrderController.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserBindReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserRespVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserUpdateReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderAutoCompleteReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCompleteReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderConfirmReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCreateReqVO.java create mode 100644 viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/open/security/SecurityOrderOpenController.java diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityAreaUserController.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityAreaUserController.java new file mode 100644 index 0000000..1421c89 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityAreaUserController.java @@ -0,0 +1,88 @@ +package com.viewsh.module.ops.controller.admin.security; + +import com.viewsh.framework.common.pojo.CommonResult; +import com.viewsh.module.ops.controller.admin.security.vo.OpsAreaSecurityUserBindReqVO; +import com.viewsh.module.ops.controller.admin.security.vo.OpsAreaSecurityUserRespVO; +import com.viewsh.module.ops.controller.admin.security.vo.OpsAreaSecurityUserUpdateReqVO; +import com.viewsh.module.ops.security.dal.dataobject.area.OpsAreaSecurityUserDO; +import com.viewsh.module.ops.security.service.area.OpsAreaSecurityUserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.viewsh.framework.common.pojo.CommonResult.success; + +/** + * 安保区域人员绑定管理 + * + * @author lzh + */ +@Tag(name = "安保区域人员绑定") +@RestController +@RequestMapping("/ops/security/area-user") +@Validated +public class SecurityAreaUserController { + + @Resource + private OpsAreaSecurityUserService areaSecurityUserService; + + @GetMapping("/list") + @Operation(summary = "查询区域绑定的安保人员") + @PreAuthorize("@ss.hasPermission('ops:security-area-user:query')") + public CommonResult> list( + @Parameter(description = "区域ID", required = true) @RequestParam("areaId") Long areaId) { + List list = areaSecurityUserService.listByAreaId(areaId); + List result = list.stream() + .map(this::convertToRespVO) + .toList(); + return success(result); + } + + @PostMapping("/bind") + @Operation(summary = "绑定安保人员到区域") + @PreAuthorize("@ss.hasPermission('ops:security-area-user:create')") + public CommonResult bind(@Valid @RequestBody OpsAreaSecurityUserBindReqVO reqVO) { + Long id = areaSecurityUserService.bindUser( + reqVO.getAreaId(), reqVO.getUserId(), reqVO.getUserName(), + reqVO.getTeamId(), reqVO.getSort()); + return success(id); + } + + @PutMapping("/update") + @Operation(summary = "更新绑定信息") + @PreAuthorize("@ss.hasPermission('ops:security-area-user:update')") + public CommonResult update(@Valid @RequestBody OpsAreaSecurityUserUpdateReqVO reqVO) { + areaSecurityUserService.updateBinding(reqVO.getId(), reqVO.getEnabled(), reqVO.getSort(), reqVO.getTeamId()); + return success(true); + } + + @DeleteMapping("/unbind") + @Operation(summary = "解除绑定") + @PreAuthorize("@ss.hasPermission('ops:security-area-user:delete')") + public CommonResult unbind( + @Parameter(description = "绑定记录ID", required = true) @RequestParam("id") Long id) { + areaSecurityUserService.unbindUser(id); + return success(true); + } + + private OpsAreaSecurityUserRespVO convertToRespVO(OpsAreaSecurityUserDO entity) { + OpsAreaSecurityUserRespVO vo = new OpsAreaSecurityUserRespVO(); + vo.setId(entity.getId()); + vo.setAreaId(entity.getAreaId()); + vo.setUserId(entity.getUserId()); + vo.setUserName(entity.getUserName()); + vo.setTeamId(entity.getTeamId()); + vo.setEnabled(entity.getEnabled()); + vo.setSort(entity.getSort()); + vo.setCreateTime(entity.getCreateTime()); + return vo; + } + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityOrderController.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityOrderController.java new file mode 100644 index 0000000..948ccc7 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/SecurityOrderController.java @@ -0,0 +1,93 @@ +package com.viewsh.module.ops.controller.admin.security; + +import com.viewsh.framework.common.pojo.CommonResult; +import com.viewsh.framework.security.core.util.SecurityFrameworkUtils; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderAutoCompleteReqVO; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderCompleteReqVO; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderConfirmReqVO; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderCreateReqVO; +import com.viewsh.module.ops.security.service.securityorder.SecurityOrderCompleteReqDTO; +import com.viewsh.module.ops.security.service.securityorder.SecurityOrderCreateReqDTO; +import com.viewsh.module.ops.security.service.securityorder.SecurityOrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import static com.viewsh.framework.common.pojo.CommonResult.success; + +/** + * 安保工单管理(Admin) + *

+ * 后台管理端安保工单接口: + * - 创建安保工单 + * - 确认工单 + * - 自动完单 + * - 人工提交结果完单 + * + * @author lzh + */ +@Tag(name = "安保工单") +@RestController +@RequestMapping("/ops/security/order") +@Validated +public class SecurityOrderController { + + @Resource + private SecurityOrderService securityOrderService; + + @PostMapping("/create") + @Operation(summary = "创建安保工单", description = "管理端创建安保工单,传入告警信息和区域,系统自动分配安保人员") + @PreAuthorize("@ss.hasPermission('ops:security-order:create')") + public CommonResult createOrder(@Valid @RequestBody SecurityOrderCreateReqVO reqVO) { + SecurityOrderCreateReqDTO dto = SecurityOrderCreateReqDTO.builder() + .title(reqVO.getTitle()) + .description(reqVO.getDescription()) + .priority(reqVO.getPriority()) + .areaId(reqVO.getAreaId()) + .location(reqVO.getLocation()) + .alarmId(reqVO.getAlarmId()) + .alarmType(reqVO.getAlarmType()) + .cameraId(reqVO.getCameraId()) + .roiId(reqVO.getRoiId()) + .imageUrl(reqVO.getImageUrl()) + .sourceType(reqVO.getSourceType()) + .build(); + Long orderId = securityOrderService.createSecurityOrder(dto); + return success(orderId); + } + + @PostMapping("/confirm") + @Operation(summary = "确认工单", description = "安保人员确认接单") + @PreAuthorize("@ss.hasPermission('ops:security-order:confirm')") + public CommonResult confirmOrder(@Valid @RequestBody SecurityOrderConfirmReqVO reqVO) { + securityOrderService.confirmOrder(reqVO.getOrderId(), reqVO.getUserId()); + return success(true); + } + + @PostMapping("/auto-complete") + @Operation(summary = "自动完单", description = "由外部系统调用,无需提交处理结果") + @PreAuthorize("@ss.hasPermission('ops:security-order:complete')") + public CommonResult autoCompleteOrder(@Valid @RequestBody SecurityOrderAutoCompleteReqVO reqVO) { + securityOrderService.autoCompleteOrder(reqVO.getOrderId(), reqVO.getRemark()); + return success(true); + } + + @PostMapping("/manual-complete") + @Operation(summary = "人工完单", description = "安保人员提交处理结果(result + 图片)完成工单") + @PreAuthorize("@ss.hasPermission('ops:security-order:complete')") + public CommonResult manualCompleteOrder(@Valid @RequestBody SecurityOrderCompleteReqVO reqVO) { + SecurityOrderCompleteReqDTO dto = SecurityOrderCompleteReqDTO.builder() + .orderId(reqVO.getOrderId()) + .result(reqVO.getResult()) + .resultImgUrls(reqVO.getResultImgUrls()) + .operatorId(SecurityFrameworkUtils.getLoginUserId()) + .build(); + securityOrderService.manualCompleteOrder(dto); + return success(true); + } + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserBindReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserBindReqVO.java new file mode 100644 index 0000000..c5a6865 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserBindReqVO.java @@ -0,0 +1,33 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 区域安保人员绑定请求 VO + * + * @author lzh + */ +@Schema(description = "区域安保人员绑定请求") +@Data +public class OpsAreaSecurityUserBindReqVO { + + @Schema(description = "区域ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "区域ID不能为空") + private Long areaId; + + @Schema(description = "安保人员用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2001") + @NotNull(message = "用户ID不能为空") + private Long userId; + + @Schema(description = "安保人员姓名", example = "张三") + private String userName; + + @Schema(description = "班组ID", example = "10") + private Long teamId; + + @Schema(description = "排序值", example = "0") + private Integer sort; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserRespVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserRespVO.java new file mode 100644 index 0000000..d733502 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserRespVO.java @@ -0,0 +1,41 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 区域安保人员绑定响应 VO + * + * @author lzh + */ +@Schema(description = "区域安保人员绑定响应") +@Data +public class OpsAreaSecurityUserRespVO { + + @Schema(description = "绑定记录ID", example = "1") + private Long id; + + @Schema(description = "区域ID", example = "100") + private Long areaId; + + @Schema(description = "安保人员用户ID", example = "2001") + private Long userId; + + @Schema(description = "安保人员姓名", example = "张三") + private String userName; + + @Schema(description = "班组ID", example = "10") + private Long teamId; + + @Schema(description = "是否启用", example = "true") + private Boolean enabled; + + @Schema(description = "排序值", example = "0") + private Integer sort; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserUpdateReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserUpdateReqVO.java new file mode 100644 index 0000000..aff9778 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/OpsAreaSecurityUserUpdateReqVO.java @@ -0,0 +1,29 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 区域安保人员绑定更新请求 VO + * + * @author lzh + */ +@Schema(description = "区域安保人员绑定更新请求") +@Data +public class OpsAreaSecurityUserUpdateReqVO { + + @Schema(description = "绑定记录ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "绑定记录ID不能为空") + private Long id; + + @Schema(description = "是否启用", example = "true") + private Boolean enabled; + + @Schema(description = "排序值", example = "0") + private Integer sort; + + @Schema(description = "班组ID", example = "10") + private Long teamId; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderAutoCompleteReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderAutoCompleteReqVO.java new file mode 100644 index 0000000..058e6b4 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderAutoCompleteReqVO.java @@ -0,0 +1,23 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 安保工单自动完单请求 VO + * + * @author lzh + */ +@Schema(description = "安保工单自动完单请求") +@Data +public class SecurityOrderAutoCompleteReqVO { + + @Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001") + @NotNull(message = "工单ID不能为空") + private Long orderId; + + @Schema(description = "备注", example = "告警自动解除") + private String remark; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCompleteReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCompleteReqVO.java new file mode 100644 index 0000000..1d4dd0b --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCompleteReqVO.java @@ -0,0 +1,30 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * 安保工单人工完单请求 VO + * + * @author lzh + */ +@Schema(description = "安保工单人工完单请求") +@Data +public class SecurityOrderCompleteReqVO { + + @Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001") + @NotNull(message = "工单ID不能为空") + private Long orderId; + + @Schema(description = "处理结果描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "已到现场排查,系误报") + @NotBlank(message = "处理结果不能为空") + private String result; + + @Schema(description = "处理结果图片URL列表", example = "[\"https://oss.example.com/result1.jpg\"]") + private List resultImgUrls; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderConfirmReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderConfirmReqVO.java new file mode 100644 index 0000000..8e04f6a --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderConfirmReqVO.java @@ -0,0 +1,24 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 安保工单确认请求 VO + * + * @author lzh + */ +@Schema(description = "安保工单确认请求") +@Data +public class SecurityOrderConfirmReqVO { + + @Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001") + @NotNull(message = "工单ID不能为空") + private Long orderId; + + @Schema(description = "安保人员user_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2001") + @NotNull(message = "用户ID不能为空") + private Long userId; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCreateReqVO.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCreateReqVO.java new file mode 100644 index 0000000..3719314 --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/admin/security/vo/SecurityOrderCreateReqVO.java @@ -0,0 +1,54 @@ +package com.viewsh.module.ops.controller.admin.security.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 安保工单创建请求 VO + * + * @author lzh + */ +@Schema(description = "安保工单创建请求") +@Data +public class SecurityOrderCreateReqVO { + + @Schema(description = "工单标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "A栋3层入侵告警") + @NotBlank(message = "工单标题不能为空") + private String title; + + @Schema(description = "工单描述", example = "摄像头检测到异常人员入侵") + private String description; + + @Schema(description = "优先级(0=P0紧急 1=P1重要 2=P2普通)", example = "1") + private Integer priority; + + @Schema(description = "区域ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "区域ID不能为空") + private Long areaId; + + @Schema(description = "具体位置描述", example = "A栋3层东侧走廊") + private String location; + + // ==================== 告警来源 ==================== + + @Schema(description = "关联告警ID", example = "ALM20260211001") + private String alarmId; + + @Schema(description = "告警类型: intrusion/leave_post/fire/fence", example = "intrusion") + private String alarmType; + + @Schema(description = "摄像头ID", example = "CAM_001") + private String cameraId; + + @Schema(description = "ROI区域ID", example = "ROI_001") + private String roiId; + + @Schema(description = "告警截图URL", example = "https://oss.example.com/alarm/snapshot.jpg") + private String imageUrl; + + @Schema(description = "来源类型(ALARM=告警触发/MANUAL=手动创建)", example = "ALARM") + private String sourceType; + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/open/security/SecurityOrderOpenController.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/open/security/SecurityOrderOpenController.java new file mode 100644 index 0000000..fd550ca --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/controller/open/security/SecurityOrderOpenController.java @@ -0,0 +1,72 @@ +package com.viewsh.module.ops.controller.open.security; + +import com.viewsh.framework.common.pojo.CommonResult; +import com.viewsh.framework.signature.core.annotation.ApiSignature; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderAutoCompleteReqVO; +import com.viewsh.module.ops.controller.admin.security.vo.SecurityOrderCreateReqVO; +import com.viewsh.module.ops.security.service.securityorder.SecurityOrderCreateReqDTO; +import com.viewsh.module.ops.security.service.securityorder.SecurityOrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.annotation.security.PermitAll; +import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static com.viewsh.framework.common.pojo.CommonResult.success; + +/** + * 安保工单 - 开放接口 + *

+ * 提供给外部告警系统调用,通过 {@link ApiSignature} 签名验证保护, + * 不走用户登录鉴权(Token)。 + *

+ * 实际路径前缀为 /open-api,由框架自动添加 + * + * @author lzh + */ +@Tag(name = "安保工单 - 开放接口") +@RestController +@RequestMapping("/ops/security/order") +@Validated +public class SecurityOrderOpenController { + + @Resource + private SecurityOrderService securityOrderService; + + @PostMapping("/create") + @Operation(summary = "创建安保工单", description = "由外部告警系统调用,传入告警信息和区域,系统自动分配安保人员") + @ApiSignature + @PermitAll + public CommonResult createOrder(@Valid @RequestBody SecurityOrderCreateReqVO reqVO) { + SecurityOrderCreateReqDTO dto = SecurityOrderCreateReqDTO.builder() + .title(reqVO.getTitle()) + .description(reqVO.getDescription()) + .priority(reqVO.getPriority()) + .areaId(reqVO.getAreaId()) + .location(reqVO.getLocation()) + .alarmId(reqVO.getAlarmId()) + .alarmType(reqVO.getAlarmType()) + .cameraId(reqVO.getCameraId()) + .roiId(reqVO.getRoiId()) + .imageUrl(reqVO.getImageUrl()) + .sourceType(reqVO.getSourceType()) + .build(); + Long orderId = securityOrderService.createSecurityOrder(dto); + return success(orderId); + } + + @PostMapping("/auto-complete") + @Operation(summary = "自动完单", description = "由外部告警系统调用,无需提交处理结果") + @ApiSignature + @PermitAll + public CommonResult autoCompleteOrder(@Valid @RequestBody SecurityOrderAutoCompleteReqVO req) { + securityOrderService.autoCompleteOrder(req.getOrderId(), req.getRemark()); + return success(true); + } + +} diff --git a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/framework/security/config/SecurityConfiguration.java b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/framework/security/config/SecurityConfiguration.java index bd01ea6..fee3468 100644 --- a/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/framework/security/config/SecurityConfiguration.java +++ b/viewsh-module-ops/viewsh-module-ops-server/src/main/java/com/viewsh/module/ops/framework/security/config/SecurityConfiguration.java @@ -8,7 +8,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; /** - * IoT 模块的 Security 配置 + * Ops 模块的 Security 配置 */ @Configuration("opsSecurityConfiguration") public class SecurityConfiguration { @@ -31,6 +31,8 @@ public class SecurityConfiguration { registry.requestMatchers("/druid/**").anonymous(); // RPC 服务的安全配置 registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll(); + // Open API 接口放行(由 @ApiSignature 签名保护) + registry.requestMatchers(buildOpenApi("/**")).permitAll(); } };