Merge branch 'cc_2250513_api' into 'master'

Cc 2250513 api

See merge request hangzhou/java/custom_zxjp!89
This commit is contained in:
苏竹红
2025-05-20 09:32:04 +00:00
18 changed files with 570 additions and 13 deletions

View File

@@ -0,0 +1,24 @@
package com.cool.store.service;
import com.cool.store.dto.StoreDTO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* @Author suzhuhong
* @Date 2025/5/13 9:56
* @Version 1.0
*/
public interface StoreService {
/**
* 分页查询门店信息 包括扩展信息
* @param pageSize
* @param pageNum
* @return
*/
PageInfo<StoreDTO> getStoreExtendFieldInfo(Integer pageSize,Integer pageNum);
}

View File

@@ -0,0 +1,22 @@
package com.cool.store.service;
import com.cool.store.dto.FoodTokenDTO;
import com.cool.store.dto.GetAccessTokenDTO;
/**
* 正新菜品市场api对接-埃林哲-对接人徐哲
* @Author suzhuhong
* @Date 2025/5/13 15:20
* @Version 1.0
*/
public interface ThirdFoodService {
/**
* 获取正新菜品市场token
* @param dto
* @return
*/
String getFoodToken(FoodTokenDTO dto);
}

View File

@@ -0,0 +1,116 @@
package com.cool.store.service.impl;
import com.cool.store.dao.StoreDao;
import com.cool.store.dto.StoreDTO;
import com.cool.store.entity.StoreDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.ExtendFieldTypeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.StoreService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author suzhuhong
* @Date 2025/5/13 9:56
* @Version 1.0
*/
@Service
@Slf4j
public class StoreServiceImpl implements StoreService {
@Resource
StoreDao storeDao;
@Override
public PageInfo<StoreDTO> getStoreExtendFieldInfo(Integer pageSize, Integer pageNum) {
if (pageSize>200){
throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE,"单次最多获取200条门店数据");
}
PageHelper.startPage(pageNum,pageSize);
List<StoreDO> list = storeDao.list();
PageInfo info = new PageInfo<>(list);
if (CollectionUtils.isEmpty(list)){
return info;
}
List<StoreDTO> storeDTOS = processStores(list);
info.setList(storeDTOS);
return info;
}
public static List<StoreDTO> processStores(List<StoreDO> stores) {
ObjectMapper objectMapper = new ObjectMapper();
// 创建配置映射key -> 枚举项
Map<String, ExtendFieldTypeEnum> configMap = ExtendFieldTypeEnum.configMap();
// 处理每个门店
return stores.stream().map(store -> {
StoreDTO dto = new StoreDTO();
dto.setStoreName(store.getStoreName());
dto.setStoreCode(store.getStoreNum());
try {
// 解析门店的扩展字段
Map<String, String> extendFields = objectMapper.readValue(
store.getExtendField(),
new TypeReference<Map<String, String>>() {}
);
// 匹配并设置DTO字段
for (Map.Entry<String, String> entry : extendFields.entrySet()) {
ExtendFieldTypeEnum fieldEnum = configMap.get(entry.getKey());
if (fieldEnum != null) {
switch (fieldEnum) {
case TEST_STORE_MANAGER_MOBILE:
case ONLINE_STORE_MANAGER_MOBILE:
dto.setManagerPhone(entry.getValue());
break;
case TEST_SIGNATORY_NAME_1:
case ONLINE_SIGNATORY_NAME_1:
dto.setSigner1Name(entry.getValue());
break;
case TEST_SIGNATORY_MOBILE_1:
case ONLINE_SIGNATORY_MOBILE_1:
dto.setSigner1Phone(entry.getValue());
break;
case TEST_SIGNATORY_NAME_2:
case ONLINE_SIGNATORY_NAME_2:
dto.setSigner2Name(entry.getValue());
break;
case TEST_SIGNATORY_MOBILE_2:
case ONLINE_SIGNATORY_MOBILE_2:
dto.setSigner2Phone(entry.getValue());
break;
case TEST_ORDER_NAME:
case ONLINE_ORDER_NAME:
dto.setOrderMiniProgramName(entry.getValue());
break;
}
}
}
} catch (Exception e) {
// 处理JSON解析异常
log.error("解析门店扩展字段失败: {} " + store.getStoreNum());
e.printStackTrace();
}
return dto;
}).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,148 @@
package com.cool.store.service.impl;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.dto.FoodTokenDTO;
import com.cool.store.dto.GetAccessTokenDTO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.response.oppty.OpportunityApiResponse;
import com.cool.store.service.ThirdFoodService;
import com.cool.store.utils.SignatureUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.URI;
import java.util.Map;
/**
* @Author suzhuhong
* @Date 2025/5/13 15:21
* @Version 1.0
*/
@Service
@Slf4j
public class ThirdFoodServiceImpl implements ThirdFoodService {
@Value("${zx.food.url}")
private String apiUrl;
@Resource
OkHttpClient okHttpClient;
@Resource
ObjectMapper objectMapper;
@Override
public String getFoodToken(FoodTokenDTO dto) {
// 1. 发送POST请求
String url = apiUrl + "/interface/v1/user/getToken";
return executeApiCall(url, dto, String.class);
}
private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) {
// 1. 打印请求前日志
//logRequest(url, requestBody);
try {
Request request = buildRequest(requestBody, url);
try (Response response = okHttpClient.newCall(request).execute()) {
// 2. 获取原始响应内容
String 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(OpportunityApiResponse.class, responseType);
OpportunityApiResponse<T> apiResponse = objectMapper.readValue(responseBody, javaType);
if (apiResponse.getCode() != 200) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, apiResponse.getMsg());
}
return apiResponse.getData();
}
} 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 buildRequest(Object requestBody, String url) {
String timestamp = String.valueOf(System.currentTimeMillis());
String random = RandomUtil.randomString(20);
String signString = null;
try {
signString = SignatureUtils.sign("POST","/v1/user/getToken", objectMapper.writeValueAsString(requestBody),timestamp,random);
} catch (Exception e) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_SIGN_ERROR,"加密失败");
}
log.info("签名生成 - 签名结果: {}", signString);
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"),
JSONObject.toJSONString(requestBody)
);
return new Request.Builder()
.url(url)
.post(body)
.addHeader("X-ZhengXin-Sign", signString)
.addHeader("X-ZhengXin-SignTime", timestamp)
.addHeader("X-ZhengXin-SignRandom", random)
.addHeader("X-ZhengXin-appId", "CRM")
.build();
}
private void logResponse(String url, int statusCode, String responseBody) {
if (log.isInfoEnabled()) {
try {
// 尝试美化JSON输出
Object json = objectMapper.readValue(responseBody, Object.class);
String prettyResponse = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
log.info("\n======= 响应开始 =======\n" +
"API地址: {}\n" +
"HTTP状态码: {}\n" +
"响应内容: {}\n" +
"======= 响应结束 =======",
url,
statusCode,
prettyResponse);
} catch (Exception e) {
// 非JSON响应或解析失败时直接输出原始内容
log.info("\n======= 响应开始 =======\n" +
"API地址: {}\n" +
"HTTP状态码: {}\n" +
"原始响应: {}\n" +
"======= 响应结束 =======",
url,
statusCode,
responseBody);
}
}
}
}