人员区域授权相关信息

master
aosodo_4812 2026-09-03 15:41:17 +08:00
parent 7c4840cd0f
commit 7db2281517
16 changed files with 285 additions and 41 deletions

View File

@ -286,3 +286,12 @@ public class XxxJob {
- [ ] XXL-JOB 名称唯一,任务幂等,失败可被调度中心感知。
- [ ] 日志和响应未泄露人脸、证件、文件、密钥或完整敏感报文。
- [ ] 完成与改动风险匹配的 Maven 编译、测试和 `git diff` 检查。
## 13. DTO、接口文档与代码格式
- DTO、Cmd、Qry、Co 等接口对象必须使用 `@ApiModel` 标明对象用途;每个对外字段必须使用 `@ApiModelProperty` 说明字段含义、枚举取值、时间格式和必要时的必填条件。Swagger 注解不能替代 Bean Validation。
- 字段、校验注解、Swagger 注解必须按“一行一个元素”排版:注解独占行、字段独占行;字段之间保留一个空行。禁止将多个注解和字段压缩到同一行。
- 方法参数、链式调用或条件表达式超过一行时,按语义换行并保持四个空格缩进;禁止为压缩行数使用单行 `if`、单行循环或单行方法体。
- 导入按 Java 标准库、第三方库、项目内包分组,组间保留一个空行;同组内按 IDE 默认规则排序。禁止通配符导入。
- DTO 命名和分层遵循《Java开发手册黄山版DO、DTO、BO、VO 等类型缩写使用 UpperCamelCase属性和方法使用 lowerCamelCase布尔属性避免使用 `is` 前缀。
- 新增或修改接口字段时,必须同步维护 Controller Swagger 描述、对应 Co/Cmd 注解及 `OPEN-API.md` 等对外文档示例。

View File

@ -1,6 +1,7 @@
package com.zcloud.gbs.edgeguard.web;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.gbs.edgeguard.api.UserRegionPermissionServiceI;
@ -31,21 +32,36 @@ public class UserRegionPermissionController {
@ApiOperation("分页查询人员区域授权")
@GetMapping
public PageResponse<UserRegionPermissionCo> page(@Validated UserRegionPermissionPageQry qry) { return permissionService.page(qry); }
public PageResponse<UserRegionPermissionCo> page(
@Validated UserRegionPermissionPageQry qry) {
return permissionService.page(qry);
}
@ApiOperation("查询人员区域授权详情")
@GetMapping("/{id}")
public SingleResponse<UserRegionPermissionCo> detail(@PathVariable Long id) { return permissionService.getById(id); }
public SingleResponse<UserRegionPermissionCo> detail(@PathVariable Long id) {
return permissionService.getById(id);
}
@ApiOperation("新增人员区域授权")
@ApiOperation("批量新增人员区域授权")
@PostMapping
public SingleResponse<Long> add(@Validated @RequestBody UserRegionPermissionAddCmd cmd) { return permissionService.add(cmd); }
public MultiResponse<Long> add(@Validated @RequestBody UserRegionPermissionAddCmd cmd) {
return permissionService.add(cmd);
}
@ApiOperation("修改人员区域授权")
@PutMapping("/{id}")
public Response update(@PathVariable Long id, @Validated @RequestBody UserRegionPermissionUpdateCmd cmd) { return permissionService.update(id, cmd); }
public Response update(
@PathVariable Long id,
@Validated @RequestBody UserRegionPermissionUpdateCmd cmd) {
return permissionService.update(id, cmd);
}
@ApiOperation("撤销人员区域授权")
@DeleteMapping("/{id}")
public Response remove(@PathVariable Long id, @RequestParam(required = false) String revokeReason) { return permissionService.remove(id, revokeReason); }
public Response remove(
@PathVariable Long id,
@RequestParam(required = false) String revokeReason) {
return permissionService.remove(id, revokeReason);
}
}

View File

@ -1,5 +1,11 @@
package com.zcloud.gbs.edgeguard.command;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.alibaba.cola.exception.BizException;
import com.zcloud.gbs.edgeguard.domain.gateway.UserRegionPermissionGateway;
import com.zcloud.gbs.edgeguard.domain.model.RegionE;
@ -9,8 +15,6 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Component
@RequiredArgsConstructor
public class UserRegionPermissionAddExe {
@ -18,22 +22,35 @@ public class UserRegionPermissionAddExe {
private final UserRegionPermissionCommandSupport support;
@Transactional(rollbackFor = Exception.class)
public Long execute(UserRegionPermissionAddCmd cmd) {
public List<Long> execute(UserRegionPermissionAddCmd cmd) {
String type = cmd.getPermissionType().trim().toUpperCase();
String source = cmd.getAuthorizationSource().trim().toUpperCase();
support.validatePeriod(type, cmd.getEffectiveStartTime(), cmd.getEffectiveEndTime());
support.validateSource(source);
RegionE region = support.validateUserAndRegion(cmd.getUserId(), cmd.getRegionId());
support.validateNoOverlap(cmd.getUserId(), cmd.getRegionId(), cmd.getEffectiveStartTime(), cmd.getEffectiveEndTime(), null);
Set<Long> uniqueUserIds = new HashSet<>(cmd.getUserIds());
if (uniqueUserIds.size() != cmd.getUserIds().size() || uniqueUserIds.contains(null)) {
throw new BizException("被授权人员用户ID不可重复或为空");
}
Date now = new Date();
List<Long> ids = new ArrayList<>();
for (Long userId : cmd.getUserIds()) {
RegionE region = support.validateUserAndRegion(userId, cmd.getRegionId());
support.validateNoOverlap(userId, cmd.getRegionId(), cmd.getEffectiveStartTime(), cmd.getEffectiveEndTime(), null);
UserRegionPermissionE entity = new UserRegionPermissionE();
entity.setUserId(cmd.getUserId()); entity.setRegionId(cmd.getRegionId()); entity.setCorpId(region.getCorpId());
entity.setPermissionType(type); entity.setEffectiveStartTime(cmd.getEffectiveStartTime()); entity.setEffectiveEndTime(cmd.getEffectiveEndTime());
entity.setAuthorizationSource(source); entity.setSourceRefNo(cmd.getSourceRefNo());
entity.setUserId(userId);
entity.setRegionId(cmd.getRegionId());
entity.setCorpId(region.getCorpId());
entity.setPermissionType(type);
entity.setEffectiveStartTime(cmd.getEffectiveStartTime());
entity.setEffectiveEndTime(cmd.getEffectiveEndTime());
entity.setAuthorizationSource(source);
entity.setSourceRefNo(cmd.getSourceRefNo());
entity.setPermissionStatus(support.currentStatus(cmd.getEffectiveStartTime(), cmd.getEffectiveEndTime(), now));
entity.setRemarks(cmd.getRemarks());
Long id = permissionGateway.add(entity);
if (id == null) throw new BizException("新增人员区域授权失败");
return id;
ids.add(id);
}
return ids;
}
}

View File

@ -1,6 +1,7 @@
package com.zcloud.gbs.edgeguard.service;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.gbs.edgeguard.api.UserRegionPermissionServiceI;
@ -23,9 +24,29 @@ public class UserRegionPermissionServiceImpl implements UserRegionPermissionServ
private final UserRegionPermissionUpdateExe updateExe;
private final UserRegionPermissionRemoveExe removeExe;
@Override public PageResponse<UserRegionPermissionCo> page(UserRegionPermissionPageQry qry) { return queryExe.page(qry); }
@Override public SingleResponse<UserRegionPermissionCo> getById(Long id) { return queryExe.detail(id); }
@Override public SingleResponse<Long> add(UserRegionPermissionAddCmd cmd) { return SingleResponse.of(addExe.execute(cmd)); }
@Override public Response update(Long id, UserRegionPermissionUpdateCmd cmd) { updateExe.execute(id, cmd); return Response.buildSuccess(); }
@Override public Response remove(Long id, String revokeReason) { removeExe.execute(id, revokeReason); return Response.buildSuccess(); }
@Override
public PageResponse<UserRegionPermissionCo> page(UserRegionPermissionPageQry qry) {
return queryExe.page(qry);
}
@Override
public SingleResponse<UserRegionPermissionCo> getById(Long id) {
return queryExe.detail(id);
}
@Override
public MultiResponse<Long> add(UserRegionPermissionAddCmd cmd) {
return MultiResponse.of(addExe.execute(cmd));
}
@Override
public Response update(Long id, UserRegionPermissionUpdateCmd cmd) {
updateExe.execute(id, cmd);
return Response.buildSuccess();
}
@Override
public Response remove(Long id, String revokeReason) {
removeExe.execute(id, revokeReason);
return Response.buildSuccess();
}
}

View File

@ -1,6 +1,7 @@
package com.zcloud.gbs.edgeguard.api;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.gbs.edgeguard.dto.UserRegionPermissionAddCmd;
@ -10,8 +11,12 @@ import com.zcloud.gbs.edgeguard.dto.clientobject.UserRegionPermissionCo;
public interface UserRegionPermissionServiceI {
PageResponse<UserRegionPermissionCo> page(UserRegionPermissionPageQry qry);
SingleResponse<UserRegionPermissionCo> getById(Long id);
SingleResponse<Long> add(UserRegionPermissionAddCmd cmd);
MultiResponse<Long> add(UserRegionPermissionAddCmd cmd);
Response update(Long id, UserRegionPermissionUpdateCmd cmd);
Response remove(Long id, String revokeReason);
}

View File

@ -1,6 +1,7 @@
package com.zcloud.gbs.edgeguard.dto;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.constraints.DecimalMax;
@ -10,6 +11,7 @@ import java.io.Serializable;
import java.math.BigDecimal;
@Data
@ApiModel("电子围栏坐标点请求")
public class FencePointCmd implements Serializable {
@NotNull(message = "围栏点序号不能为空")
@ApiModelProperty(value = "点序号1至4", required = true)

View File

@ -3,6 +3,7 @@ package com.zcloud.gbs.edgeguard.dto;
import com.alibaba.cola.dto.Command;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -12,6 +13,7 @@ import javax.validation.constraints.Size;
import java.util.Date;
@Data
@ApiModel("开放接口接收报警请求")
@EqualsAndHashCode(callSuper = true)
public class OpenAlarmReceiveCmd extends Command {
@NotBlank(message = "报警编号不能为空")
@ -43,9 +45,12 @@ public class OpenAlarmReceiveCmd extends Command {
@ApiModelProperty(value = "海康摄像头indexCode", required = true)
private String cameraId;
@Size(max = 500, message = "报警地址长度不能超过500")
@ApiModelProperty("报警发生位置描述")
private String alarmAddress;
@Size(max = 1000, message = "报警图片地址长度不能超过1000")
@ApiModelProperty("报警截图URL禁止携带永久明文密钥")
private String alarmImageUrl;
@Size(max = 255, message = "备注长度不能超过255")
@ApiModelProperty("补充说明")
private String remarks;
}

View File

@ -2,23 +2,50 @@ package com.zcloud.gbs.edgeguard.dto;
import com.alibaba.cola.dto.Command;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("批量新增人员区域授权请求")
@EqualsAndHashCode(callSuper = true)
public class UserRegionPermissionAddCmd extends Command {
@NotNull private Long userId;
@NotNull private Long regionId;
@NotBlank @ApiModelProperty(value = "TEMPORARY 或 FIXED", required = true) private String permissionType;
@NotNull private Date effectiveStartTime;
@NotEmpty
@Size(max = 500)
@ApiModelProperty(value = "被授权人员用户ID列表单次最多500人不可重复", required = true)
private List<Long> userIds;
@NotNull
@ApiModelProperty(value = "被授权区域ID", required = true)
private Long regionId;
@NotBlank
@ApiModelProperty(value = "权限类型TEMPORARY临时/FIXED固定", required = true)
private String permissionType;
@NotNull
@ApiModelProperty(value = "权限生效开始时间格式yyyy-MM-dd HH:mm:ss", required = true)
private Date effectiveStartTime;
@ApiModelProperty("权限生效结束时间TEMPORARY时必填FIXED时不填")
private Date effectiveEndTime;
@NotBlank @ApiModelProperty(value = "MANUAL、IMPORT 或 API", required = true) private String authorizationSource;
@Size(max = 128) private String sourceRefNo;
@Size(max = 255) private String remarks;
@NotBlank
@ApiModelProperty(value = "授权来源MANUAL人工/IMPORT导入/API接口", required = true)
private String authorizationSource;
@Size(max = 128)
@ApiModelProperty("授权来源业务单号或外部流水号")
private String sourceRefNo;
@Size(max = 255)
@ApiModelProperty("备注")
private String remarks;
}

View File

@ -1,14 +1,24 @@
package com.zcloud.gbs.edgeguard.dto;
import com.alibaba.cola.dto.PageQuery;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@ApiModel("人员区域授权分页查询条件")
@EqualsAndHashCode(callSuper = true)
public class UserRegionPermissionPageQry extends PageQuery {
@ApiModelProperty("按被授权人员用户ID筛选")
private Long userId;
@ApiModelProperty("按区域ID筛选与corpId至少传一个")
private Long regionId;
@ApiModelProperty("按企业ID筛选与regionId至少传一个")
private Long corpId;
@ApiModelProperty("按权限状态筛选PENDING/ACTIVE/EXPIRED/REVOKED")
private String permissionStatus;
}

View File

@ -1,6 +1,8 @@
package com.zcloud.gbs.edgeguard.dto;
import com.alibaba.cola.dto.Command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -10,15 +12,41 @@ import javax.validation.constraints.Size;
import java.util.Date;
@Data
@ApiModel("修改人员区域授权请求")
@EqualsAndHashCode(callSuper = true)
public class UserRegionPermissionUpdateCmd extends Command {
@NotNull private Long userId;
@NotNull private Long regionId;
@NotBlank private String permissionType;
@NotNull private Date effectiveStartTime;
@NotNull
@ApiModelProperty(value = "被授权人员用户ID", required = true)
private Long userId;
@NotNull
@ApiModelProperty(value = "被授权区域ID", required = true)
private Long regionId;
@NotBlank
@ApiModelProperty(value = "权限类型TEMPORARY临时/FIXED固定", required = true)
private String permissionType;
@NotNull
@ApiModelProperty(value = "权限生效开始时间格式yyyy-MM-dd HH:mm:ss", required = true)
private Date effectiveStartTime;
@ApiModelProperty("权限生效结束时间TEMPORARY时必填FIXED时不填")
private Date effectiveEndTime;
@NotBlank private String authorizationSource;
@Size(max = 128) private String sourceRefNo;
@NotNull private Integer version;
@Size(max = 255) private String remarks;
@NotBlank
@ApiModelProperty(value = "授权来源MANUAL人工/IMPORT导入/API接口", required = true)
private String authorizationSource;
@Size(max = 128)
@ApiModelProperty("授权来源业务单号或外部流水号")
private String sourceRefNo;
@NotNull
@ApiModelProperty(value = "乐观锁版本号", required = true)
private Integer version;
@Size(max = 255)
@ApiModelProperty("备注")
private String remarks;
}

View File

@ -1,13 +1,21 @@
package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel("电子围栏坐标点")
public class FencePointCo extends ClientObject {
@ApiModelProperty("坐标点顺序从1开始")
private Integer seq;
@ApiModelProperty("经度")
private BigDecimal longitude;
@ApiModelProperty("纬度")
private BigDecimal latitude;
}

View File

@ -2,15 +2,25 @@ package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("开放接口报警接收回执")
public class OpenAlarmReceiptCo extends ClientObject {
@ApiModelProperty("平台报警记录ID")
private Long alarmId;
@ApiModelProperty("第三方报警唯一编号")
private String alarmNo;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("平台接收时间,东八区")
private Date receivedTime;
@ApiModelProperty("是否为幂等重复提交true表示复用首次保存结果")
private Boolean duplicate;
}

View File

@ -1,12 +1,22 @@
package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("开放接口摄像头信息")
public class OpenCameraCo extends ClientObject {
@ApiModelProperty("摄像头来源系统编码例如HIKVISION")
private String cameraSource;
@ApiModelProperty("第三方摄像头唯一标识")
private String cameraId;
@ApiModelProperty("摄像头名称")
private String cameraName;
@ApiModelProperty("第三方平台所属区域名称快照")
private String cameraRegionName;
}

View File

@ -1,24 +1,52 @@
package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
@ApiModel("开放接口区域及关联资源信息")
public class OpenRegionCo extends ClientObject {
@ApiModelProperty("区域ID")
private Long regionId;
@ApiModelProperty("区域稳定唯一编码")
private String regionCode;
@ApiModelProperty("区域名称")
private String regionName;
@ApiModelProperty("所属企业ID")
private Long corpId;
@ApiModelProperty("父区域ID0表示企业顶级区域")
private Long parentId;
@ApiModelProperty("祖先区域路径")
private String treePath;
@ApiModelProperty("区域树层级")
private Integer treeLevel;
@ApiModelProperty("同级排序号")
private Integer sortNo;
@ApiModelProperty("坐标系WGS84/GCJ02/BD09")
private String coordinateSystem;
@ApiModelProperty("四个有序电子围栏坐标点")
private List<FencePointCo> fencePoints = new ArrayList<>();
@ApiModelProperty("区域状态ENABLED/DISABLED")
private String regionStatus;
@ApiModelProperty("区域绑定的有效摄像头列表")
private List<OpenCameraCo> cameras = new ArrayList<>();
@ApiModelProperty("区域当前有效的授权人员列表")
private List<OpenRegionUserCo> users = new ArrayList<>();
}

View File

@ -1,16 +1,30 @@
package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("开放接口区域授权人员信息")
public class OpenRegionUserCo extends ClientObject {
@ApiModelProperty("被授权人员用户ID")
private Long userId;
@ApiModelProperty("被授权人员姓名")
private String userName;
@ApiModelProperty("权限类型TEMPORARY临时/FIXED固定")
private String permissionType;
@ApiModelProperty("权限生效开始时间")
private Date effectiveStartTime;
@ApiModelProperty("权限生效结束时间;固定权限为空")
private Date effectiveEndTime;
@ApiModelProperty("授权来源MANUAL人工/IMPORT导入/API接口")
private String authorizationSource;
}

View File

@ -1,28 +1,62 @@
package com.zcloud.gbs.edgeguard.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
@Data
@ApiModel("人员区域授权信息")
@EqualsAndHashCode(callSuper = true)
public class UserRegionPermissionCo extends ClientObject {
@ApiModelProperty("授权记录ID")
private Long id;
@ApiModelProperty("被授权人员用户ID")
private Long userId;
@ApiModelProperty("被授权人员姓名")
private String userName;
@ApiModelProperty("区域ID")
private Long regionId;
@ApiModelProperty("区域名称")
private String regionName;
@ApiModelProperty("所属企业ID")
private Long corpId;
@ApiModelProperty("权限类型TEMPORARY临时/FIXED固定")
private String permissionType;
@ApiModelProperty("权限生效开始时间")
private Date effectiveStartTime;
@ApiModelProperty("权限生效结束时间;固定权限为空")
private Date effectiveEndTime;
@ApiModelProperty("授权来源MANUAL/IMPORT/API")
private String authorizationSource;
@ApiModelProperty("来源业务单号或外部流水号")
private String sourceRefNo;
@ApiModelProperty("权限状态PENDING/ACTIVE/EXPIRED/REVOKED")
private String permissionStatus;
@ApiModelProperty("撤销时间")
private Date revokeTime;
@ApiModelProperty("撤销原因")
private String revokeReason;
@ApiModelProperty("乐观锁版本号")
private Integer version;
@ApiModelProperty("备注")
private String remarks;
}