diff --git a/db/1000pjcloudx_thirdparty.sql b/db/1000pjcloudx_thirdparty.sql index 1346cc84..896b8a12 100644 --- a/db/1000pjcloudx_thirdparty.sql +++ b/db/1000pjcloudx_thirdparty.sql @@ -40,6 +40,7 @@ CREATE TABLE `third_door_log` `api_type` tinytext NOT NULL COMMENT '请求类型', `biz_type` tinytext NOT NULL COMMENT 'api类型', `biz_id` varchar(2048) DEFAULT NULL COMMENT 'api类型id', + `request_id` varchar(64) DEFAULT NULL COMMENT '请求id', `api_url` text DEFAULT NULL COMMENT 'api url', `res` text DEFAULT NULL COMMENT 'res', `req` text DEFAULT NULL COMMENT 'req', diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/spu/HardSpuController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/spu/HardSpuController.java index 77542a10..462e0713 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/spu/HardSpuController.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/spu/HardSpuController.java @@ -39,6 +39,13 @@ public class HardSpuController { private final HardSpuService hardSpuService; + @Operation(summary = "拉取旷世商品", description = "拉取旷世商品") + @GetMapping("/async-all") + public R asyncAll() { + hardSpuService.asyncAll(); + return R.ok(); + } + @Operation(summary = "根据设备id智能柜编号查询商品", description = "根据设备id智能柜编号查询商品") @GetMapping("/get-by-cabinet-no") public R>>> getByCabinetNo(@RequestParam Long hardId, @RequestParam String cabinetNo) { diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardSpuService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardSpuService.java index cfa14bb5..b02be44f 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardSpuService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardSpuService.java @@ -38,4 +38,9 @@ public interface HardSpuService extends IService { * 根据 hardwareId 和 cabinetNo 查询商品 */ List>> getByCabinetNo(Long hardId, String cabinetNo); + + /** + * 拉取旷世商品 + */ + void asyncAll(); } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/spu/HardSpuServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/spu/HardSpuServiceImpl.java index a12d8ff7..f958f718 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/spu/HardSpuServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/spu/HardSpuServiceImpl.java @@ -9,17 +9,17 @@ import com.bsd.pjcloud.hard.api.constant.spu.HardKsSkuTypeEnum; import com.bsd.pjcloud.hard.api.dto.spu.HardSpuDto; import com.bsd.pjcloud.hard.api.dto.spu.HardSpuJoinDto; import com.bsd.pjcloud.hard.api.entity.spu.HardSpuEntity; -import com.bsd.pjcloud.hard.api.entity.spu.HardSpuJoinEntity; import com.bsd.pjcloud.hard.api.vo.manager.HardDoorManagerVo; -import com.bsd.pjcloud.hard.api.vo.manager.HardManagerVo; import com.bsd.pjcloud.hard.api.vo.spu.HardSpuJoinVo; import com.bsd.pjcloud.hard.api.vo.spu.HardSpuVo; -import com.bsd.pjcloud.hard.mapper.spu.HardSpuJoinMapper; import com.bsd.pjcloud.hard.mapper.spu.HardSpuMapper; import com.bsd.pjcloud.hard.service.HardDoorManagerService; import com.bsd.pjcloud.hard.service.HardManagerService; import com.bsd.pjcloud.hard.service.HardSpuJoinService; import com.bsd.pjcloud.hard.service.HardSpuService; +import com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdKsService; +import com.bsd.pjcloud.thirdparty.dto.ks.KsBarcodeLikeDto; +import com.bsd.pjcloud.thirdparty.vo.ks.KsBarcodeLikeVo; import com.bsd.pjcloud.wallet.api.feign.RemoteMchService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -42,6 +42,7 @@ public class HardSpuServiceImpl extends ServiceImpl skuSubmit(@RequestBody KsSkuSubmitDto dto); + + /** + * 集合SKU提交审核(未公开) + */ + @NoToken + @PostMapping("/third-ks/sku-submit-collection") + R skuSubmitCollection(@RequestBody KsSkuSubmitCollectionDto dto); + + /** + * SKU审核结果主动获取 + */ + @NoToken + @PostMapping("/third-ks/sku-result") + R skuResult(@RequestBody KsSkuResultDto dto); + + /** + * SKU删除 + */ + @NoToken + @PostMapping("/third-ks/sku-delete") + R skuDelete(@RequestBody KsSkuDeleteDto dto); + + /** + * 根据69码查询标准库和私有库商品信息 + */ + @NoToken + @PostMapping("/third-ks/barcode-sku") + R barcodeSku(@RequestBody KsBarcodeSkuDto dto); + + /** + * 根据ks_sku_id查询标准库和私有库商品信息 + */ + @NoToken + @PostMapping("/third-ks/barcode-sku-by-id") + R barcodeSkuById(@RequestParam Long ksSkuId); + + /** + * 模糊查询标准库和私有库商品信息 + */ + @NoToken + @PostMapping("/third-ks/barcode-sku-like") + R barcodeSkuLike(@RequestBody KsBarcodeLikeDto dto); + + /** + * SKU提交识别 + */ + @NoToken + @PostMapping("/third-ks/recognition") + R recognition(@RequestBody KsRecognitionDto dto); + + /** + * SKU识别结果主动获取 + */ + @NoToken + @PostMapping("/third-ks/recognition-result") + R recognitionResult(@RequestBody KsRecognitionResultDto dto); +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorApiTypeEnum.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorApiTypeEnum.java index 2d4c989a..9a76a0ca 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorApiTypeEnum.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorApiTypeEnum.java @@ -1,18 +1,29 @@ package com.bsd.pjcloud.thirdparty.constant.door; import cn.hutool.core.util.ObjectUtil; -import com.bsd.pjcloud.thirdparty.constant.ThirdZyBizEnumType; import lombok.AllArgsConstructor; import lombok.Getter; import java.util.Arrays; +/** + * 柜子接口 + */ @AllArgsConstructor @Getter public enum ThirdDoorApiTypeEnum { - DOOR_API("10", "智能柜接口"), - DISCERN_API("20", "识别接口"), + REGISTER("10", "设备注册"), + BIND("20", "设备信息绑定"), + STATUS("30", "查询设备状态"), + RESTART("40", "设备重启"), + SETTING("50", "设备设置"), + VOLUME("60", "音量设置"), + OPEN("70", "请求开锁"), + VIDEO("80", "调取另一个摄像头视频"), + OPEN_CALLBACK("90", "门锁开关通知"), + VIDEO_CALLBACK("100", "视频地址通知"), + STATUS_CALLBACK("110", "设备状态通知"), ; private final String type; diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorBizTypeEnum.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorBizTypeEnum.java new file mode 100644 index 00000000..10940786 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorBizTypeEnum.java @@ -0,0 +1,25 @@ +package com.bsd.pjcloud.thirdparty.constant.door; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@AllArgsConstructor +@Getter +public enum ThirdDoorBizTypeEnum { + + DOOR_API("10", "智能柜接口"), + DISCERN_API("20", "识别接口"), + ; + + private final String type; + private final String description; + + public static ThirdDoorBizTypeEnum valueOfByType(String type) { + if (ObjectUtil.isEmpty(type)) return null; + return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get(); + } + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorKsApiTypeEnum.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorKsApiTypeEnum.java new file mode 100644 index 00000000..49a6b8ae --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThirdDoorKsApiTypeEnum.java @@ -0,0 +1,34 @@ +package com.bsd.pjcloud.thirdparty.constant.door; + + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@AllArgsConstructor +@Getter +public enum ThirdDoorKsApiTypeEnum { + + REGISTER("10", "常规SKU提交审核"), + SKU_SUBMIT_COLLECTION("20", "集合SKU提交审核(未公开)"), + SKU_RESULT("30", "SKU审核结果主动获取"), + SKU_EDIT("40", "常规SKU修改"), + SKU_DELETE("50", "SKU删除"), + BARCODE_SKU("60", "根据69码查询标准库和私有库商品信息"), + BARCODE_SKU_BY_ID("70", "根据ks_sku_id查询标准库和私有库商品信息"), + BARCODE_SKU_LIKE("80", "模糊查询标准库和私有库商品信息"), + RECOGNITION("90", "SKU提交识别"), + RECOGNITION_RESULT("100", "SKU识别结果主动获取"), + ; + + private final String type; + private final String description; + + public static ThirdDoorKsApiTypeEnum valueOfByType(String type) { + if (ObjectUtil.isEmpty(type)) return null; + return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get(); + } + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThordDoorApiTypeEnum.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThordDoorApiTypeEnum.java deleted file mode 100644 index 5dfa0f6d..00000000 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/constant/door/ThordDoorApiTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.bsd.pjcloud.thirdparty.constant.door; - -import cn.hutool.core.util.ObjectUtil; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 柜子接口 - */ -@AllArgsConstructor -@Getter -public enum ThordDoorApiTypeEnum { - - REGISTER("10", "设备注册"), - BIND("20", "设备信息绑定"), - STATUS("30", "查询设备状态"), - RESTART("40", "设备重启"), - SETTING("50", "设备设置"), - VOLUME("60", "音量设置"), - OPEN("70", "请求开锁"), - VIDEO("80", "调取另一个摄像头视频"), - OPEN_CALLBACK("90", "门锁开关通知"), - VIDEO_CALLBACK("100", "视频地址通知"), - STATUS_CALLBACK("110", "设备状态通知"), - ; - - private final String type; - private final String description; - - public static ThordDoorApiTypeEnum valueOfByType(String type) { - if (ObjectUtil.isEmpty(type)) return null; - return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get(); - } - -} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/door/ThirdDoorLogEntity.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/door/ThirdDoorLogEntity.java index 2c55b35b..70369487 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/door/ThirdDoorLogEntity.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/door/ThirdDoorLogEntity.java @@ -45,6 +45,12 @@ public class ThirdDoorLogEntity extends Model { @Schema(description = "api类型id") private String bizId; + /** + * 请求id + */ + @Schema(description = "请求id") + private String requestId; + /** * api url */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports index 77223a1d..3e365f92 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports @@ -1,3 +1,4 @@ +com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdKsService com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdDoorApiService com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdPartyAuthService com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdZyService diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/KsDiscernConfig.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/KsDiscernConfig.java index 5a5e3143..4e7c5267 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/KsDiscernConfig.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/KsDiscernConfig.java @@ -11,6 +11,8 @@ public class KsDiscernConfig { private String baseUrl; + private String host; + private String accessKey; private String secretKey; diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ks/ThirdKsApiController.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ks/ThirdKsApiController.java index 9bdcf94b..cd236597 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ks/ThirdKsApiController.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ks/ThirdKsApiController.java @@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor -@RequestMapping("/third-door") -@Tag(description = "third-door", name = "智能柜") +@RequestMapping("/third-ks") +@Tag(description = "third-ks", name = "旷世识别") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class ThirdKsApiController { @@ -89,7 +89,7 @@ public class ThirdKsApiController { @Inner @Operation(summary = "SKU识别结果主动获取") - @PostMapping("/recognition_result") + @PostMapping("/recognition-result") public R recognitionResult(@RequestBody KsRecognitionResultDto dto) { return R.ok(thirdKsApiService.recognitionResult(dto)); } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ks/ThirdKsApiServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ks/ThirdKsApiServiceImpl.java index bf1e0314..255dd7d6 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ks/ThirdKsApiServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ks/ThirdKsApiServiceImpl.java @@ -2,6 +2,7 @@ package com.bsd.pjcloud.thirdparty.service.impl.ks; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.json.JSONUtil; import com.bsd.pjcloud.thirdparty.config.KsDiscernConfig; import com.bsd.pjcloud.thirdparty.dto.ks.*; @@ -15,9 +16,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import java.util.*; @Service @@ -202,12 +201,17 @@ public class ThirdKsApiServiceImpl implements ThirdKsApiService { public KsBarcodeLikeVo barcodeSkuLike(KsBarcodeLikeDto dto) { long startTime = System.currentTimeMillis(); KsBaseVo ksBaseVo = new KsBaseVo(); - KsApi.Api api = KsApi.BARCODE_SKU_LIKE.setBaseUrl(ksDiscernConfig.getBaseUrl()).setParams(BeanUtil.beanToMap(dto)); + KsApi.Api api = KsApi.BARCODE_SKU_LIKE + .setBaseUrl(ksDiscernConfig.getBaseUrl()) + .setParams(BeanUtil.beanToMap(dto)) + .setAccessKey(ksDiscernConfig.getAccessKey()) + .setSecretKey(ksDiscernConfig.getSecretKey()) + .setHost(ksDiscernConfig.getHost()); ThirdDoorLogEntity logEntity = api.getInitLogEntity(); logEntity.setReq(JSONUtil.toJsonStr(dto)); try { String body = JSONUtil.toJsonStr(dto); - String res = api.getHttpRequest().body(body).execute().body(); + String res = api.getHttpRequest().execute().body(); if (ObjectUtil.isEmpty(res)) throw new RuntimeException("response响应为空"); logEntity.setRes(res); ksBaseVo = JSONUtil.toBean(res, KsBaseVo.class); diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/door/api/DoorApi.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/door/api/DoorApi.java index ca1f143d..1459bd67 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/door/api/DoorApi.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/door/api/DoorApi.java @@ -4,49 +4,47 @@ package com.bsd.pjcloud.thirdparty.utils.door.api; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpRequest; import com.bsd.pjcloud.thirdparty.constant.door.ThirdDoorApiTypeEnum; -import com.bsd.pjcloud.thirdparty.constant.door.ThordDoorApiTypeEnum; +import com.bsd.pjcloud.thirdparty.constant.door.ThirdDoorBizTypeEnum; import com.bsd.pjcloud.thirdparty.entity.door.ThirdDoorLogEntity; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.Map; - public class DoorApi { // 设备注册 - public static final Api REGISTER = Api.builder().url("/ams/api/device/register").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final Api REGISTER = Api.builder().url("/ams/api/device/register").bizType(ThirdDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); // 设备信息绑定 - public static final Api BIND = Api.builder().url("/ams/api/device/bind").bizType(ThordDoorApiTypeEnum.BIND).method("post").contentType("application/json").build(); + public static final Api BIND = Api.builder().url("/ams/api/device/bind").bizType(ThirdDoorApiTypeEnum.BIND).method("post").contentType("application/json").build(); // 查询设备状态 - public static final Api STATUS = Api.builder().url("/ams/api/device/status").bizType(ThordDoorApiTypeEnum.STATUS).method("post").contentType("application/json").build(); + public static final Api STATUS = Api.builder().url("/ams/api/device/status").bizType(ThirdDoorApiTypeEnum.STATUS).method("post").contentType("application/json").build(); // 设备重启 - public static final Api RESTART = Api.builder().url("/ams/api/device/restart").bizType(ThordDoorApiTypeEnum.RESTART).method("post").contentType("application/json").build(); + public static final Api RESTART = Api.builder().url("/ams/api/device/restart").bizType(ThirdDoorApiTypeEnum.RESTART).method("post").contentType("application/json").build(); // 设备设置 - public static final Api SETTING = Api.builder().url("/ams/api/device/setting").bizType(ThordDoorApiTypeEnum.SETTING).method("post").contentType("application/json").build(); + public static final Api SETTING = Api.builder().url("/ams/api/device/setting").bizType(ThirdDoorApiTypeEnum.SETTING).method("post").contentType("application/json").build(); // 音量设置 - public static final Api VOLUME = Api.builder().url("/ams/api/device/volume").bizType(ThordDoorApiTypeEnum.VOLUME).method("post").contentType("application/json").build(); + public static final Api VOLUME = Api.builder().url("/ams/api/device/volume").bizType(ThirdDoorApiTypeEnum.VOLUME).method("post").contentType("application/json").build(); // 请求开锁 - public static final Api OPEN = Api.builder().url("/ams/api/event/open").bizType(ThordDoorApiTypeEnum.OPEN).method("post").contentType("application/json").build(); + public static final Api OPEN = Api.builder().url("/ams/api/event/open").bizType(ThirdDoorApiTypeEnum.OPEN).method("post").contentType("application/json").build(); // 调取另一个摄像头视频 - public static final Api VIDEO = Api.builder().url("/ams/api/event/video").bizType(ThordDoorApiTypeEnum.VIDEO).method("post").contentType("application/json").build(); + public static final Api VIDEO = Api.builder().url("/ams/api/event/video").bizType(ThirdDoorApiTypeEnum.VIDEO).method("post").contentType("application/json").build(); // 门锁开关通知 - public static final Api OPEN_CALLBACK = Api.builder().url("/door/callback/open").bizType(ThordDoorApiTypeEnum.OPEN_CALLBACK).method("post").contentType("application/json").build(); + public static final Api OPEN_CALLBACK = Api.builder().url("/door/callback/open").bizType(ThirdDoorApiTypeEnum.OPEN_CALLBACK).method("post").contentType("application/json").build(); // 视频地址通知 - public static final Api VIDEO_CALLBACK = Api.builder().url("/door/callback/video").bizType(ThordDoorApiTypeEnum.VIDEO_CALLBACK).method("post").contentType("application/json").build(); + public static final Api VIDEO_CALLBACK = Api.builder().url("/door/callback/video").bizType(ThirdDoorApiTypeEnum.VIDEO_CALLBACK).method("post").contentType("application/json").build(); // 设备状态通知 - public static final Api STATUS_CALLBACK = Api.builder().url("/door/callback/status").bizType(ThordDoorApiTypeEnum.STATUS_CALLBACK).method("post").contentType("application/json").build(); + public static final Api STATUS_CALLBACK = Api.builder().url("/door/callback/status").bizType(ThirdDoorApiTypeEnum.STATUS_CALLBACK).method("post").contentType("application/json").build(); @Data @Builder @@ -62,9 +60,9 @@ public class DoorApi { private String contentType; - private ThirdDoorApiTypeEnum apiType = ThirdDoorApiTypeEnum.DOOR_API; + private ThirdDoorBizTypeEnum apiType = ThirdDoorBizTypeEnum.DOOR_API; - private ThordDoorApiTypeEnum bizType; + private ThirdDoorApiTypeEnum bizType; public Api setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; @@ -82,7 +80,7 @@ public class DoorApi { } public ThirdDoorLogEntity getInitLogEntity() { - if (ObjectUtil.isEmpty(this.apiType)) this.setApiType(ThirdDoorApiTypeEnum.DOOR_API); + if (ObjectUtil.isEmpty(this.apiType)) this.setApiType(ThirdDoorBizTypeEnum.DOOR_API); ThirdDoorLogEntity entity = new ThirdDoorLogEntity(); entity.setBizId(null); entity.setBizType(bizType.getType()); diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/api/KsApi.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/api/KsApi.java index 895ea6df..cb17e8f6 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/api/KsApi.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/api/KsApi.java @@ -2,52 +2,61 @@ package com.bsd.pjcloud.thirdparty.utils.ks.api; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.http.HttpRequest; -import com.bsd.pjcloud.thirdparty.constant.door.ThirdDoorApiTypeEnum; -import com.bsd.pjcloud.thirdparty.constant.door.ThordDoorApiTypeEnum; +import com.bsd.pjcloud.thirdparty.constant.door.ThirdDoorBizTypeEnum; +import com.bsd.pjcloud.thirdparty.constant.door.ThirdDoorKsApiTypeEnum; import com.bsd.pjcloud.thirdparty.entity.door.ThirdDoorLogEntity; +import com.bsd.pjcloud.thirdparty.utils.ks.tool.KsRetailSignUtils; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.TreeMap; @Slf4j public class KsApi { // 常规SKU提交审核 - public static final KsApi.Api SKU_SUBMIT = KsApi.Api.builder().url("/openapi/sc/v1/sku").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final KsApi.Api SKU_SUBMIT = KsApi.Api.builder().url("/openapi/sc/v1/sku").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPost.METHOD_NAME).contentType("application/json").build(); // 集合SKU提交审核(未公开) - public static final KsApi.Api SKU_SUBMIT_COLLECTION = KsApi.Api.builder().url("/openapi/sc/v1/sku/collection").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final KsApi.Api SKU_SUBMIT_COLLECTION = KsApi.Api.builder().url("/openapi/sc/v1/sku/collection").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPost.METHOD_NAME).contentType("application/json").build(); // SKU审核结果主动获取 - public static final KsApi.Api SKU_RESULT = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final KsApi.Api SKU_RESULT = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPost.METHOD_NAME).contentType("application/json").build(); // 常规SKU修改 - public static final KsApi.Api SKU_EDIT = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("patch").contentType("application/json").build(); + public static final KsApi.Api SKU_EDIT = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPatch.METHOD_NAME).contentType("application/json").build(); // SKU删除 - public static final KsApi.Api SKU_DELETE = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("delete").contentType("application/json").build(); + public static final KsApi.Api SKU_DELETE = KsApi.Api.builder().url("/openapi/sc/v1/sku/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpDelete.METHOD_NAME).contentType("application/json").build(); // 根据69码查询标准库和私有库商品信息 - public static final KsApi.Api BARCODE_SKU = KsApi.Api.builder().url("/openapi/sc/v1/sku/all_sku/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("get").contentType("application/json").build(); + public static final KsApi.Api BARCODE_SKU = KsApi.Api.builder().url("/openapi/sc/v1/sku/all_sku/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpGet.METHOD_NAME).contentType("application/json").build(); // 根据ks_sku_id查询标准库和私有库商品信息 - public static final KsApi.Api BARCODE_SKU_BY_ID = KsApi.Api.builder().url("/openapi/sc/v1/sku/skus/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("get").contentType("application/json").build(); + public static final KsApi.Api BARCODE_SKU_BY_ID = KsApi.Api.builder().url("/openapi/sc/v1/sku/skus/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpGet.METHOD_NAME).contentType("application/json").build(); // 模糊查询标准库和私有库商品信息 - public static final KsApi.Api BARCODE_SKU_LIKE = KsApi.Api.builder().url("/openapi/sc/v1/sku/sku_list/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("get").contentType("application/json").build(); + public static final KsApi.Api BARCODE_SKU_LIKE = KsApi.Api.builder().url("/openapi/sc/v1/sku/sku_list").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpGet.METHOD_NAME).contentType("application/json").build(); // SKU提交识别 - public static final KsApi.Api RECOGNITION = KsApi.Api.builder().url("/openapi/sc/v1/recognition/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final KsApi.Api RECOGNITION = KsApi.Api.builder().url("/openapi/sc/v1/recognition/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPost.METHOD_NAME).contentType("application/json").build(); // SKU识别结果主动获取 - public static final KsApi.Api RECOGNITION_RESULT = KsApi.Api.builder().url("/openapi/sc/v1/recognition/%s").bizType(ThordDoorApiTypeEnum.REGISTER).method("post").contentType("application/json").build(); + public static final KsApi.Api RECOGNITION_RESULT = KsApi.Api.builder().url("/openapi/sc/v1/recognition/%s").bizType(ThirdDoorKsApiTypeEnum.REGISTER).method(HttpPost.METHOD_NAME).contentType("application/json").build(); @Data @Builder @@ -58,15 +67,26 @@ public class KsApi { private String url; - private Map params; + private Map params = new TreeMap<>(); + + private String body; private String method; private String contentType; - private ThirdDoorApiTypeEnum apiType = ThirdDoorApiTypeEnum.DISCERN_API; + private ThirdDoorBizTypeEnum apiType = ThirdDoorBizTypeEnum.DISCERN_API; - private ThordDoorApiTypeEnum bizType; + private ThirdDoorKsApiTypeEnum bizType; + + private String accessKey; + + private String secretKey; + + private String host = ""; + + + private String requestId; public KsApi.Api setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; @@ -78,35 +98,89 @@ public class KsApi { return this; } - public HttpRequest getHttpRequest() { - String fullPatch = baseUrl + url; - if (ObjectUtil.isNotEmpty(params)) { - StringBuilder query = new StringBuilder(); - for (Map.Entry entry : params.entrySet()) { + public KsApi.Api setAccessKey(String accessKey) { + this.accessKey = accessKey; + return this; + } + + public KsApi.Api setSecretKey(String secretKey) { + this.secretKey = secretKey; + return this; + } + + public KsApi.Api setHost(String host) { + this.host = host; + return this; + } + + /** + * 获取当前时间戳 + */ + public Long getXRequestDate() { + return System.currentTimeMillis(); + } + + public String getQueryString() { + if (ObjectUtil.isEmpty(params)) return null; + StringBuilder query = new StringBuilder(); + for (Map.Entry entry : params.entrySet()) { + if (ObjectUtil.isNotEmpty(query)) query.append("&"); + if (ObjectUtil.isNotEmpty(entry.getValue())) { query.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)).append("=").append(URLEncoder.encode(String.valueOf(entry.getValue()), StandardCharsets.UTF_8)); } + } + return query.toString(); + } + + /** + * 获取header + */ + public Map> getHeader() { + // 初始化数据 + if (ObjectUtil.isEmpty(getBody())) setBody(""); + if (ObjectUtil.isEmpty(getParams())) setParams(new TreeMap<>()); + // 计算签名 + Long currentTime = getXRequestDate(); + String queryString = getQueryString(); + String auth = KsRetailSignUtils.getSignAuth(getHost(), getUrl(), contentType, getMethod(), currentTime, getAccessKey(), getSecretKey(), getBody(), queryString); + String requestId = getXRequestDate() + RandomUtil.randomString(19); + setRequestId(requestId); + Map> header = new HashMap<>(); + header.put("Authorization", List.of(auth)); + header.put("Content-Type", List.of(getContentType())); + header.put("X-Request-Date", List.of(String.valueOf(getXRequestDate()))); + header.put("X-Request-id", List.of(requestId)); + header.put("Referer", List.of("https://" + getHost())); + return header; + } + + public HttpRequest getHttpRequest() { + String fullPatch = baseUrl + url; + String query = getQueryString(); + if (ObjectUtil.isNotEmpty(query)) { fullPatch = fullPatch + "?" + query; } - if (ObjectUtil.equals(method, "post")) { - return HttpRequest.post(fullPatch).contentType(contentType); - } else if (ObjectUtil.equals(method, "get")) { - return HttpRequest.get(fullPatch).contentType(contentType); - } else if (ObjectUtil.equals(method, "patch")) { - return HttpRequest.patch(fullPatch).contentType(contentType); - } else if (ObjectUtil.equals(method, "delete")) { - return HttpRequest.delete(fullPatch).contentType(contentType); + if (ObjectUtil.equals(method, HttpPost.METHOD_NAME)) { + return HttpRequest.post(fullPatch).header(getHeader()).body(getBody()); + } else if (ObjectUtil.equals(method, HttpGet.METHOD_NAME)) { + return HttpRequest.get(fullPatch).header(getHeader()); + } else if (ObjectUtil.equals(method, HttpPatch.METHOD_NAME)) { + return HttpRequest.patch(fullPatch).header(getHeader()).body(getBody()); + } else if (ObjectUtil.equals(method, HttpDelete.METHOD_NAME)) { + return HttpRequest.delete(fullPatch).header(getHeader()).body(getBody()); } else { return null; } } public ThirdDoorLogEntity getInitLogEntity() { - if (ObjectUtil.isEmpty(this.apiType)) this.setApiType(ThirdDoorApiTypeEnum.DISCERN_API); + if (ObjectUtil.isEmpty(this.apiType)) this.setApiType(ThirdDoorBizTypeEnum.DISCERN_API); ThirdDoorLogEntity entity = new ThirdDoorLogEntity(); entity.setBizId(null); entity.setBizType(bizType.getType()); entity.setApiType(apiType.getType()); entity.setApiUrl(url); + entity.setRequestId(getRequestId()); return entity; } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsMD5Encryption.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsMD5Encryption.java new file mode 100644 index 00000000..3a5814ad --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsMD5Encryption.java @@ -0,0 +1,101 @@ +package com.bsd.pjcloud.thirdparty.utils.ks.tool; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class KsMD5Encryption { + private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + + + /*** + * 对指定的字符串进行MD5加密 + */ + public static String encrypByMD5(String originString) { + try { + //创建具有MD5算法的信息摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 + byte[] bytes = md.digest(originString.getBytes()); + //将得到的字节数组变成字符串返回 + String s = byteArrayToHex(bytes); + return s.toUpperCase(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 使用 HMAC-SHA1 签名方法对对encryptText进行签名 + * + * @param encryptText 被签名的字符串 + * @param encryptKey 密钥 + * @return + * @throws Exception + */ + public static String encrypByHMACSHA1(String encryptText, String encryptKey) { + try { + byte[] data = encryptKey.getBytes(StandardCharsets.UTF_8); + //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 + SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1"); + //生成一个指定 Mac 算法 的 Mac 对象 + Mac mac = Mac.getInstance("HmacSHA1"); + //用给定密钥初始化 Mac 对象 + mac.init(secretKey); + byte[] text = encryptText.getBytes(StandardCharsets.UTF_8); + //完成 Mac 操作 + String s = byteArrayToHex(mac.doFinal(text)); + return s; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /*** + * 对指定的字符串进行MD5加密 + */ + public static String encrypBySHA1(String originString) { + try { + //创建具有MD5算法的信息摘要 + MessageDigest md = MessageDigest.getInstance("SHA1"); + //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 + byte[] bytes = md.digest(originString.getBytes()); + //将得到的字节数组变成字符串返回 + String s = byteArrayToHex(bytes); + return s.toUpperCase(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 将字节数组转换成十六进制,并以字符串的形式返回 + * 128位是指二进制位。二进制太长,所以一般都改写成16进制, + * 每一位16进制数可以代替4位二进制数,所以128位二进制数写成16进制就变成了128/4=32位。 + */ + public static String byteArrayToHex(byte[] b) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < b.length; i++) { + sb.append(byteToHex(b[i])); + } + return sb.toString(); + } + + /** + * 将一个字节转换成十六进制,并以字符串的形式返回 + */ + public static String byteToHex(byte b) { + int n = b; + if (n < 0) + n = n + 256; + int d1 = n / 16; + int d2 = n % 16; + return hexArray[d1] + hexArray[d2]; + } +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsRetailSignUtils.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsRetailSignUtils.java new file mode 100644 index 00000000..5e995f20 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/ks/tool/KsRetailSignUtils.java @@ -0,0 +1,56 @@ +package com.bsd.pjcloud.thirdparty.utils.ks.tool; + + +import lombok.extern.slf4j.Slf4j; + +import java.nio.charset.StandardCharsets; + +@Slf4j +public class KsRetailSignUtils { + + private static final String ALGORITHM = "HMAC-SHA1"; + + public static String getSignAuth(String host, String uri, String contentType, String methodType, long timeMillis, String ak, String sk, String body, String queryString) { + log.info("host={}, uri={}, contentType={}, methodType={}, timeMillis={}, ak={}, sk={}, body={}, queryString={}", host, uri, contentType, methodType, timeMillis, ak, sk, body, queryString); + String signedHeaders = getSignedHeaders(host, contentType, timeMillis); + log.info("signedHeaders = {}", signedHeaders); + String payloadHex = getMD5Hex(body); + log.info("payloadHex = {}", payloadHex); + String request = getRequest(methodType, uri, queryString, signedHeaders, payloadHex); + log.info("request = {}", request); + String requextHex = getSHA1Hex(request); + log.info("requextHex = {}", requextHex); + String stringToSign = getStringToSign(ALGORITHM, requextHex); + log.info("stringToSign = {}", stringToSign); + String signature = getSignature(stringToSign, sk); + log.info("signature = {}", signature); + String auth = KsMD5Encryption.encrypByHMACSHA1(stringToSign, sk); + log.info("auth = {}", auth); + return String.format("%s %s:%s", ALGORITHM, ak, signature); + } + private static String getSignedHeaders(String host, String contentType, long time) { + return host.toLowerCase() + ";" + contentType.toLowerCase() + ";" + String.valueOf(time).toLowerCase(); + } + + private static String getMD5Hex(String payload) { + String payloadUtf8 = new String(payload.getBytes(), StandardCharsets.UTF_8); + return KsMD5Encryption.encrypByMD5(payloadUtf8).toLowerCase(); + } + + private static String getSHA1Hex(String request) { + String requestUtf8 = new String(request.getBytes(), StandardCharsets.UTF_8); + return KsMD5Encryption.encrypBySHA1(requestUtf8).toLowerCase(); + } + + private static String getRequest(String httpRequestMethod, String uri, String queryString, String signHeaders, String hex) { + return httpRequestMethod + "\n" + uri + "\n" + queryString + "\n" + signHeaders + "\n" + hex; + } + + private static String getStringToSign(String algorithm, String requextHex) { + return algorithm + "\n" + requextHex; + } + + private static String getSignature(String stringToSign, String sk) { + return KsMD5Encryption.encrypByHMACSHA1(stringToSign, sk); + } +} 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 0dca5d90..8bfcee7f 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -80,9 +80,11 @@ door: # 旷世识别 ks-discern: - base-url: https://gwycport.zj.gov.cn + base-url: https://retail.xlsdn.com access-key: ed5A923eF0e941A1968eGTpF secret-key: Ex3X0kgoc94sBOtivjWm5Vz9AyZTOUpl + host: retail.xlsdn.com +