feat:云流水
This commit is contained in:
@@ -252,6 +252,7 @@ public enum ErrorCodeEnum {
|
||||
SYSTEM_DATA_ERROR(151004,"平台账号不能为空",null),
|
||||
CURRENT_STATUS_NOT_OPERATION(151005,"平台账号当前非审核状态!不能提交审核",null),
|
||||
CURRENT_ENTRY_STATUS_NOT_OPERATION(151006,"进件状态未审核!不能执行该操作",null),
|
||||
GET_YLS_CODE_FAIL(151006,"系统无云流水编码!无法获取TOKEN!请先维护该编码",null),
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -81,10 +81,9 @@ public class ServiceException extends RuntimeException{
|
||||
}
|
||||
|
||||
public ServiceException(ErrorCodeEnum responseEnum, Object... objects) {
|
||||
super(responseEnum.getMessage());
|
||||
String message = MessageFormat.format(responseEnum.getMessage(), objects);
|
||||
super(MessageFormat.format(responseEnum.getMessage(), objects));
|
||||
this.errorCode = responseEnum.getCode();
|
||||
this.errorMessage = message;
|
||||
this.errorMessage = super.getMessage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ public class HmacSigner {
|
||||
}
|
||||
|
||||
private static String hmacSha256(String secret, String data) throws Exception {
|
||||
if (StringUtil.isEmpty(secret)){
|
||||
return "";
|
||||
}
|
||||
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
|
||||
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM));
|
||||
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
@@ -25,7 +25,7 @@ public class OpenSignatureUtil {
|
||||
// 2. 创建不包含固定参数的临时Map用于排序
|
||||
Map<String, String> sortedParams = new TreeMap<>(
|
||||
params.entrySet().stream()
|
||||
.filter(e -> !"appkey".equals(e.getKey()))
|
||||
.filter(e -> !"appKey".equals(e.getKey()))
|
||||
.filter(e -> !"timestamp".equals(e.getKey()))
|
||||
.filter(e -> !"sign".equals(e.getKey()))
|
||||
.collect(Collectors.toMap(
|
||||
|
||||
@@ -28,4 +28,16 @@ public class OldShopDAO {
|
||||
example.createCriteria().andEqualTo("mobile", mobile);
|
||||
return oldShopMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
||||
public OldShopDO getByCode(String code) {
|
||||
if (StringUtils.isBlank(code)){
|
||||
return null;
|
||||
}
|
||||
Example example = new Example(OldShopDO.class);
|
||||
example.createCriteria().andEqualTo("ylsShopCode", code);
|
||||
example.setOrderByClause("id ASC LIMIT 1");
|
||||
List<OldShopDO> list = oldShopMapper.selectByExample(example);
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.cool.store.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/4/17 15:13
|
||||
* @Version 1.0
|
||||
*/
|
||||
@Data
|
||||
public class AskBotTokenDTO {
|
||||
|
||||
private String shopCode;
|
||||
|
||||
}
|
||||
@@ -14,4 +14,12 @@ public class GetAccessTokenDTO {
|
||||
|
||||
private String shopCode;
|
||||
|
||||
public GetAccessTokenDTO(){
|
||||
|
||||
}
|
||||
|
||||
public GetAccessTokenDTO(String mobile, String shopCode) {
|
||||
this.mobile = mobile;
|
||||
this.shopCode = shopCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ public class OldShopDO {
|
||||
@Column(name = "shop_code")
|
||||
private String shopCode;
|
||||
|
||||
/**
|
||||
* 云流水编码
|
||||
*/
|
||||
@Column(name = "yls_shop_code")
|
||||
private String ylsShopCode;
|
||||
|
||||
@Column(name = "shop_name")
|
||||
private String shopName;
|
||||
|
||||
|
||||
@@ -74,7 +74,9 @@ public interface ShopAccountService {
|
||||
* @param shopId
|
||||
* @return
|
||||
*/
|
||||
String shopCodeToYlsCode(Long shopId);
|
||||
String shopIdToYlsCode(Long shopId);
|
||||
|
||||
String shopCodeToYlsCode(String shopCode);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -78,12 +78,6 @@ public class PushServiceImpl implements PushService {
|
||||
@Value("${xzg.api.auth.url}")
|
||||
private String xzgUrl;
|
||||
|
||||
@Value("${xzg.api.auth.username}")
|
||||
private String xzgUsername;
|
||||
|
||||
@Value("${xzg.api.auth.secret}")
|
||||
private String xzgSecret;
|
||||
|
||||
@Resource
|
||||
OkHttpClient okHttpClient;
|
||||
@Resource
|
||||
@@ -135,7 +129,8 @@ public class PushServiceImpl implements PushService {
|
||||
@Override
|
||||
public String getXzgToken(GetAccessTokenDTO dto) {
|
||||
String apiUrl = xzgUrl + "/api/supply-chain/get-token-byshopcode";
|
||||
return executeApiCall(apiUrl, dto, String.class, xzgUsername, xzgSecret);
|
||||
//不需要验签
|
||||
return executeApiCall(apiUrl, dto, String.class, "", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package com.cool.store.service.impl;
|
||||
|
||||
import com.cool.store.dao.HyPartnerUserInfoDAO;
|
||||
import com.cool.store.dao.ShopAccountDAO;
|
||||
import com.cool.store.dao.ShopInfoDAO;
|
||||
import com.cool.store.dao.ShopStageInfoDAO;
|
||||
import com.cool.store.dao.*;
|
||||
import com.cool.store.dto.AccountAuditDTO;
|
||||
import com.cool.store.dto.AccountEntryStatusAuditDTO;
|
||||
import com.cool.store.dto.ModifyPasswordDTO;
|
||||
import com.cool.store.dto.ShopAccount.ShopAccountDTO;
|
||||
import com.cool.store.dto.AccountEntryStatusChangeDTO;
|
||||
import com.cool.store.entity.HyPartnerUserInfoDO;
|
||||
import com.cool.store.entity.OldShopDO;
|
||||
import com.cool.store.entity.ShopAccountDO;
|
||||
import com.cool.store.entity.ShopInfoDO;
|
||||
import com.cool.store.enums.*;
|
||||
@@ -52,6 +50,8 @@ public class ShopAccountServiceImpl implements ShopAccountService {
|
||||
ShopStageInfoDAO shopStageInfoDAO;
|
||||
@Resource
|
||||
PosAndOrderInfoService posAndOrderInfoService;
|
||||
@Resource
|
||||
OldShopDAO oldShopDAO;
|
||||
|
||||
@Override
|
||||
public List<ShopAccountDTO> getShopAccountByShopId(Long shopId) {
|
||||
@@ -230,7 +230,7 @@ public class ShopAccountServiceImpl implements ShopAccountService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shopCodeToYlsCode(Long shopId) {
|
||||
public String shopIdToYlsCode(Long shopId) {
|
||||
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
|
||||
if (Objects.isNull(shopInfo)){
|
||||
throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
|
||||
@@ -247,5 +247,19 @@ public class ShopAccountServiceImpl implements ShopAccountService {
|
||||
return StringUtil.isEmpty(shopAccountDO.getAccount())?shopInfo.getShopCode():shopAccountDO.getAccount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shopCodeToYlsCode(String shopCode) {
|
||||
ShopInfoDO shopInfoDO = shopInfoDAO.selectByStoreCode(shopCode);
|
||||
if (!Objects.isNull(shopInfoDO)){
|
||||
return this.shopIdToYlsCode(shopInfoDO.getId());
|
||||
}
|
||||
//查询老店关联表数据
|
||||
OldShopDO oldShopDO = oldShopDAO.getByCode(shopCode);
|
||||
if (Objects.isNull(oldShopDO)){
|
||||
throw new ServiceException(ErrorCodeEnum.GET_YLS_CODE_FAIL);
|
||||
}
|
||||
return oldShopDO.getYlsShopCode();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import com.cool.store.constants.CommonConstants;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.cool.store.utils.OpenSignatureUtil;
|
||||
import com.cool.store.utils.StringUtil;
|
||||
import com.cool.store.utils.UUIDUtils;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -48,7 +49,7 @@ public class OpenApiValidateFilter implements Filter {
|
||||
MDC.put(CommonConstants.REQUEST_ID, UUIDUtils.get32UUID());
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
String uri = request.getRequestURI();
|
||||
if(!uri.startsWith("/zxjp/open1")){
|
||||
if(!uri.startsWith("/zxjp/open/v1/getYlsToken")){
|
||||
filterChain.doFilter(servletRequest, response);
|
||||
return;
|
||||
}
|
||||
@@ -60,15 +61,15 @@ public class OpenApiValidateFilter implements Filter {
|
||||
log.info("timestampStr is null {}","缺少timestamp参数");
|
||||
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
|
||||
}
|
||||
|
||||
long timestamp = Long.parseLong(timestampStr)/1000;
|
||||
long currentTime = System.currentTimeMillis()/1000;
|
||||
long timeDiff = Math.abs(currentTime - timestamp);
|
||||
try {
|
||||
long timestamp = Long.parseLong(timestampStr)/1000;
|
||||
long currentTime = System.currentTimeMillis()/1000;
|
||||
long timeDiff = Math.abs(currentTime - timestamp);
|
||||
|
||||
|
||||
if (timeDiff > 600) {
|
||||
log.info("OpenApiValidateFilter==>{}","请求已过期,服务器时间:" + currentTime + " 请求时间:" + timestamp);
|
||||
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,"请求已过期,请保证timestamp时间在10分钟之内");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.info("OpenApiValidateFilter==>{}","非法timestamp格式");
|
||||
@@ -79,12 +80,12 @@ public class OpenApiValidateFilter implements Filter {
|
||||
String appKey = request.getHeader("appkey");
|
||||
if (appKey == null || !coolAppKey.equals(appKey)) {
|
||||
log.info("OpenApiValidateFilter==>{}","无效的appKey");
|
||||
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,"无效的appKey");
|
||||
}
|
||||
|
||||
String clientSign = request.getHeader("sign");
|
||||
if (clientSign == null) {
|
||||
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,"签名校验失败");
|
||||
}
|
||||
// 1. 读取请求体
|
||||
StringBuilder requestBody = new StringBuilder();
|
||||
@@ -103,6 +104,8 @@ public class OpenApiValidateFilter implements Filter {
|
||||
jsonBody,
|
||||
new TypeReference<TreeMap<String, String>>() {}
|
||||
);
|
||||
params.put("appKey",appKey);
|
||||
params.put("timestamp", String.valueOf(timestamp));
|
||||
|
||||
String serverSign = OpenSignatureUtil.generateSign(params, coolAppSecret);
|
||||
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
package com.cool.store.controller.webb;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cool.store.dto.AskBotTokenDTO;
|
||||
import com.cool.store.dto.GetAccessTokenDTO;
|
||||
import com.cool.store.dto.StatusRefreshDTO;
|
||||
import com.cool.store.response.ResponseResult;
|
||||
import com.cool.store.response.bigdata.ApiResponse;
|
||||
import com.cool.store.service.OpenApiService;
|
||||
import com.cool.store.service.PushService;
|
||||
import com.cool.store.service.ShopAccountService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -23,6 +30,10 @@ public class OpenApiController {
|
||||
|
||||
@Resource
|
||||
OpenApiService openApiService;
|
||||
@Resource
|
||||
PushService pushService;
|
||||
@Resource
|
||||
ShopAccountService shopAccountService;
|
||||
|
||||
@PostMapping("/statusRefresh")
|
||||
public ApiResponse<Boolean> statusRefresh(@RequestBody StatusRefreshDTO statusRefreshDTO){
|
||||
@@ -30,4 +41,12 @@ public class OpenApiController {
|
||||
return ApiResponse.success(openApiService.statusRefresh(statusRefreshDTO));
|
||||
}
|
||||
|
||||
@ApiOperation("获取云流水免登token")
|
||||
@PostMapping("/getYlsToken")
|
||||
public ApiResponse<String> getYlsToken(@RequestBody @Validated AskBotTokenDTO dto) {
|
||||
String ylsCode = shopAccountService.shopCodeToYlsCode(dto.getShopCode());
|
||||
return ApiResponse.success(pushService.getYlsToken(new GetAccessTokenDTO(ylsCode,ylsCode)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class MiniShopAccountController {
|
||||
@ApiOperation("门店编码换云流水编码")
|
||||
@GetMapping("/shopCodeToYlsCode")
|
||||
public ResponseResult<String> shopCodeToYlsCode(@RequestParam(value = "shopId",required = true) Long shopId) {
|
||||
return ResponseResult.success(accountService.shopCodeToYlsCode(shopId));
|
||||
return ResponseResult.success(accountService.shopIdToYlsCode(shopId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,15 +95,35 @@ xgj.open.organization.X-Secret = 3fe724f9607448728ee3393eff75718a
|
||||
xgj.open.organization.url = https://masterdata.zhengxinfood.com/dmp/one-id
|
||||
|
||||
|
||||
|
||||
#huoma pos
|
||||
api.auth.url=https://api.zhengxindzg.cn
|
||||
api.auth.username=GkqgAhUJ7p9swJo
|
||||
api.auth.secret=NzVrnS3OWiupdDY
|
||||
|
||||
#xingguanjia
|
||||
xgj.api.auth.url=https://masterdata.zhengxinfood.com/dmp/one-id
|
||||
xgj.api.auth.username=6446346061e043e392dd53c9c8d1af0b
|
||||
xgj.api.auth.secret=3ba6e4c5632547b8b2b3acefe08667bb
|
||||
|
||||
#yunliushui
|
||||
yls.api.auth.url=http://yuanguiwuliu.com
|
||||
yls.api.auth.username=096d4009072c927c
|
||||
yls.api.auth.secret=3b56198f096d4009072c927c96fbc8b6
|
||||
|
||||
|
||||
#机会点地址 已确定
|
||||
third.party.appKey=IGSAEQoakR2HEaYx
|
||||
third.party.appSecret=aPsA99K1obFeFm3m
|
||||
zx.opportunity.url=https://snp.wenmatech.com/
|
||||
|
||||
#大数据地址 已确定
|
||||
zx.big.data.url=https://ds.zhengxinfood.com/
|
||||
zx.big.data.appKey=ff203b5567744feaaae49fb86f58c5bf
|
||||
zx.big.data.appSecret=35b8b9a400b4430fa022190be0913cd6
|
||||
|
||||
#新掌柜账号
|
||||
xzg.api.auth.url=http://webapi.zhengxinfood.com
|
||||
|
||||
|
||||
cool.api.appKey=k8J7fG2qR5tY9vX3
|
||||
cool.api.secret=wP4sN6dL8zK2xM9c
|
||||
@@ -116,8 +116,6 @@ yls.api.auth.secret=3b56198f096d4009072c927c96fbc8b6
|
||||
|
||||
#新掌柜账号
|
||||
xzg.api.auth.url=http://webapi.zhengxinfood.com
|
||||
xzg.api.auth.username=****
|
||||
xzg.api.auth.secret=****
|
||||
|
||||
cool.api.appKey=k8J7fG2qR5tY9vX3
|
||||
cool.api.secret=wP4sN6dL8zK2xM9c
|
||||
|
||||
Reference in New Issue
Block a user