From 773813c26995df79f4cef8e3932abf75090f4594 Mon Sep 17 00:00:00 2001 From: "shuo.wang" Date: Fri, 11 Apr 2025 16:10:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/entity/HyPartnerUserInfoDO.java | 2 +- .../cool/store/request/ZxjpApiRequest.java | 3 + .../cool/store/response/XgjBaseResponse.java | 18 ++ .../response/XgjOrganizationResponse.java | 22 +++ .../com/cool/store/service/PushService.java | 4 + .../store/service/impl/PushServiceImpl.java | 181 ++++++++++++++++-- .../service/impl/SyncDataServiceImpl.java | 1 + .../cool/store/config/SignValidateFilter.java | 3 +- .../webb/PCOrderSysInfoController.java | 15 +- .../controller/webb/PCTestController.java | 8 + .../resources/application-online.properties | 5 + .../resources/application-test.properties | 4 + 12 files changed, 249 insertions(+), 17 deletions(-) create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/XgjBaseResponse.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/XgjOrganizationResponse.java diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java index d90bc3bb9..6f1e196a2 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/HyPartnerUserInfoDO.java @@ -59,6 +59,6 @@ public class HyPartnerUserInfoDO implements Serializable { private String downstreamSystemPassword; @ApiModelProperty("下游系统第二密码") - @Column(name = "downstream_system_Secondary_password") + @Column(name = "downstream_system_secondary_password") private String downstreamSystemSecondaryPassword; } \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/ZxjpApiRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/ZxjpApiRequest.java index c2169da68..5d3bc419d 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/request/ZxjpApiRequest.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/ZxjpApiRequest.java @@ -50,6 +50,9 @@ public class ZxjpApiRequest { @ApiModelProperty(value = "下游系统密码盐值") private String downstreamSystemSalt; + @ApiModelProperty(value = "第二密码") + private String downstreamSystemSecondaryPassword; + @ApiModelProperty(value = "下游系统店铺名称") private String downstreamSystemShopName; diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/XgjBaseResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/XgjBaseResponse.java new file mode 100644 index 000000000..4ab0a4339 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/XgjBaseResponse.java @@ -0,0 +1,18 @@ +package com.cool.store.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * @Author: WangShuo + * @Date: 2025/04/11/10:57 + * @Version 1.0 + * @注释: + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class XgjBaseResponse { + private String retMsg; + private int retCode; + private T retData; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/XgjOrganizationResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/XgjOrganizationResponse.java new file mode 100644 index 000000000..a4764e887 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/XgjOrganizationResponse.java @@ -0,0 +1,22 @@ +package com.cool.store.response; + +import com.cool.store.dto.XgjOrganizationDTO; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @Author: WangShuo + * @Date: 2025/04/11/13:38 + * @Version 1.0 + * @注释: + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class XgjOrganizationResponse { + List list; +} \ No newline at end of file diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/PushService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/PushService.java index ed036559a..b5f406259 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/PushService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/PushService.java @@ -2,8 +2,11 @@ package com.cool.store.service; import com.cool.store.dto.GetAccessTokenDTO; import com.cool.store.dto.ModifyPasswordDTO; +import com.cool.store.dto.XgjOrganizationDTO; import com.cool.store.request.ZxjpApiRequest; +import java.util.List; + /** * @Author suzhuhong * @Date 2025/4/9 14:23 @@ -55,6 +58,7 @@ public interface PushService { */ String getPosToken(GetAccessTokenDTO dto); + List getXgjOrganization(String partnerId); diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PushServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PushServiceImpl.java index d5950d941..13e3ec9ea 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PushServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PushServiceImpl.java @@ -3,14 +3,20 @@ package com.cool.store.service.impl; import com.alibaba.fastjson.JSONObject; import com.cool.store.dto.GetAccessTokenDTO; import com.cool.store.dto.ModifyPasswordDTO; +import com.cool.store.dto.XgjOrganizationDTO; import com.cool.store.enums.ErrorCodeEnum; import com.cool.store.exception.ServiceException; import com.cool.store.request.ZxjpApiRequest; +import com.cool.store.response.XgjBaseResponse; +import com.cool.store.response.XgjOrganizationResponse; import com.cool.store.response.huoma.ShopBaseInfoResponse; import com.cool.store.response.oppty.OpportunityApiResponse; import com.cool.store.service.PushService; import com.cool.store.utils.HmacSigner; +import com.cool.store.utils.RedisUtilPool; +import com.cool.store.utils.poi.StringUtils; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; @@ -19,7 +25,12 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * @Author suzhuhong @@ -32,6 +43,9 @@ public class PushServiceImpl implements PushService { // TODO: 2025/4/9 suzhuhong_ + @Value("${spring.profiles.active}") + private String active; + @Value("${api.auth.url}") private String url; @@ -74,27 +88,39 @@ public class PushServiceImpl implements PushService { ObjectMapper objectMapper; + @Value("${xgj.open.organization.X-key}") + private String xgjOpenOrganizationXKey; + @Value("${xgj.open.organization.X-Secret}") + private String xgjOpenOrganizationXSecret; + @Value("${xgj.open.organization.url}") + private String xgjOpenOrganizationUrl; + @Resource + private RedisUtilPool redisUtilPool; + + @Value("${mybatis.configuration.variables.enterpriseId}") + private String eid; + @Override public Boolean pushDataToXGJ(ZxjpApiRequest zxjpApiRequest) { String apiUrl = xgjUrl + "XXX"; - return executeApiCall(apiUrl,zxjpApiRequest, Boolean.class,xgjUsername,xgjSecret); + return executeApiCall(apiUrl, zxjpApiRequest, Boolean.class, xgjUsername, xgjSecret); } @Override public Boolean pushDataToPOS(ZxjpApiRequest zxjpApiRequest) { String apiUrl = url + "/dzgV1/zxcrm/shop/upsert"; - return executeApiCall(apiUrl,zxjpApiRequest, Boolean.class,username,secret); + return executeApiCall(apiUrl, zxjpApiRequest, Boolean.class, username, secret); } private Boolean modifyXGJPassword(ModifyPasswordDTO dto) { String apiUrl = xgjUrl + "XXX"; - return executeApiCall(apiUrl,dto, Boolean.class,xgjUsername,xgjSecret); + return executeApiCall(apiUrl, dto, Boolean.class, xgjUsername, xgjSecret); } - private Boolean modifyPosPassword(ModifyPasswordDTO dto) { + private Boolean modifyPosPassword(ModifyPasswordDTO dto) { String apiUrl = url + "/dzgV1/zxcrm/business_user/modifyPassword"; - return executeApiCall(apiUrl,dto, Boolean.class,username,secret); + return executeApiCall(apiUrl, dto, Boolean.class, username, secret); } @@ -112,28 +138,56 @@ public class PushServiceImpl implements PushService { @Override public String getYlsToken(GetAccessTokenDTO dto) { String apiUrl = url + "XXX"; - return executeApiCall(apiUrl,dto, String.class,ylsUsername,ylsSecret); + return executeApiCall(apiUrl, dto, String.class, ylsUsername, ylsSecret); } @Override public String getXzgToken(GetAccessTokenDTO dto) { String apiUrl = url + "XXX"; - return executeApiCall(apiUrl,dto, String.class,xzgUsername,xzgSecret); + return executeApiCall(apiUrl, dto, String.class, xzgUsername, xzgSecret); } @Override public String getPosToken(GetAccessTokenDTO dto) { String apiUrl = url + "/dzgV1/zxcrm/business_user/generateToken"; - return executeApiCall(apiUrl,dto, String.class,username,secret); + return executeApiCall(apiUrl, dto, String.class, username, secret); + } + + @Override + public List getXgjOrganization(String partnerId) { + String key = active+"_XgjOrganization_" + eid; + String resObject = redisUtilPool.getString(key); + if (StringUtils.isBlank(resObject)) { + String apiUrl = xgjOpenOrganizationUrl + "/open/organization"; + resObject = JSONObject.toJSONString(executeApiGetCall(apiUrl, null, Object.class, xgjOpenOrganizationXKey, xgjOpenOrganizationXSecret)); + redisUtilPool.setNxExpire(key, resObject, 7200000); + } + List response = new ArrayList<>(); + if (StringUtils.isNotBlank(resObject)) { + // 使用 Jackson 将 Object 转换为目标类型 + ObjectMapper objectMapper = new ObjectMapper(); + try { + response = objectMapper.readValue(resObject, new TypeReference>() { + }); + } catch (JsonProcessingException e) { + throw new ServiceException("数据类型转化异常: " + e.getMessage()); + } + + } + List filteredList = response.stream() + .filter(customer -> customer.getParentId().equals(partnerId)) + .collect(Collectors.toList()); + return filteredList; + } - private T executeApiCall(String url, Object requestBody, Class responseType,String username,String secret) { + private T executeApiCall(String url, Object requestBody, Class responseType, String username, String secret) { // 1. 打印请求前日志 logRequest(url, requestBody); try { - Request request = buildRequest(requestBody, url,username,secret); + Request request = buildRequest(requestBody, url, username, secret); try (Response response = okHttpClient.newCall(request).execute()) { // 2. 获取原始响应内容 @@ -218,7 +272,7 @@ public class PushServiceImpl implements PushService { } - private Request buildRequest(Object requestBody, String url,String username,String secret) { + private Request buildRequest(Object requestBody, String url, String username, String secret) { try { Map authHeaders = HmacSigner.generateHeaders( @@ -244,8 +298,113 @@ public class PushServiceImpl implements PushService { } } + private T executeApiGetCall(String url, Map requestParams, Class responseType, String username, String secret) { + //1.处理请求参数 + String buildUrlWithParams = buildUrlWithParams(url, requestParams); + // 2. 打印请求前日志 + logRequest(buildUrlWithParams, requestParams); + + try { + Request request = buildGetRequest(url, username, secret); + + try (Response response = okHttpClient.newCall(request).execute()) { + // 2. 获取原始响应内容 + String responseBody = null; + if (response.body() != null) { + responseBody = response.body().string(); + } + + // 3. 打印响应日志 + logResponse(url, response.code(), responseBody); + + if (!response.isSuccessful()) { + throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, + "HTTP请求失败,状态码: " + response.code()); + } + + // 4. 解析响应 + JavaType javaType = objectMapper.getTypeFactory() + .constructParametricType(XgjBaseResponse.class, responseType); + + XgjBaseResponse apiResponse = objectMapper.readValue(responseBody, javaType); + + if (apiResponse.getRetCode() != 200) { + throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, + "业务逻辑错误: " + apiResponse.getRetMsg()); + } + + return apiResponse.getRetData(); + } + } catch (ServiceException e) { + throw e; + } catch (Exception e) { + log.error("API调用异常 - URL: {}, 错误: {}", url, e.getMessage(), e); + throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, "接口调用异常: " + e.getMessage()); + } + } + + private Request buildGetRequest(String url, String username, String secret) { + + try { +// Map authHeaders = HmacSigner.generateHeaders( +// username, secret,null); + +// log.debug("签名生成 - 签名结果: {}", JSONObject.toJSONString(authHeaders)); + return new Request.Builder() + .url(url) + .get() + .addHeader("Content-Type", "application/json") + .addHeader("Accept", "application/json") + .addHeader("X-Key", username) + .addHeader("X-Secret", secret) + .build(); + } catch (Exception e) { + throw new ServiceException(ErrorCodeEnum.THIRD_API_SIGN_ERROR); + } + } + + public String buildUrlWithParams(String baseUrl, Map requestParams) { + if (requestParams == null || requestParams.isEmpty()) { + // 如果没有参数,直接返回基础 URL + return baseUrl; + } + + StringBuilder urlBuilder = new StringBuilder(baseUrl); + + // 检查是否需要添加 "?" 或 "&" + if (!baseUrl.contains("?")) { + urlBuilder.append("?"); + } else if (!baseUrl.endsWith("&")) { + urlBuilder.append("&"); + } + + try { + // 遍历参数并拼接 + for (Map.Entry entry : requestParams.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value != null) { + // 对键和值进行 URL 编码 + urlBuilder.append(URLEncoder.encode(key, "UTF-8")) + .append("=") + .append(URLEncoder.encode(value.toString(), "UTF-8")) + .append("&"); + } + } + + // 删除最后一个多余的 "&" + if (urlBuilder.charAt(urlBuilder.length() - 1) == '&') { + urlBuilder.deleteCharAt(urlBuilder.length() - 1); + } + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Error encoding URL parameters", e); + } + + return urlBuilder.toString(); + } } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncDataServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncDataServiceImpl.java index 2a4f06fcf..46ed56270 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncDataServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncDataServiceImpl.java @@ -112,6 +112,7 @@ public class SyncDataServiceImpl implements SyncDataService { request.setCrmAccount(lineInfoDO.getMobile()); request.setDownstreamSystemPassword(hyPartnerUserInfoDO.getDownstreamSystemPassword()); request.setDownstreamSystemSalt(hyPartnerUserInfoDO.getDownstreamSystemSalting()); + request.setDownstreamSystemSecondaryPassword(hyPartnerUserInfoDO.getDownstreamSystemSecondaryPassword()); if (StringUtils.isNotBlank(shopInfo.getFranchiseBrand())) { String[] split = shopInfo.getFranchiseBrand().split(Constants.COMMA); request.setFranchiseBrand(split[0]); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java b/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java index d96af4e4a..44b826e8d 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java @@ -59,7 +59,8 @@ public class SignValidateFilter implements Filter { "/zxjp/mini/program/v1/partnerManage/openArea/areaApplyQuery", "/zxjp/**/api/audit/result", "/zxjp/**/api/license", - "/zxjp/mini/line/getRegionPayPic" + "/zxjp/mini/line/getRegionPayPic", + "/zxjp/mini/**" ); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCOrderSysInfoController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCOrderSysInfoController.java index e663b84de..2ac36d2a3 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCOrderSysInfoController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCOrderSysInfoController.java @@ -5,13 +5,11 @@ import com.cool.store.enums.OrderSysTypeEnum; import com.cool.store.request.OrderSysInfoRequest; import com.cool.store.response.ResponseResult; import com.cool.store.service.OrderSysInfoService; +import com.cool.store.service.PushService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -28,6 +26,8 @@ public class PCOrderSysInfoController { @Resource private OrderSysInfoService orderSysInfoService; + @Resource + private PushService pushService; @PostMapping("/submitOrderInfo") @ApiOperation("物流提交订货信息") @@ -42,4 +42,11 @@ public class PCOrderSysInfoController { request.setType(OrderSysTypeEnum.ORDER_SYS_TYPE_2.getType()); return ResponseResult.success(orderSysInfoService.updateByShopId(request, CurrentUserHolder.getUserId())); } + + @GetMapping("/getXgjOrganization") + @ApiOperation("获取新管家组织架构") + public ResponseResult getXgjOrganization(@RequestParam(value = "partnerId", required = true,defaultValue = "0") String partnerId) { + return ResponseResult.success(pushService.getXgjOrganization(partnerId)); + } + } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java index 7a92d6420..0ee93fad9 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java @@ -32,6 +32,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.annotations.Param; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -258,6 +259,13 @@ public class PCTestController { return ResponseResult.success(shopAccountDAO.initShopAccount(hyPartnerUserInfoDO,Arrays.asList(shopId))); } + @Resource + private PushService pushService; + @GetMapping("/getXgjOrganization") + @ApiOperation("获取新管家组织架构") + public ResponseResult getXgjOrganization(@RequestParam(value = "partnerId", required = true,defaultValue = "0") String partnerId) { + return ResponseResult.success(pushService.getXgjOrganization(partnerId)); + } @Resource diff --git a/coolstore-partner-web/src/main/resources/application-online.properties b/coolstore-partner-web/src/main/resources/application-online.properties index d3e67b460..c5cbbdffc 100644 --- a/coolstore-partner-web/src/main/resources/application-online.properties +++ b/coolstore-partner-web/src/main/resources/application-online.properties @@ -82,6 +82,11 @@ enterprise.dingCorpId=wpayJeDAAAklx_q1jGhyGUd4yEh8vV_g qywx.task.notice.url2=https://store-h5.coolstore.cn/?corpId=%s&appType=%s#/notice?target=%s¬iceType=zx&corpId=%s&appType=%s&eid=%s +xgj.open.organization.X-key = 2677a58dd9e24fc6b20e835ef5f19e63 +xgj.open.organization.X-Secret = 3fe724f9607448728ee3393eff75718a +xgj.open.organization.url = https://masterdata.zhengxinfood.com/dmp/one-id + + api.auth.url=https://api.zhengxindzg.cn api.auth.username=GkqgAhUJ7p9swJo diff --git a/coolstore-partner-web/src/main/resources/application-test.properties b/coolstore-partner-web/src/main/resources/application-test.properties index 892e14608..b9ba98cb0 100644 --- a/coolstore-partner-web/src/main/resources/application-test.properties +++ b/coolstore-partner-web/src/main/resources/application-test.properties @@ -115,3 +115,7 @@ xzg.api.auth.secret=**** cool.api.appKey=k8J7fG2qR5tY9vX3 cool.api.secret=wP4sN6dL8zK2xM9c + +xgj.open.organization.X-key = 2677a58dd9e24fc6b20e835ef5f19e63 +xgj.open.organization.X-Secret = 3fe724f9607448728ee3393eff75718a +xgj.open.organization.url = http://117.139.13.24:11180/dmp/one-id