feat:平台账号

This commit is contained in:
苏竹红
2025-04-10 20:29:57 +08:00
parent f9219e028e
commit 080019ac0d
19 changed files with 111 additions and 41 deletions

View File

@@ -50,6 +50,7 @@ public class OpenSignatureUtil {
return hmacSha256(sb.toString(), appSecret);
}
private static String hmacSha256(String data, String key) {
try {
Mac sha256_HMAC = Mac.getInstance(HMAC_SHA256);

View File

@@ -20,7 +20,7 @@ public class PasswordUtil {
public static byte[] generateSalt() {
SecureRandom secureRandom = new SecureRandom();
// 16 字节的盐值
byte[] salt = new byte[16];
byte[] salt = new byte[3];
secureRandom.nextBytes(salt);
return salt;
}
@@ -50,12 +50,13 @@ public class PasswordUtil {
* @param salt 盐值
* @return 加密后的密码(十六进制字符串)
*/
public static String encryptPassword(String plainPassword, byte[] salt) {
public static String encryptPassword(String plainPassword, String salt) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
// 将盐值和明文密码拼接后进行哈希计算
messageDigest.update(salt);
byte[] hashedBytes = messageDigest.digest(plainPassword.getBytes());
String combined = plainPassword + salt;
byte[] hashedBytes = messageDigest.digest(combined.getBytes());
// 将字节数组转换为十六进制字符串
return bytesToHex(hashedBytes);

View File

@@ -40,6 +40,7 @@ public class ShopAccountDAO {
if (ShopAccountEnum.getSpecialEnumList().contains(shopAccountEnum)){
shopAccountDO.setPasswordSalt(partnerUserInfoDO.getDownstreamSystemSalting());
shopAccountDO.setPassword(partnerUserInfoDO.getDownstreamSystemPassword());
shopAccountDO.setSecondaryPassword(partnerUserInfoDO.getDownstreamSystemSecondaryPassword());
}
shopAccountDO.setStatus(shopAccountEnum.getInitStatus().getCode());
if (ShopAccountEnum.HUOMA.equals(shopAccountEnum)){
@@ -71,7 +72,7 @@ public class ShopAccountDAO {
/**
* 根据shopId与system_name修改status
* @param shopId 店铺ID
* @param systemName 系统名称
* @param systemNameList 系统名称
* @param status 状态
* @return 影响的行数
*/
@@ -112,9 +113,9 @@ public class ShopAccountDAO {
* @param lastSyncTime
* @return
*/
public int batchUpdatePasswordByShopIds( List<Long> shopIds, String password, String passwordSalt, Date lastSyncTime){
public int batchUpdatePasswordByShopIds( List<Long> shopIds, String password,String secondaryPassword, String passwordSalt, Date lastSyncTime){
return shopAccountMapper.batchUpdatePasswordByShopIds(
shopIds, password, passwordSalt, lastSyncTime
shopIds, password, secondaryPassword, passwordSalt, lastSyncTime
);
}

View File

@@ -253,4 +253,11 @@ public class ShopInfoDAO {
}
return shopInfoMapper.getShopCodeList(lineId);
}
public List<Long> getShopIdList(Long lineId){
if (lineId == null){
return new ArrayList<>();
}
return shopInfoMapper.getShopIdList(lineId);
}
}

View File

@@ -64,6 +64,7 @@ public interface ShopAccountMapper extends Mapper<ShopAccountDO> {
int batchUpdatePasswordByShopIds(
@Param("shopIds") List<Long> shopIds,
@Param("password") String password,
@Param("secondaryPassword") String secondaryPassword,
@Param("passwordSalt") String passwordSalt,
@Param("lastSyncTime") Date lastSyncTime
);

View File

@@ -132,4 +132,6 @@ public interface ShopInfoMapper extends Mapper<ShopInfoDO> {
Integer updateShopCode(@Param("shopCode") String shopCode,@Param("shopId") Long shopId);
List<String> getShopCodeList(@Param("lineId") Long lineId);
List<Long> getShopIdList(@Param("lineId") Long lineId);
}

View File

@@ -117,6 +117,7 @@
xfsg_shop_account
SET
password = #{password},
secondary_password = #{secondaryPassword},
password_salt = #{passwordSalt},
last_sync_time = #{lastSyncTime,jdbcType=TIMESTAMP}
WHERE

View File

@@ -439,6 +439,12 @@
where deleted = 0 and line_id = #{lineId} and shop_code is not null
</select>
<select id="getShopIdList" resultType="java.lang.String">
select id
from xfsg_shop_info
where deleted = 0 and line_id = #{lineId} and shop_code is not null
</select>
<update id="batchUpdate" parameterType="list">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
UPDATE xfsg_shop_info

View File

@@ -13,10 +13,14 @@ import java.util.List;
@Data
public class ModifyPasswordDTO {
@ApiModelProperty(value = "手机号",hidden = true)
private String mobile;
@ApiModelProperty(value = "盐值",required = true)
String passwordSalt;
@ApiModelProperty(value = "密码",required = true)
String password;
@ApiModelProperty(value = "第二密码",required = true)
String passwordSecondary;
@ApiModelProperty(value = "门店ID",required = true)
Long shopId;
@ApiModelProperty(value = "门店ID",hidden = true)

View File

@@ -57,4 +57,8 @@ public class HyPartnerUserInfoDO implements Serializable {
@ApiModelProperty("下游系统密码")
@Column(name = "downstream_system_password")
private String downstreamSystemPassword;
@ApiModelProperty("下游系统第二密码")
@Column(name = "downstream_system_Secondary_password")
private String downstreamSystemSecondaryPassword;
}

View File

@@ -49,6 +49,11 @@ public class ShopAccountDO {
*/
private String password;
/**
* 第二密码
*/
private String secondaryPassword;
/**
* 状态1-开通资料收集中, 2-资料审核中, 3-资料审核失败, 4-开通中, 5-开通成功, 6-开通失败
*/

View File

@@ -126,7 +126,7 @@ public class JoinIntentionServiceImpl extends LineFlowService implements JoinInt
//生成密码和盐值
byte[] saltBytes = PasswordUtil.generateSalt();
String salt = PasswordUtil.bytesToHex(saltBytes);
String password = PasswordUtil.encryptPassword(substring, saltBytes);
String password = PasswordUtil.encryptPassword(substring, salt);
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(lineInfo.getPartnerId());
hyPartnerUserInfoDO.setDownstreamSystemPassword(password);
hyPartnerUserInfoDO.setDownstreamSystemSalting(salt);
@@ -169,4 +169,5 @@ public class JoinIntentionServiceImpl extends LineFlowService implements JoinInt
response.setBigRegionId(byLineId.getBigRegionId());
return response;
}
}

View File

@@ -83,7 +83,7 @@ public class PushServiceImpl implements PushService {
@Override
public Boolean pushDataToPOS(ZxjpApiRequest zxjpApiRequest) {
String apiUrl = url + "XXX";
String apiUrl = url + "/dzgV1/zxcrm/shop/upsert";
return executeApiCall(apiUrl,zxjpApiRequest, Boolean.class,username,secret);
}
@@ -93,7 +93,7 @@ public class PushServiceImpl implements PushService {
}
private Boolean modifyPosPassword(ModifyPasswordDTO dto) {
String apiUrl = url + "XXX";
String apiUrl = url + "/dzgV1/zxcrm/business_user/modifyPassword";
return executeApiCall(apiUrl,dto, Boolean.class,username,secret);
}
@@ -102,7 +102,7 @@ public class PushServiceImpl implements PushService {
public Boolean modifyDownstreamSystem(ModifyPasswordDTO modifyPasswordDTO) {
try {
this.modifyPosPassword(modifyPasswordDTO);
this.modifyXGJPassword(modifyPasswordDTO);
//this.modifyXGJPassword(modifyPasswordDTO);
} catch (Exception e) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR);
}
@@ -123,7 +123,7 @@ public class PushServiceImpl implements PushService {
@Override
public String getPosToken(GetAccessTokenDTO dto) {
String apiUrl = url + "XXX";
String apiUrl = url + "/dzgV1/zxcrm/business_user/generateToken";
return executeApiCall(apiUrl,dto, String.class,username,secret);
}

View File

@@ -94,20 +94,20 @@ public class ShopAccountServiceImpl implements ShopAccountService {
}
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(shopInfo.getPartnerId());
hyPartnerUserInfoDO.setDownstreamSystemPassword(modifyPasswordDTO.getPassword());
hyPartnerUserInfoDO.setDownstreamSystemSecondaryPassword(modifyPasswordDTO.getPasswordSecondary());
hyPartnerUserInfoDO.setDownstreamSystemSalting(modifyPasswordDTO.getPasswordSalt());
hyPartnerUserInfoDO.setUpdateTime(new Date());
hyPartnerUserInfoDAO.updatePasswordByPartnerId(hyPartnerUserInfoDO);
List<MiniShopsResponse> shopListSuccessOpen = shopService.getShopListSuccessOpen(shopInfo.getLineId());
//修改数据
List<Long> shopIdList = shopListSuccessOpen.stream().map(MiniShopsResponse::getShopId).collect(Collectors.toList());
List<Long> shopIdList = shopInfoDAO.getShopIdList(shopInfo.getLineId());
//批量修改密码 密码盐
shopAccountDAO.batchUpdatePasswordByShopIds(shopIdList,modifyPasswordDTO.getPassword(),modifyPasswordDTO.getPasswordSalt(),new Date());
shopAccountDAO.batchUpdatePasswordByShopIds(shopIdList,modifyPasswordDTO.getPassword(),modifyPasswordDTO.getPasswordSecondary(),modifyPasswordDTO.getPasswordSalt(),new Date());
//当前加盟商所有开店成功的CODE
List<String> shopCodeList = shopListSuccessOpen.stream().map(MiniShopsResponse::getShopCode).collect(Collectors.toList());
List<String> shopCodeList = shopInfoDAO.getShopCodeList(shopInfo.getLineId());
modifyPasswordDTO.setShopCode(shopCodeList);
modifyPasswordDTO.setMobile(hyPartnerUserInfoDO.getMobile());
//推送下游系统
pushService.modifyDownstreamSystem(modifyPasswordDTO);
@@ -202,7 +202,9 @@ public class ShopAccountServiceImpl implements ShopAccountService {
// TODO: 2025/4/8 suzhuhong_
try {
if (DownSystemTypeEnum.POS.equals(downSystemTypeEnum)){
pushService.pushDataToPOS(data);
Boolean successFlag = pushService.pushDataToPOS(data);
OpenStatusEnum openStatusEnum = successFlag ? OpenStatusEnum.OPENSTATUSENUM_5 : OpenStatusEnum.OPENSTATUSENUM_6;
shopAccountDAO.updateEntryStatusByShopIdAndSystemName(accountAuditDTO.getShopId(),Arrays.asList(ShopAccountEnum.HUOMA.getSystemName()),openStatusEnum.getCode());
}else {
pushService.pushDataToXGJ(data);
}

View File

@@ -4,6 +4,8 @@ import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.utils.OpenSignatureUtil;
import com.cool.store.utils.UUIDUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
@@ -12,8 +14,11 @@ import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
@@ -50,7 +55,7 @@ public class OpenApiValidateFilter implements Filter {
// 1. 验证时间戳
try {
String timestampStr = request.getParameter("timestamp");
String timestampStr = request.getHeader("timestamp");
if (timestampStr == null) {
log.info("timestampStr is null {}","缺少timestamp参数");
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
@@ -71,22 +76,33 @@ public class OpenApiValidateFilter implements Filter {
}
// 2. 验证签名
String appKey = request.getParameter("appKey");
String appKey = request.getHeader("appkey");
if (appKey == null || !coolAppKey.equals(appKey)) {
log.info("OpenApiValidateFilter==>{}","无效的appKey");
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
}
String clientSign = request.getParameter("sign");
String clientSign = request.getHeader("sign");
if (clientSign == null) {
throw new ServiceException(ErrorCodeEnum.SIGN_FAIL);
}
// 1. 读取请求体
StringBuilder requestBody = new StringBuilder();
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
requestBody.append(line);
}
}
// 获取所有请求参数
Map<String, String> params = request.getParameterMap().entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> String.join(",", e.getValue())));
String jsonBody = requestBody.toString();
// 2. 使用 Jackson 解析 JSON 并转为 TreeMap自动按键排序
ObjectMapper objectMapper = new ObjectMapper();
SortedMap<String, String> params = objectMapper.readValue(
jsonBody,
new TypeReference<TreeMap<String, String>>() {}
);
String serverSign = OpenSignatureUtil.generateSign(params, coolAppSecret);

View File

@@ -4,9 +4,7 @@ import com.cool.store.dto.StatusRefreshDTO;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.OpenApiService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -23,9 +21,10 @@ public class OpenApiController {
@Resource
OpenApiService openApiService;
@GetMapping("/statusRefresh")
public ApiResponse<Boolean> statusRefresh(StatusRefreshDTO statusRefreshDTO){
return ApiResponse.success(openApiService.statusRefresh(statusRefreshDTO));
@PostMapping("/statusRefresh")
public ApiResponse<Boolean> statusRefresh(@RequestBody StatusRefreshDTO statusRefreshDTO){
//openApiService.statusRefresh(statusRefreshDTO)
return ApiResponse.success(Boolean.TRUE);
}
}

View File

@@ -3,6 +3,7 @@ package com.cool.store.controller.webb;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.*;
import com.cool.store.dto.ModifyPasswordDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.DownSystemTypeEnum;
import com.cool.store.enums.MessageEnum;
@@ -258,4 +259,12 @@ public class PCTestController {
}
@Resource
ShopAccountService accountService;
@ApiOperation("修改密码")
@GetMapping("/modifyPassword")
public ResponseResult<Boolean> modifyPassword(@RequestBody ModifyPasswordDTO request) {
return ResponseResult.success(accountService.modifyPassword(request));
}
}

View File

@@ -80,3 +80,13 @@ mybatis.configuration.variables.enterpriseId=214ac5a3a517472a87268e02a2e6410a
enterprise.dingCorpId=wpayJeDAAAklx_q1jGhyGUd4yEh8vV_g
qywx.task.notice.url2=https://store-h5.coolstore.cn/?corpId=%s&appType=%s#/notice?target=%s&noticeType=zx&corpId=%s&appType=%s&eid=%s
api.auth.url=https://api.zhengxindzg.cn
api.auth.username=GkqgAhUJ7p9swJo
api.auth.secret=NzVrnS3OWiupdDY
xgj.api.auth.url=https://masterdata.zhengxinfood.com/dmp/one-id/
xgj.api.auth.username=2677a58dd9e24fc6b20e835ef5f19e63
xgj.api.auth.secret=3fe724f9607448728ee3393eff75718a

View File

@@ -94,14 +94,14 @@ zx.big.data.appKey=ff203b5567744feaaae49fb86f58c5bf
zx.big.data.appSecret=35b8b9a400b4430fa022190be0913cd6
#火吗POS
api.auth.url=https://api.zhengxindzg.cn
api.auth.username=GkqgAhUJ7p9swJo
api.auth.secret=NzVrnS3OWiupdDY
api.auth.url=https://api.hmdzg.top
api.auth.username=VA59C0ubfcpcVpl
api.auth.secret=H9YKHF6R7N16Fvy
#新管家账号
xgj.api.auth.url=****
xgj.api.auth.username=****
xgj.api.auth.secret=****
xgj.api.auth.url=http://117.139.13.24:11180/dmp/one-id/
xgj.api.auth.username=2677a58dd9e24fc6b20e835ef5f19e63
xgj.api.auth.secret=3fe724f9607448728ee3393eff75718a
#云流水账号
yls.api.auth.url=****
@@ -113,5 +113,5 @@ xzg.api.auth.url=****
xzg.api.auth.username=****
xzg.api.auth.secret=****
cool.api.appKey=123
cool.api.secret=123
cool.api.appKey=k8J7fG2qR5tY9vX3
cool.api.secret=wP4sN6dL8zK2xM9c