Merge branch 'cc_2250513_api' into 'master'
Cc 2250513 api See merge request hangzhou/java/custom_zxjp!89
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user