From ac709e77e65240415ef3e48731570867bfda664f Mon Sep 17 00:00:00 2001 From: zjf <1799650030@qq.com> Date: Tue, 3 Jun 2025 16:10:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=98=89=E5=85=B4=E8=AE=BF=E5=AE=A2=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/visitor/app/VisitorsAppPageVo.java | 4 + .../vo/visitor/app/VisitorsAppVo.java | 9 + .../vo/visitor/app/VisitorsPeopleAppVo.java | 7 + .../service/impl/VisitorsServiceImpl.java | 27 +- .../api/feign/RemoterVisitorService.java | 98 +++ .../thirdparty/dto/face/AddFaceRequest.java | 23 + .../thirdparty/dto/face/AddFaceResponse.java | 44 + .../dto/face/DeleteFaceRequest.java | 18 + .../dto/face/DeleteFaceResponse.java | 25 + .../dto/face/UpdateFaceRequest.java | 24 + .../dto/person/AddPersonRequest.java | 95 +++ .../dto/person/AddPersonResponse.java | 38 + .../dto/person/BatchAddPersonRequest.java | 29 + .../dto/person/BatchAddPersonResponse.java | 73 ++ .../dto/person/BatchDeletePersonRequest.java | 20 + .../dto/person/BatchDeletePersonResponse.java | 45 ++ .../dto/person/GetPersonInfoRequest.java | 34 + .../dto/person/GetPersonInfoResponse.java | 328 ++++++++ .../dto/person/GetPersonListRequest.java | 32 + .../dto/person/GetPersonListResponse.java | 145 ++++ .../dto/person/UpdatePersonRequest.java | 81 ++ .../dto/person/UpdatePersonResponse.java | 25 + .../thirdparty/dto/visitor/PersonInfo.java | 2 +- .../controller/VisitorController.java | 158 ++++ .../thirdparty/service/VisitorService.java | 756 ++++++++++++++++++ .../src/main/resources/application.yml | 2 +- .../admin/controller/SysUserController.java | 29 + 27 files changed, 2166 insertions(+), 5 deletions(-) create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/UpdateFaceRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListResponse.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonRequest.java create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonResponse.java diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppPageVo.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppPageVo.java index 2ac800404..6a4f81c25 100644 --- a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppPageVo.java +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppPageVo.java @@ -88,4 +88,8 @@ public class VisitorsAppPageVo { @Schema(description="token") private String token; + + @Schema(description="类型") + private String type; + } \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppVo.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppVo.java index 2f1d6484b..00f539389 100644 --- a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppVo.java +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsAppVo.java @@ -133,4 +133,13 @@ public class VisitorsAppVo{ @Schema(description="随行人员信息") private List visitorsPeopleAppVos; + + @Schema(description="二维码") + private String qrcode; + + + @Schema(description="验证码") + private String verificationCode; + + } \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsPeopleAppVo.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsPeopleAppVo.java index 570ea2752..a7e12026d 100644 --- a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsPeopleAppVo.java +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/vo/visitor/app/VisitorsPeopleAppVo.java @@ -22,4 +22,11 @@ public class VisitorsPeopleAppVo { private String mobile; + @Schema(description="二维码") + private String qrcode; + + + @Schema(description="验证码") + private String verificationCode; + } \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/VisitorsServiceImpl.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/VisitorsServiceImpl.java index dcac4c345..d410a2a5e 100644 --- a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/VisitorsServiceImpl.java +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/VisitorsServiceImpl.java @@ -11,6 +11,7 @@ import com.bsd.pjcloud.common.core.util.BeanUtils; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.core.util.TimeUtils; import com.bsd.pjcloud.common.data.datascope.DataScope; +import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.flow.task.api.feign.RemoteFlowApiFlowService; import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum; @@ -186,6 +187,14 @@ public class VisitorsServiceImpl extends ServiceImpl visitorsCarEntities = visitorsCarMapper.selectList(new LambdaQueryWrapper().eq(VisitorsCarEntity::getVisitorsId, visitors.getId())); if (!CollectionUtils.isEmpty(visitorsCarEntities)){ @@ -196,6 +205,15 @@ public class VisitorsServiceImpl extends ServiceImpl().eq(VisitorsPeopleEntity::getVisitorsId, visitors.getId())); if (!CollectionUtils.isEmpty(visitorsPeopleEntities)){ List visitorsPeopleAppVos = BeanUtils.toBean(visitorsPeopleEntities, VisitorsPeopleAppVo.class); + + // 对于其他访客,同样只有审核通过时才携带qrcode信息 + if (!TaskCheckStatusEnum.RESULT.getCode().equals(visitors.getCheckStatus())) { + visitorsPeopleAppVos.forEach(peopleVo -> { + peopleVo.setQrcode(null); + peopleVo.setVerificationCode(null); + }); + } + bean.setVisitorsPeopleAppVos(visitorsPeopleAppVos); } @@ -218,12 +236,14 @@ public class VisitorsServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>(); wrapper.eq(VisitorsEntity::getUserId, userId); wrapper.eq(StringUtils.isNotBlank(visitors.getCheckStatus()),VisitorsEntity::getCheckStatus, visitors.getCheckStatus()); -// wrapper.eq(VisitorsEntity::getType, VisitorTypeEnum.ZDYQ.getType()); + wrapper.eq(VisitorsEntity::getType, visitors.getType()); + wrapper.orderByDesc(VisitorsEntity::getCreateTime); Page pageData = baseMapper.selectPage(page, wrapper); List records = pageData.getRecords(); diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/api/feign/RemoterVisitorService.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/api/feign/RemoterVisitorService.java index 2ad10b791..266bcbbca 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/api/feign/RemoterVisitorService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/api/feign/RemoterVisitorService.java @@ -27,6 +27,23 @@ import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.RegisterAppointmentRe import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentRequest; import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.AppointmentData; import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.RegisterAppointmentResponse; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.face.UpdateFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoResponse; import io.swagger.v3.oas.annotations.Operation; import jakarta.validation.Valid; import org.springframework.cloud.openfeign.FeignClient; @@ -73,4 +90,85 @@ public interface RemoterVisitorService { */ @PostMapping("/visitors/checkout") public R checkOut(@Valid @RequestBody CheckOutRequest request); + + /** + * 添加人员信息v2 + * @param request 添加人员请求参数 + * @return 添加人员响应结果 + */ + @PostMapping("/person/add") + @Operation(summary = "添加人员信息v2", description = "添加人员信息到海康平台") + public R addPersonV2(@Valid @RequestBody AddPersonRequest request); + + /** + * 批量添加人员信息v1 + * @param request 批量添加人员请求参数 + * @return 批量添加人员响应结果 + */ + @PostMapping("/person/batch-add") + @Operation(summary = "批量添加人员信息v1", description = "批量添加人员信息到海康平台") + public R batchAddPersonV1(@Valid @RequestBody BatchAddPersonRequest request); + + /** + * 修改人员信息v1 + * @param request 修改人员请求参数 + * @return 修改人员响应结果 + */ + @PostMapping("/person/update") + @Operation(summary = "修改人员信息v1", description = "修改海康平台人员信息") + public R updatePersonV1(@Valid @RequestBody UpdatePersonRequest request); + + /** + * 批量删除人员信息v1 + * @param request 批量删除人员请求参数 + * @return 批量删除人员响应结果 + */ + @PostMapping("/person/batch-delete") + @Operation(summary = "批量删除人员信息v1", description = "批量删除海康平台人员信息") + public R batchDeletePersonV1(@Valid @RequestBody BatchDeletePersonRequest request); + + /** + * 添加人脸信息v1 + * @param request 添加人脸请求参数 + * @return 添加人脸响应结果 + */ + @PostMapping("/face/add") + @Operation(summary = "添加人脸信息v1", description = "添加人脸信息到海康平台") + public R addFaceV1(@Valid @RequestBody AddFaceRequest request); + + /** + * 修改人脸信息v1 + * @param request 修改人脸请求参数 + * @return 修改人脸响应结果 + */ + @PostMapping("/face/update") + @Operation(summary = "修改人脸信息v1", description = "修改海康平台人脸信息") + public R updateFaceV1(@Valid @RequestBody UpdateFaceRequest request); + + /** + * 删除人脸信息v1 + * @param request 删除人脸请求参数 + * @return 删除人脸响应结果 + */ + @PostMapping("/face/delete") + @Operation(summary = "删除人脸信息v1", description = "删除海康平台人脸信息") + public R deleteFaceV1(@Valid @RequestBody DeleteFaceRequest request); + + /** + * 获取组织下人员列表v2 + * @param request 获取人员列表请求参数 + * @return 获取人员列表响应结果 + */ + @PostMapping("/person/list") + @Operation(summary = "获取组织下人员列表v2", description = "根据组织编号获取组织下的人员信息列表") + public R getPersonListV2(@Valid @RequestBody GetPersonListRequest request); + + /** + * 根据人员唯一字段获取人员详细信息v1 + * @param request 获取人员详细信息请求参数 + * @return 获取人员详细信息响应结果 + */ + @PostMapping("/person/detail") + @Operation(summary = "根据人员唯一字段获取人员详细信息v1", description = "根据实名标识精确查询人员详细信息") + public R getPersonInfoV1(@Valid @RequestBody GetPersonInfoRequest request); } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceRequest.java new file mode 100644 index 000000000..2edfd487f --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceRequest.java @@ -0,0 +1,23 @@ +package com.bsd.pjcloud.thirdparty.dto.face; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; + +/** + * 添加人脸请求DTO + */ +@Data +public class AddFaceRequest { + + /** + * 人员Id,必填 + */ + @NotBlank(message = "人员ID不能为空") + private String personId; + + /** + * 人脸图片base64编码后的字符数据,必填 + */ + @NotBlank(message = "人脸图片数据不能为空") + private String faceData; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceResponse.java new file mode 100644 index 000000000..5368576af --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/AddFaceResponse.java @@ -0,0 +1,44 @@ +package com.bsd.pjcloud.thirdparty.dto.face; + +import lombok.Data; + +/** + * 添加人脸响应VO + */ +@Data +public class AddFaceResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回说明 + */ + private String msg; + + /** + * 返回数据 + */ + private FaceData data; + + @Data + public static class FaceData { + + /** + * 人脸Id + */ + private String faceId; + + /** + * 人脸图片Url + */ + private String faceUrl; + + /** + * 人员ID + */ + private String personId; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceRequest.java new file mode 100644 index 000000000..1538fe73a --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceRequest.java @@ -0,0 +1,18 @@ +package com.bsd.pjcloud.thirdparty.dto.face; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; + +/** + * 删除人脸请求DTO + */ +@Data +public class DeleteFaceRequest { + + /** + * 人脸图片Id,必填 + * 添加人脸接口返回报文中的faceId字段,或获取人员列表v2接口返回报文中的personPhotoIndexCode字段 + */ + @NotBlank(message = "人脸ID不能为空") + private String faceId; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceResponse.java new file mode 100644 index 000000000..2ece54d22 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/DeleteFaceResponse.java @@ -0,0 +1,25 @@ +package com.bsd.pjcloud.thirdparty.dto.face; + +import lombok.Data; + +/** + * 删除人脸响应VO + */ +@Data +public class DeleteFaceResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回信息(注意:删除接口返回的是message字段,不是msg) + */ + private String message; + + /** + * 删除成功则为空 + */ + private String data; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/UpdateFaceRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/UpdateFaceRequest.java new file mode 100644 index 000000000..55768a587 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/face/UpdateFaceRequest.java @@ -0,0 +1,24 @@ +package com.bsd.pjcloud.thirdparty.dto.face; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; + +/** + * 修改人脸请求DTO + */ +@Data +public class UpdateFaceRequest { + + /** + * 人脸图片Id,必填 + * 添加人脸接口返回报文中的faceId字段,或获取人员列表v2接口返回报文中的personPhotoIndexCode字段 + */ + @NotBlank(message = "人脸ID不能为空") + private String faceId; + + /** + * 人脸图片base64编码后的字符数据,必填 + */ + @NotBlank(message = "人脸图片数据不能为空") + private String faceData; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonRequest.java new file mode 100644 index 000000000..5e1479c56 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonRequest.java @@ -0,0 +1,95 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.Valid; +import java.util.List; + +/** + * 添加人员请求DTO + */ +@Data +public class AddPersonRequest { + + /** + * 人员ID,可以指定人员personId,不允许与其他人员personId重复,包括已删除的人员。 + * 为空时平台自动生成人员ID + */ + private String personId; + + /** + * 人员名称,1~32个字符;不能包含 ' / \ : * ? " < > + */ + @NotBlank(message = "人员名称不能为空") + @Size(min = 1, max = 32, message = "人员名称长度必须在1-32个字符之间") + @Pattern(regexp = "^[^'/\\\\:*?\"<>]*$", message = "人员名称不能包含特殊字符:' / \\ : * ? \" < >") + private String personName; + + /** + * 性别:1-男,2-女 + */ + @NotBlank(message = "性别不能为空") + @Pattern(regexp = "^[12]$", message = "性别只能是1(男)或2(女)") + private String gender; + + /** + * 所属组织标识,必须是已存在组织 + */ + @NotBlank(message = "所属组织标识不能为空") + private String orgIndexCode; + + /** + * 出生日期,举例:1992-09-12 + */ + @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "出生日期格式必须为yyyy-MM-dd") + private String birthday; + + /** + * 手机号,1-20位数字,平台上人员信息实名标识选择为手机号码时必填 + */ + @Size(min = 1, max = 20, message = "手机号长度必须在1-20位之间") + @Pattern(regexp = "^\\d{1,20}$", message = "手机号只能包含数字") + private String phoneNo; + + /** + * 邮箱,举例:hic@163.com + */ + @Email(message = "邮箱格式不正确") + private String email; + + /** + * 证件类型,参考附录A数据字典,平台上人员信息实名标识选择为身份证件时必填 + */ + private String certificateType; + + /** + * 证件号码,1-20位数字字母,平台上人员信息实名标识选择为身份证件时必填 + */ + @Size(min = 1, max = 20, message = "证件号码长度必须在1-20位之间") + @Pattern(regexp = "^[a-zA-Z0-9]{1,20}$", message = "证件号码只能包含数字和字母") + private String certificateNo; + + /** + * 工号,1-32个字符,平台上人员信息实名标识选择为工号时必填 + */ + @Size(min = 1, max = 32, message = "工号长度必须在1-32个字符之间") + private String jobNo; + + /** + * 人脸信息 + */ + @Valid + private List faces; + + @Data + public static class FaceInfo { + /** + * 人脸图片base64编码后的字符 + */ + @NotBlank(message = "人脸图片数据不能为空") + private String faceData; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonResponse.java new file mode 100644 index 000000000..e6a520a8e --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/AddPersonResponse.java @@ -0,0 +1,38 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; + +/** + * 添加人员响应VO + */ +@Data +public class AddPersonResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回说明 + */ + private String msg; + + /** + * 成功添加的人员信息 + */ + private PersonData data; + + @Data + public static class PersonData { + /** + * 成功添加的人员Id + */ + private String personId; + + /** + * 成功添加的人脸Id + */ + private String faceId; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonRequest.java new file mode 100644 index 000000000..e006b16e1 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonRequest.java @@ -0,0 +1,29 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import com.bsd.pjcloud.thirdparty.dto.visitor.PersonInfo; +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Max; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 批量添加人员请求DTO + */ +@Data +public class BatchAddPersonRequest { + + /** + * 待添加的人员列表,单次操作上限为1000条 + */ + @NotEmpty(message = "人员列表不能为空") + @Size(max = 1000, message = "单次操作最多支持1000条记录") + @Valid + private List persons; + +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonResponse.java new file mode 100644 index 000000000..8fa176899 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchAddPersonResponse.java @@ -0,0 +1,73 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import java.util.List; + +/** + * 批量添加人员响应VO + */ +@Data +public class BatchAddPersonResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回说明 + */ + private String msg; + + /** + * 返回结果 + */ + private BatchPersonData data; + + @Data + public static class BatchPersonData { + + /** + * 批量添加成功的记录 + */ + private List successes; + + /** + * 批量添加失败的记录 + */ + private List failures; + } + + @Data + public static class SuccessRecord { + + /** + * 调用方指定人员临时标志 + */ + private Long clientId; + + /** + * 服务端生成的唯一标识 + */ + private String personId; + } + + @Data + public static class FailureRecord { + + /** + * 调用方指定Id + */ + private Long clientId; + + /** + * 错误码 + */ + private String code; + + /** + * 错误信息 + */ + private String message; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonRequest.java new file mode 100644 index 000000000..d4d60f258 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonRequest.java @@ -0,0 +1,20 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * 批量删除人员请求DTO + */ +@Data +public class BatchDeletePersonRequest { + + /** + * 人员Id列表,单次操作上限为1000条 + */ + @NotEmpty(message = "人员ID列表不能为空") + @Size(max = 1000, message = "单次操作最多支持1000条记录") + private List personIds; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonResponse.java new file mode 100644 index 000000000..c4b4a7857 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/BatchDeletePersonResponse.java @@ -0,0 +1,45 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import java.util.List; + +/** + * 批量删除人员响应VO + */ +@Data +public class BatchDeletePersonResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回说明 + */ + private String msg; + + /** + * 若执行结果为部分删除成功,则返回删除失败的人员标志和错误原因,若全部成功,则该字段为空 + */ + private List data; + + @Data + public static class DeleteFailureRecord { + + /** + * 人员标志 + */ + private String personId; + + /** + * 错误码 + */ + private String code; + + /** + * 错误信息 + */ + private String msg; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoRequest.java new file mode 100644 index 000000000..1d9b03448 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoRequest.java @@ -0,0 +1,34 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.Pattern; +import java.util.List; + +/** + * 根据人员唯一字段获取人员详细信息请求DTO + */ +@Data +public class GetPersonInfoRequest { + + /** + * 参数名,必填 + * certificateNo:证件号码 + * personId:人员Id + * phoneNo:手机号码 + * jobNo:工号 + */ + @NotBlank(message = "参数名不能为空") + @Pattern(regexp = "^(certificateNo|personId|phoneNo|jobNo)$", + message = "参数名只能是:certificateNo、personId、phoneNo、jobNo") + private String paramName; + + /** + * 根据入参传对应的值,最大1000个 + */ + @NotEmpty(message = "参数值列表不能为空") + @Size(max = 1000, message = "参数值最多支持1000个") + private List paramValue; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoResponse.java new file mode 100644 index 000000000..3962ee586 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonInfoResponse.java @@ -0,0 +1,328 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import java.util.List; + +/** + * 根据人员唯一字段获取人员详细信息响应VO + */ +@Data +public class GetPersonInfoResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 接口执行情况说明信息 + */ + private String msg; + + /** + * 返回数据 + */ + private PersonInfoData data; + + @Data + public static class PersonInfoData { + + /** + * 结果总数 + */ + private Integer total; + + /** + * 人员信息列表 + */ + private List list; + } + + @Data + public static class DetailedPersonInfo { + + /** + * 人员ID + */ + private String personId; + + /** + * 姓名 + */ + private String personName; + + /** + * 性别:1-男,2-女 + */ + private Integer gender; + + /** + * 所属组织目录,以@符号分割,包含本组织,例如@root000000@ + */ + private String orgPath; + + /** + * 所属组织目录名称,以/分隔 + */ + private String orgPathName; + + /** + * 所属组织唯一标识码 + */ + private String orgIndexCode; + + /** + * 证件类型 + */ + private Integer certificateType; + + /** + * 证件号码 + */ + private String certificateNo; + + /** + * 工号 + */ + private String jobNo; + + /** + * 出生日期,例"1990-01-01" + */ + private String birthday; + + /** + * 联系电话 + */ + private String phoneNo; + + /** + * 联系地址 + */ + private String address; + + /** + * 人员照片信息 + */ + private List personPhoto; + + /** + * 邮箱 + */ + private String email; + + /** + * 学历 + */ + private Integer education; + + /** + * 人员姓氏 + */ + private String lastName; + + /** + * 人员名称 + */ + private String givenName; + + /** + * 年龄 + */ + private Integer age; + + /** + * 职业 + */ + private String job; + + /** + * 职工性质 + */ + private String staffProperty; + + /** + * 工作单位 + */ + private String company; + + /** + * 职位 + */ + private String employeePost; + + /** + * 员工编号 + */ + private String employeeNumber; + + /** + * 岗位类别 + */ + private String postType; + + /** + * 身份类型 + */ + private String identityType; + + /** + * 国籍 + */ + private String nationality; + + /** + * 民族 + */ + private Integer nation; + + /** + * 籍贯 + */ + private String birthplace; + + /** + * 户籍 + */ + private String censusRegister; + + /** + * 婚姻状况 + */ + private Integer marriaged; + + /** + * 政治面貌 + */ + private String politicalStatus; + + /** + * 宗教 + */ + private String religion; + + /** + * 房间号 + */ + private String roomNum; + + /** + * 与户主关系 + */ + private String houseHolderRel; + + /** + * 学号 + */ + private String studentId; + + /** + * 学生入学时间,例"1990-01-01" + */ + private String stuStartTime; + + /** + * 学生毕业时间,例"1990-01-01" + */ + private String stuEndTime; + + /** + * 年级 + */ + private String stuGrade; + + /** + * 班级 + */ + private String stuClass; + + /** + * 学院 + */ + private String academy; + + /** + * 学生专业 + */ + private String profession; + + /** + * 宿舍楼 + */ + private String dormitory; + + /** + * 是否住校,1:是;2:否 + */ + private Integer lodge; + + /** + * 人员描述 + */ + private String personDesc; + + /** + * 同步标志类型 + */ + private Integer syncFlag; + + /** + * 拼音 + */ + private String pinyin; + + /** + * 发证机构 + */ + private String certIssuer; + + /** + * 发证地址 + */ + private String certAddr; + + /** + * 证件有效期 + */ + private String certExpireTime; + + /** + * 状态,小于0则代表资源已被删除 + */ + private Integer status; + + /** + * 创建时间,ISO8601格式 + */ + private String createTime; + + /** + * 更新时间,ISO8601格式 + */ + private String updateTime; + } + + @Data + public static class PersonPhotoInfo { + + /** + * 图片唯一标示 + */ + private String personPhotoIndexCode; + + /** + * 图片相对url,从提取人员图片接口获取图片数据 + */ + private String picUri; + + /** + * 图片服务器唯一标示 + */ + private String serverIndexCode; + + /** + * 人员ID + */ + private String personId; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListRequest.java new file mode 100644 index 000000000..728d8fde9 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListRequest.java @@ -0,0 +1,32 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Max; + +/** + * 获取组织下人员列表v2请求DTO + */ +@Data +public class GetPersonListRequest { + + /** + * 组织唯一标识码,必填 + */ + @NotBlank(message = "组织唯一标识码不能为空") + private String orgIndexCode; + + /** + * 当前页码,必填,需大于0 + */ + @Min(value = 1, message = "当前页码需大于0") + private Integer pageNo; + + /** + * 实际每页记录总数,必填,需大于0且小于等于1000 + */ + @Min(value = 1, message = "每页记录数需大于0") + @Max(value = 1000, message = "每页记录数需小于等于1000") + private Integer pageSize; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListResponse.java new file mode 100644 index 000000000..2595d03c8 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/GetPersonListResponse.java @@ -0,0 +1,145 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import java.util.List; + +/** + * 获取组织下人员列表v2响应VO + */ +@Data +public class GetPersonListResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 接口执行情况说明信息 + */ + private String msg; + + /** + * 人员信息结构体 + */ + private PersonListData data; + + @Data + public static class PersonListData { + + /** + * 查询数据记录总数 + */ + private Integer total; + + /** + * 当前页码 + */ + private Integer pageNo; + + /** + * 每页记录总数 + */ + private Integer pageSize; + + /** + * 人员列表 + */ + private List list; + } + + @Data + public static class PersonInfo { + + /** + * 人员ID + */ + private String personId; + + /** + * 姓名 + */ + private String personName; + + /** + * 性别:1-男,2-女 + */ + private Integer gender; + + /** + * 所属组织唯一标识码 + */ + private String orgIndexCode; + + /** + * 联系电话 + */ + private String phoneNo; + + /** + * 工号 + */ + private String jobNo; + + /** + * 证件类型 + * 111:身份证, 414:护照, 113:户口簿, 335:驾驶证 + * 131:工作证, 133:学生证, 990:其他 + */ + private Integer certificateType; + + /** + * 证件号码 + */ + private String certificateNo; + + /** + * 创建时间(ISO8601格式) + */ + private String createTime; + + /** + * 更新时间(ISO8601格式) + */ + private String updateTime; + + /** + * 所属组织目录,@进行分割,例如 @root000000@ + */ + private String orgPath; + + /** + * 所属组织名称,@进行分割,如@默认部门@ + */ + private String orgPathName; + + /** + * 人员图片信息 + */ + private PersonPhoto personPhoto; + } + + @Data + public static class PersonPhoto { + + /** + * 人脸图片唯一标示 + */ + private String personPhotoIndexCode; + + /** + * 图片相对url,通过提取人员图片接口获取图片数据 + */ + private String picUri; + + /** + * 图片服务器唯一标示,提取人员图片接口必要参数 + */ + private String serverIndexCode; + + /** + * 人员ID + */ + private String personId; + } +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonRequest.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonRequest.java new file mode 100644 index 000000000..23e5a758d --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonRequest.java @@ -0,0 +1,81 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Max; + +/** + * 修改人员请求DTO + */ +@Data +public class UpdatePersonRequest { + + /** + * 人员id,必填 + */ + @NotBlank(message = "人员ID不能为空") + private String personId; + + /** + * 人员名称,1~32个字符;不能包含 ' / \ : * ? " < > + */ + @Size(min = 1, max = 32, message = "人员名称长度必须在1-32个字符之间") + @Pattern(regexp = "^[^'/\\\\:*?\"<>]*$", message = "人员名称不能包含特殊字符:' / \\ : * ? \" < >") + private String personName; + + /** + * 所属组织标识,必须是已存在组织 + */ + private String orgIndexCode; + + /** + * 性别:1-男,2-女 + */ + @Min(value = 1, message = "性别值必须为1或2") + @Max(value = 2, message = "性别值必须为1或2") + private Integer gender; + + /** + * 出生日期,举例:1992-09-12 + */ + @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "出生日期格式必须为yyyy-MM-dd") + private String birthday; + + /** + * 手机号,1-20位数字 + */ + @Size(min = 1, max = 20, message = "手机号长度必须在1-20位之间") + @Pattern(regexp = "^\\d{1,20}$", message = "手机号只能包含数字") + private String phoneNo; + + /** + * 邮箱,举例:hic@163.com + */ + @Email(message = "邮箱格式不正确") + private String email; + + /** + * 证件类型 + * 111: 身份证, 414: 护照, 113: 户口簿, 335: 驾驶证 + * 131: 工作证, 133: 学生证, 990: 其他 + */ + @Pattern(regexp = "^(111|414|113|335|131|133|990)$", message = "证件类型不正确") + private String certificateType; + + /** + * 证件号码,1-20位数字字母 + */ + @Size(min = 1, max = 20, message = "证件号码长度必须在1-20位之间") + @Pattern(regexp = "^[a-zA-Z0-9]{1,20}$", message = "证件号码只能包含数字和字母") + private String certificateNo; + + /** + * 工号,1-32个字符 + */ + @Size(min = 1, max = 32, message = "工号长度必须在1-32个字符之间") + private String jobNo; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonResponse.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonResponse.java new file mode 100644 index 000000000..f2198ab4f --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/person/UpdatePersonResponse.java @@ -0,0 +1,25 @@ +package com.bsd.pjcloud.thirdparty.dto.person; + +import lombok.Data; + +/** + * 修改人员响应VO + */ +@Data +public class UpdatePersonResponse { + + /** + * 返回码,0 – 成功,其他- 失败 + */ + private String code; + + /** + * 返回说明 + */ + private String msg; + + /** + * 成功则data为空 + */ + private String data; +} \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/visitor/PersonInfo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/visitor/PersonInfo.java index 622723c72..c37c0076b 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/visitor/PersonInfo.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/visitor/PersonInfo.java @@ -14,7 +14,7 @@ public class PersonInfo { private String personId; private String personName; private Integer gender; - private String orgIndexCode; + private String orgIndexCode="1013f7bb18d94ec8962a9fb3eb1df44b"; private String phoneNo; private String jobNo; private Integer certificateType; diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/VisitorController.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/VisitorController.java index f2a6ffc76..c26ad0f70 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/VisitorController.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/VisitorController.java @@ -9,6 +9,23 @@ import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentReq import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorInfo; import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.AppointmentData; import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.RegisterAppointmentResponse; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.face.UpdateFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoResponse; import com.bsd.pjcloud.thirdparty.service.VisitorService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -95,7 +112,148 @@ public class VisitorController { return R.ok(); } + /** + * 添加人员信息v2 + * @param request 添加人员请求参数 + * @return 添加人员响应结果 + */ + @Operation(summary = "添加人员信息v2", description = "添加人员信息到海康平台") + @PostMapping("/person/add") + public R addPersonV2(@Valid @RequestBody AddPersonRequest request) { + try { + AddPersonResponse response = visitorService.addPersonV2(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("添加人员失败: " + e.getMessage()); + } + } + /** + * 批量添加人员信息v1 + * @param request 批量添加人员请求参数 + * @return 批量添加人员响应结果 + */ + @Operation(summary = "批量添加人员信息v1", description = "批量添加人员信息到海康平台") + @PostMapping("/person/batch-add") + public R batchAddPersonV1(@Valid @RequestBody BatchAddPersonRequest request) { + try { + BatchAddPersonResponse response = visitorService.batchAddPersonV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("批量添加人员失败: " + e.getMessage()); + } + } + /** + * 修改人员信息v1 + * @param request 修改人员请求参数 + * @return 修改人员响应结果 + */ + @Operation(summary = "修改人员信息v1", description = "修改海康平台人员信息") + @PostMapping("/person/update") + public R updatePersonV1(@Valid @RequestBody UpdatePersonRequest request) { + try { + UpdatePersonResponse response = visitorService.updatePersonV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("修改人员失败: " + e.getMessage()); + } + } + + /** + * 批量删除人员信息v1 + * @param request 批量删除人员请求参数 + * @return 批量删除人员响应结果 + */ + @Operation(summary = "批量删除人员信息v1", description = "批量删除海康平台人员信息") + @PostMapping("/person/batch-delete") + public R batchDeletePersonV1(@Valid @RequestBody BatchDeletePersonRequest request) { + try { + BatchDeletePersonResponse response = visitorService.batchDeletePersonV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("批量删除人员失败: " + e.getMessage()); + } + } + + /** + * 添加人脸信息v1 + * @param request 添加人脸请求参数 + * @return 添加人脸响应结果 + */ + @Operation(summary = "添加人脸信息v1", description = "添加人脸信息到海康平台") + @PostMapping("/face/add") + public R addFaceV1(@Valid @RequestBody AddFaceRequest request) { + try { + AddFaceResponse response = visitorService.addFaceV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("添加人脸失败: " + e.getMessage()); + } + } + + /** + * 修改人脸信息v1 + * @param request 修改人脸请求参数 + * @return 修改人脸响应结果 + */ + @Operation(summary = "修改人脸信息v1", description = "修改海康平台人脸信息") + @PostMapping("/face/update") + public R updateFaceV1(@Valid @RequestBody UpdateFaceRequest request) { + try { + AddFaceResponse response = visitorService.updateFaceV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("修改人脸失败: " + e.getMessage()); + } + } + + /** + * 删除人脸信息v1 + * @param request 删除人脸请求参数 + * @return 删除人脸响应结果 + */ + @Operation(summary = "删除人脸信息v1", description = "删除海康平台人脸信息") + @PostMapping("/face/delete") + public R deleteFaceV1(@Valid @RequestBody DeleteFaceRequest request) { + try { + DeleteFaceResponse response = visitorService.deleteFaceV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("删除人脸失败: " + e.getMessage()); + } + } + + /** + * 获取组织下人员列表v2 + * @param request 获取人员列表请求参数 + * @return 获取人员列表响应结果 + */ + @Operation(summary = "获取组织下人员列表v2", description = "根据组织编号获取组织下的人员信息列表") + @PostMapping("/person/list") + public R getPersonListV2(@Valid @RequestBody GetPersonListRequest request) { + try { + GetPersonListResponse response = visitorService.getPersonListV2(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("获取人员列表失败: " + e.getMessage()); + } + } + + /** + * 根据人员唯一字段获取人员详细信息v1 + * @param request 获取人员详细信息请求参数 + * @return 获取人员详细信息响应结果 + */ + @Operation(summary = "根据人员唯一字段获取人员详细信息v1", description = "根据实名标识精确查询人员详细信息") + @PostMapping("/person/detail") + public R getPersonInfoV1(@Valid @RequestBody GetPersonInfoRequest request) { + try { + GetPersonInfoResponse response = visitorService.getPersonInfoV1(request); + return R.ok(response); + } catch (Exception e) { + return R.failed("获取人员详细信息失败: " + e.getMessage()); + } + } } \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/VisitorService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/VisitorService.java index ce8363aa8..9e1320541 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/VisitorService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/VisitorService.java @@ -27,6 +27,24 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.AddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.UpdatePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonRequest; +import com.bsd.pjcloud.thirdparty.dto.person.BatchDeletePersonResponse; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.AddFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.face.UpdateFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceRequest; +import com.bsd.pjcloud.thirdparty.dto.face.DeleteFaceResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonListResponse; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoRequest; +import com.bsd.pjcloud.thirdparty.dto.person.GetPersonInfoResponse; + @Service @Slf4j public class VisitorService extends BaseHikvisionService { @@ -360,6 +378,744 @@ public class VisitorService extends BaseHikvisionService { } } + /** + * 添加人员信息v2 + * + * @param request 添加人员请求参数 + * @return 添加人员响应结果 + */ + @Transactional + public AddPersonResponse addPersonV2(AddPersonRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("添加人员请求参数不能为空"); + } + if (StringUtils.isBlank(request.getPersonName())) { + throw new IllegalArgumentException("人员名称不能为空"); + } + if (StringUtils.isBlank(request.getGender())) { + throw new IllegalArgumentException("性别不能为空"); + } + if (StringUtils.isBlank(request.getOrgIndexCode())) { + throw new IllegalArgumentException("所属组织标识不能为空"); + } + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v2/person/single/add"; + + // 3. 转换请求体 + JSONObject body = convertAddPersonRequestToJSON(request); + + // 添加日志便于调试 + log.info("添加人员请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("添加人员响应: {}", responseJson); + + // 5. 处理响应 + AddPersonResponse response = parseAddPersonResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换添加人员请求为JSON + */ + private JSONObject convertAddPersonRequestToJSON(AddPersonRequest request) { + JSONObject json = new JSONObject(); + + // 必填字段 + json.put("personName", request.getPersonName()); + json.put("gender", request.getGender()); + json.put("orgIndexCode", request.getOrgIndexCode()); + + // 可选字段 + if (StringUtils.isNotBlank(request.getPersonId())) { + json.put("personId", request.getPersonId()); + } + if (StringUtils.isNotBlank(request.getBirthday())) { + json.put("birthday", request.getBirthday()); + } + if (StringUtils.isNotBlank(request.getPhoneNo())) { + json.put("phoneNo", request.getPhoneNo()); + } + if (StringUtils.isNotBlank(request.getEmail())) { + json.put("email", request.getEmail()); + } + if (StringUtils.isNotBlank(request.getCertificateType())) { + json.put("certificateType", request.getCertificateType()); + } + if (StringUtils.isNotBlank(request.getCertificateNo())) { + json.put("certificateNo", request.getCertificateNo()); + } + if (StringUtils.isNotBlank(request.getJobNo())) { + json.put("jobNo", request.getJobNo()); + } + + // 处理人脸信息 + if (!CollectionUtils.isEmpty(request.getFaces())) { + JSONArray facesArray = new JSONArray(); + request.getFaces().forEach(face -> { + JSONObject faceJson = new JSONObject(); + faceJson.put("faceData", face.getFaceData()); + facesArray.add(faceJson); + }); + json.put("faces", facesArray); + } + + return json; + } + + /** + * 解析添加人员响应 + */ + private AddPersonResponse parseAddPersonResponse(String json) { + try { + return JSON.parseObject(json, AddPersonResponse.class); + } catch (JSONException e) { + log.error("解析添加人员响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "添加人员响应解析失败"); + } + } + + /** + * 批量添加人员信息v1 + * + * @param request 批量添加人员请求参数 + * @return 批量添加人员响应结果 + */ + @Transactional + public BatchAddPersonResponse batchAddPersonV1(BatchAddPersonRequest request) { + // 1. 参数校验 + if (request == null || CollectionUtils.isEmpty(request.getPersons())) { + throw new IllegalArgumentException("批量添加人员请求参数不能为空"); + } + + // 检查数量限制 + if (request.getPersons().size() > 1000) { + throw new IllegalArgumentException("单次操作最多支持1000条记录"); + } + + // 检查clientId唯一性 +// long distinctClientIdCount = request.getPersons().stream() +// .filter(person -> person.getClientId() != null) +// .mapToLong(BatchAddPersonRequest.PersonInfo::getClientId) +// .distinct() +// .count(); + +// long totalClientIdCount = request.getPersons().stream() +// .filter(person -> person.getClientId() != null) +// .count(); + +// if (distinctClientIdCount != totalClientIdCount) { +// throw new IllegalArgumentException("请求内的每一条数据的clientId必须唯一"); +// } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/person/batch/add"; + + // 3. 转换请求体 + JSONArray body = convertBatchAddPersonRequestToJSON(request); + + // 添加日志便于调试 + log.info("批量添加人员请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("批量添加人员响应: {}", responseJson); + + // 5. 处理响应 + BatchAddPersonResponse response = parseBatchAddPersonResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换批量添加人员请求为JSON数组 + */ + private JSONArray convertBatchAddPersonRequestToJSON(BatchAddPersonRequest request) { + JSONArray jsonArray = new JSONArray(); + + request.getPersons().forEach(person -> { + JSONObject personJson = new JSONObject(); + + // 必填字段 + personJson.put("personName", person.getPersonName()); + personJson.put("orgIndexCode", person.getOrgIndexCode()); + + // 可选字段 + if (person.getClientId() != null) { + personJson.put("clientId", person.getClientId()); + } + if (StringUtils.isNotBlank(person.getPersonId())) { + personJson.put("personId", person.getPersonId()); + } + if (person.getGender() != null) { + personJson.put("gender", person.getGender()); + } + if (StringUtils.isNotBlank(person.getBirthday())) { + personJson.put("birthday", person.getBirthday()); + } + if (StringUtils.isNotBlank(person.getPhoneNo())) { + personJson.put("phoneNo", person.getPhoneNo()); + } + if (StringUtils.isNotBlank(person.getEmail())) { + personJson.put("email", person.getEmail()); + } + if (StringUtils.isNotBlank(person.getCertificateType())) { + personJson.put("certificateType", person.getCertificateType()); + } + if (StringUtils.isNotBlank(person.getCertificateNo())) { + personJson.put("certificateNo", person.getCertificateNo()); + } + if (StringUtils.isNotBlank(person.getJobNo())) { + personJson.put("jobNo", person.getJobNo()); + } + + jsonArray.add(personJson); + }); + + return jsonArray; + } + + /** + * 解析批量添加人员响应 + */ + private BatchAddPersonResponse parseBatchAddPersonResponse(String json) { + try { + return JSON.parseObject(json, BatchAddPersonResponse.class); + } catch (JSONException e) { + log.error("解析批量添加人员响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "批量添加人员响应解析失败"); + } + } + + /** + * 修改人员信息v1 + * + * @param request 修改人员请求参数 + * @return 修改人员响应结果 + */ + @Transactional + public UpdatePersonResponse updatePersonV1(UpdatePersonRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("修改人员请求参数不能为空"); + } + if (StringUtils.isBlank(request.getPersonId())) { + throw new IllegalArgumentException("人员ID不能为空"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/person/single/update"; + + // 3. 转换请求体 + JSONObject body = convertUpdatePersonRequestToJSON(request); + + // 添加日志便于调试 + log.info("修改人员请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("修改人员响应: {}", responseJson); + + // 5. 处理响应 + UpdatePersonResponse response = parseUpdatePersonResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换修改人员请求为JSON + */ + private JSONObject convertUpdatePersonRequestToJSON(UpdatePersonRequest request) { + JSONObject json = new JSONObject(); + + // 必填字段 + json.put("personId", request.getPersonId()); + + // 可选字段 - 只有非空值才会被包含 + if (StringUtils.isNotBlank(request.getPersonName())) { + json.put("personName", request.getPersonName()); + } + if (StringUtils.isNotBlank(request.getOrgIndexCode())) { + json.put("orgIndexCode", request.getOrgIndexCode()); + } + if (request.getGender() != null) { + json.put("gender", request.getGender()); + } + if (StringUtils.isNotBlank(request.getBirthday())) { + json.put("birthday", request.getBirthday()); + } + if (StringUtils.isNotBlank(request.getPhoneNo())) { + json.put("phoneNo", request.getPhoneNo()); + } + if (StringUtils.isNotBlank(request.getEmail())) { + json.put("email", request.getEmail()); + } + if (StringUtils.isNotBlank(request.getCertificateType())) { + json.put("certificateType", request.getCertificateType()); + } + if (StringUtils.isNotBlank(request.getCertificateNo())) { + json.put("certificateNo", request.getCertificateNo()); + } + if (StringUtils.isNotBlank(request.getJobNo())) { + json.put("jobNo", request.getJobNo()); + } + + return json; + } + + /** + * 解析修改人员响应 + */ + private UpdatePersonResponse parseUpdatePersonResponse(String json) { + try { + return JSON.parseObject(json, UpdatePersonResponse.class); + } catch (JSONException e) { + log.error("解析修改人员响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "修改人员响应解析失败"); + } + } + + /** + * 批量删除人员信息v1 + * + * @param request 批量删除人员请求参数 + * @return 批量删除人员响应结果 + */ + @Transactional + public BatchDeletePersonResponse batchDeletePersonV1(BatchDeletePersonRequest request) { + // 1. 参数校验 + if (request == null || CollectionUtils.isEmpty(request.getPersonIds())) { + throw new IllegalArgumentException("批量删除人员请求参数不能为空"); + } + + // 检查数量限制 + if (request.getPersonIds().size() > 1000) { + throw new IllegalArgumentException("单次操作最多支持1000条记录"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/person/batch/delete"; + + // 3. 转换请求体 + JSONObject body = convertBatchDeletePersonRequestToJSON(request); + + // 添加日志便于调试 + log.info("批量删除人员请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("批量删除人员响应: {}", responseJson); + + // 5. 处理响应 + BatchDeletePersonResponse response = parseBatchDeletePersonResponse(responseJson); + if (!"0".equals(response.getCode())) { + // 对于批量删除,即使部分失败也可能返回code=0 + // 具体的失败信息在data字段中 + if (!CollectionUtils.isEmpty(response.getData())) { + log.warn("批量删除人员部分失败,失败记录数: {}", response.getData().size()); + } else { + // 完全失败的情况 + throw new HikvisionException(response.getCode(), response.getMsg()); + } + } + + return response; + } + + /** + * 转换批量删除人员请求为JSON + */ + private JSONObject convertBatchDeletePersonRequestToJSON(BatchDeletePersonRequest request) { + JSONObject json = new JSONObject(); + json.put("personIds", request.getPersonIds()); + return json; + } + + /** + * 解析批量删除人员响应 + */ + private BatchDeletePersonResponse parseBatchDeletePersonResponse(String json) { + try { + return JSON.parseObject(json, BatchDeletePersonResponse.class); + } catch (JSONException e) { + log.error("解析批量删除人员响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "批量删除人员响应解析失败"); + } + } + + /** + * 添加人脸信息v1 + * + * @param request 添加人脸请求参数 + * @return 添加人脸响应结果 + */ + @Transactional + public AddFaceResponse addFaceV1(AddFaceRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("添加人脸请求参数不能为空"); + } + if (StringUtils.isBlank(request.getPersonId())) { + throw new IllegalArgumentException("人员ID不能为空"); + } + if (StringUtils.isBlank(request.getFaceData())) { + throw new IllegalArgumentException("人脸图片数据不能为空"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/face/single/add"; + + // 3. 转换请求体 + JSONObject body = convertAddFaceRequestToJSON(request); + + // 添加日志便于调试(注意:人脸数据通常很大,只记录长度) + log.info("添加人脸请求体: personId={}, faceData length={}", + request.getPersonId(), request.getFaceData().length()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("添加人脸响应: {}", responseJson); + + // 5. 处理响应 + AddFaceResponse response = parseAddFaceResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换添加人脸请求为JSON + */ + private JSONObject convertAddFaceRequestToJSON(AddFaceRequest request) { + JSONObject json = new JSONObject(); + json.put("personId", request.getPersonId()); + json.put("faceData", request.getFaceData()); + return json; + } + + /** + * 解析添加人脸响应 + */ + private AddFaceResponse parseAddFaceResponse(String json) { + try { + return JSON.parseObject(json, AddFaceResponse.class); + } catch (JSONException e) { + log.error("解析添加人脸响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "添加人脸响应解析失败"); + } + } + + /** + * 修改人脸信息v1 + * + * @param request 修改人脸请求参数 + * @return 修改人脸响应结果 + */ + @Transactional + public AddFaceResponse updateFaceV1(UpdateFaceRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("修改人脸请求参数不能为空"); + } + if (StringUtils.isBlank(request.getFaceId())) { + throw new IllegalArgumentException("人脸ID不能为空"); + } + if (StringUtils.isBlank(request.getFaceData())) { + throw new IllegalArgumentException("人脸图片数据不能为空"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/face/single/update"; + + // 3. 转换请求体 + JSONObject body = convertUpdateFaceRequestToJSON(request); + + // 添加日志便于调试(注意:人脸数据通常很大,只记录长度) + log.info("修改人脸请求体: faceId={}, faceData length={}", + request.getFaceId(), request.getFaceData().length()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("修改人脸响应: {}", responseJson); + + // 5. 处理响应(修改人脸的响应格式和添加人脸相同) + AddFaceResponse response = parseAddFaceResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 删除人脸信息v1 + * + * @param request 删除人脸请求参数 + * @return 删除人脸响应结果 + */ + @Transactional + public DeleteFaceResponse deleteFaceV1(DeleteFaceRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("删除人脸请求参数不能为空"); + } + if (StringUtils.isBlank(request.getFaceId())) { + throw new IllegalArgumentException("人脸ID不能为空"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/face/single/delete"; + + // 3. 转换请求体 + JSONObject body = convertDeleteFaceRequestToJSON(request); + + // 添加日志便于调试 + log.info("删除人脸请求体: faceId={}", request.getFaceId()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("删除人脸响应: {}", responseJson); + + // 5. 处理响应 + DeleteFaceResponse response = parseDeleteFaceResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMessage()); + } + + return response; + } + + /** + * 转换修改人脸请求为JSON + */ + private JSONObject convertUpdateFaceRequestToJSON(UpdateFaceRequest request) { + JSONObject json = new JSONObject(); + json.put("faceId", request.getFaceId()); + json.put("faceData", request.getFaceData()); + return json; + } + + /** + * 转换删除人脸请求为JSON + */ + private JSONObject convertDeleteFaceRequestToJSON(DeleteFaceRequest request) { + JSONObject json = new JSONObject(); + json.put("faceId", request.getFaceId()); + return json; + } + + /** + * 解析删除人脸响应 + */ + private DeleteFaceResponse parseDeleteFaceResponse(String json) { + try { + return JSON.parseObject(json, DeleteFaceResponse.class); + } catch (JSONException e) { + log.error("解析删除人脸响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "删除人脸响应解析失败"); + } + } + + /** + * 获取组织下人员列表v2 + * + * @param request 获取人员列表请求参数 + * @return 获取人员列表响应结果 + */ + @Transactional(readOnly = true) + public GetPersonListResponse getPersonListV2(GetPersonListRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("获取人员列表请求参数不能为空"); + } + if (StringUtils.isBlank(request.getOrgIndexCode())) { + throw new IllegalArgumentException("组织唯一标识码不能为空"); + } + if (request.getPageNo() == null || request.getPageNo() <= 0) { + throw new IllegalArgumentException("当前页码需大于0"); + } + if (request.getPageSize() == null || request.getPageSize() <= 0 || request.getPageSize() > 1000) { + throw new IllegalArgumentException("每页记录数需大于0且小于等于1000"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v2/person/orgIndexCode/personList"; + + // 3. 转换请求体 + JSONObject body = convertGetPersonListRequestToJSON(request); + + // 添加日志便于调试 + log.info("获取人员列表请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("获取人员列表响应: {}", responseJson); + + // 5. 处理响应 + GetPersonListResponse response = parseGetPersonListResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换获取人员列表请求为JSON + */ + private JSONObject convertGetPersonListRequestToJSON(GetPersonListRequest request) { + JSONObject json = new JSONObject(); + json.put("orgIndexCode", request.getOrgIndexCode()); + json.put("pageNo", request.getPageNo()); + json.put("pageSize", request.getPageSize()); + return json; + } + + /** + * 解析获取人员列表响应 + */ + private GetPersonListResponse parseGetPersonListResponse(String json) { + try { + return JSON.parseObject(json, GetPersonListResponse.class); + } catch (JSONException e) { + log.error("解析获取人员列表响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "获取人员列表响应解析失败"); + } + } + + /** + * 根据人员唯一字段获取人员详细信息v1 + * + * @param request 获取人员详细信息请求参数 + * @return 获取人员详细信息响应结果 + */ + @Transactional(readOnly = true) + public GetPersonInfoResponse getPersonInfoV1(GetPersonInfoRequest request) { + // 1. 参数校验 + if (request == null) { + throw new IllegalArgumentException("获取人员详细信息请求参数不能为空"); + } + if (StringUtils.isBlank(request.getParamName())) { + throw new IllegalArgumentException("参数名不能为空"); + } + if (CollectionUtils.isEmpty(request.getParamValue())) { + throw new IllegalArgumentException("参数值列表不能为空"); + } + if (request.getParamValue().size() > 1000) { + throw new IllegalArgumentException("参数值最多支持1000个"); + } + + // 2. 构建API路径 + String apiPath = properties.getArtemisPath() + "/api/resource/v1/person/condition/personInfo"; + + // 3. 转换请求体 + JSONObject body = convertGetPersonInfoRequestToJSON(request); + + // 添加日志便于调试 + log.info("获取人员详细信息请求体: {}", body.toJSONString()); + + // 4. 发送请求 + String responseJson = ArtemisHttpUtil.doPostStringArtemis( + Map.of("https://", apiPath), + body.toJSONString(), + null, null, "application/json", null + ); + + // 添加日志便于调试 + log.info("获取人员详细信息响应: {}", responseJson); + + // 5. 处理响应 + GetPersonInfoResponse response = parseGetPersonInfoResponse(responseJson); + if (!"0".equals(response.getCode())) { + throw new HikvisionException(response.getCode(), response.getMsg()); + } + + return response; + } + + /** + * 转换获取人员详细信息请求为JSON + */ + private JSONObject convertGetPersonInfoRequestToJSON(GetPersonInfoRequest request) { + JSONObject json = new JSONObject(); + json.put("paramName", request.getParamName()); + json.put("paramValue", request.getParamValue()); + return json; + } + + /** + * 解析获取人员详细信息响应 + */ + private GetPersonInfoResponse parseGetPersonInfoResponse(String json) { + try { + return JSON.parseObject(json, GetPersonInfoResponse.class); + } catch (JSONException e) { + log.error("解析获取人员详细信息响应失败: {}", json, e); + throw new HikvisionException("PARSE_ERROR", "获取人员详细信息响应解析失败"); + } + } } \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml index 79b052fc1..589ac6244 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -128,7 +128,7 @@ hikvision: app-key: 21470882 app-secret: lYRm5YwBp90qdg5eb0p6 artemis-path: /artemis - person-id: 639f8b57bb6c438e884ae48c5cd535c8 + person-id: 1896952011376566273 apis: person-list: /api/resource/v2/person/personList # 新增人员列表接口 visitor-appointment: /api/visitor/v2/appointment # 新增访客预约接口 diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java index 84cb2da46..d52ed95f1 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java @@ -43,6 +43,9 @@ import com.bsd.pjcloud.common.security.annotation.Inner; import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto; +import com.bsd.pjcloud.thirdparty.api.feign.RemoterVisitorService; +import com.bsd.pjcloud.thirdparty.dto.person.BatchAddPersonRequest; +import com.bsd.pjcloud.thirdparty.dto.visitor.PersonInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -58,6 +61,7 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -76,6 +80,8 @@ public class SysUserController { private final SysUserService userService; + private final RemoterVisitorService remoterVisitorService; + /* ************************************* start 回调 start ************************************* */ @Inner(value = false) @@ -468,4 +474,27 @@ public class SysUserController { } return R.ok(true); } + + + @GetMapping("/syncHKUser") + @Schema(description = "同步用户到海康") + public R syncHKUser() { + List list = userService.list(); + BatchAddPersonRequest batchAddPersonRequest = new BatchAddPersonRequest(); + + List personInfos = new ArrayList<>(); + + for (SysUser sysUser : list){ + PersonInfo personInfo = new PersonInfo(); + personInfo.setPersonName(sysUser.getName()); + personInfo.setPhoneNo(sysUser.getPhone()); + personInfo.setGender(1); + personInfo.setPersonId(sysUser.getUserId().toString()); + personInfos.add(personInfo); + } + batchAddPersonRequest.setPersons(personInfos); + remoterVisitorService.batchAddPersonV1(batchAddPersonRequest); + return R.ok(true); + } + }