feat:门店最近订货时间定时任务
This commit is contained in:
@@ -230,4 +230,6 @@ public class CommonConstants {
|
|||||||
* refreshToken有效期,单位秒
|
* refreshToken有效期,单位秒
|
||||||
*/
|
*/
|
||||||
public static final int REFRESH_TOKEN_EXPIRE = 30 * 24 * 60 * 60;
|
public static final int REFRESH_TOKEN_EXPIRE = 30 * 24 * 60 * 60;
|
||||||
|
|
||||||
|
public static final int BATCH_SIZE = 200;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.cool.store.dao;
|
package com.cool.store.dao;
|
||||||
|
|
||||||
|
import com.cool.store.dto.store.StoreOrderTimeDTO;
|
||||||
import com.cool.store.entity.StoreDO;
|
import com.cool.store.entity.StoreDO;
|
||||||
import com.cool.store.mapper.StoreMapper;
|
import com.cool.store.mapper.StoreMapper;
|
||||||
import com.cool.store.response.MiniShopsResponse;
|
import com.cool.store.response.MiniShopsResponse;
|
||||||
@@ -83,4 +84,22 @@ public class StoreDao {
|
|||||||
return storeMapper.getStoreNumByStoreCodes(storeCodeIds);
|
return storeMapper.getStoreNumByStoreCodes(storeCodeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或编辑最新订货时间
|
||||||
|
* @param dtoList 门店最新订货时间DTO列表
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public void batchInsertOrUpdateOrderTime(List<StoreOrderTimeDTO> dtoList) {
|
||||||
|
if (CollectionUtils.isEmpty(dtoList)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
storeMapper.batchInsertOrUpdateOrderTime(dtoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有门店id和门店编码
|
||||||
|
*/
|
||||||
|
public List<StoreDO> getAllStoreIdAndNum() {
|
||||||
|
return storeMapper.getAllStoreIdAndNum();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.cool.store.mapper;
|
package com.cool.store.mapper;
|
||||||
|
|
||||||
import com.cool.store.dto.store.StoreAreaDTO;
|
import com.cool.store.dto.store.StoreAreaDTO;
|
||||||
|
import com.cool.store.dto.store.StoreOrderTimeDTO;
|
||||||
import com.cool.store.entity.StoreDO;
|
import com.cool.store.entity.StoreDO;
|
||||||
import com.cool.store.response.MiniShopsResponse;
|
import com.cool.store.response.MiniShopsResponse;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
@@ -47,4 +48,15 @@ public interface StoreMapper {
|
|||||||
|
|
||||||
List<StoreAreaDTO> listStoreByRegionPathList(@Param("regionPathList") List<String> regionPathList);
|
List<StoreAreaDTO> listStoreByRegionPathList(@Param("regionPathList") List<String> regionPathList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增或编辑最新订货时间
|
||||||
|
* @param dtoList 门店最新订货时间DTO列表
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int batchInsertOrUpdateOrderTime(@Param("dtoList") List<StoreOrderTimeDTO> dtoList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有门店id和门店编码
|
||||||
|
*/
|
||||||
|
List<StoreDO> getAllStoreIdAndNum();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,4 +222,31 @@
|
|||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<insert id="batchInsertOrUpdateOrderTime">
|
||||||
|
INSERT INTO store_extend_info_${enterpriseId}
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
store_id,
|
||||||
|
latest_order_time
|
||||||
|
</trim>
|
||||||
|
VALUES
|
||||||
|
<foreach collection="dtoList" item="dto" separator=",">
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
#{dto.storeId},
|
||||||
|
#{dto.latestOrderTime}
|
||||||
|
</trim>
|
||||||
|
</foreach>
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
<trim suffixOverrides=",">
|
||||||
|
store_id = VALUES(store_id),
|
||||||
|
latest_order_time = VALUES(latest_order_time),
|
||||||
|
update_time = now(),
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<select id="getAllStoreIdAndNum" resultType="com.cool.store.entity.StoreDO">
|
||||||
|
SELECT store_id, store_num
|
||||||
|
FROM store_${enterpriseId}
|
||||||
|
WHERE is_delete = 'effective'
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.cool.store.dto.store;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 门店最新订货时间DTO
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author wangff
|
||||||
|
* @since 2025/10/23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class StoreOrderTimeDTO {
|
||||||
|
@ApiModelProperty("门店id")
|
||||||
|
private String storeId;
|
||||||
|
|
||||||
|
@ApiModelProperty("最新订货时间")
|
||||||
|
private Date latestOrderTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.cool.store.request.bigdata;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 最新订货日期Request
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author wangff
|
||||||
|
* @since 2025/10/23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class LatestOrderDateRequest {
|
||||||
|
/**
|
||||||
|
* 页码
|
||||||
|
*/
|
||||||
|
private Integer pageNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页数量
|
||||||
|
*/
|
||||||
|
private Integer pageSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 门店编码列表
|
||||||
|
*/
|
||||||
|
private String store_code;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.cool.store.response.bigdata;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 分页对象
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author wangff
|
||||||
|
* @since 2025/10/27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiPageResponse<T> {
|
||||||
|
private Integer total;
|
||||||
|
private List<T> list;
|
||||||
|
private Integer pageNum;
|
||||||
|
private Integer pageSize;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.cool.store.response.bigdata;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 最新订货日期Response
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author wangff
|
||||||
|
* @since 2025/10/23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LatestOrderDateResponse {
|
||||||
|
/**
|
||||||
|
* 门店编码
|
||||||
|
*/
|
||||||
|
private String store_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最新订货日期,yyyy-MM-dd
|
||||||
|
*/
|
||||||
|
private String latest_buy_date;
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.cool.store.service;
|
package com.cool.store.service;
|
||||||
|
|
||||||
|
import com.cool.store.request.bigdata.LatestOrderDateRequest;
|
||||||
import com.cool.store.request.bigdata.ProfitDataRequest;
|
import com.cool.store.request.bigdata.ProfitDataRequest;
|
||||||
import com.cool.store.request.oppty.CityRequest;
|
import com.cool.store.request.oppty.CityRequest;
|
||||||
import com.cool.store.response.bigdata.ActDataResponse;
|
import com.cool.store.response.bigdata.ActDataResponse;
|
||||||
|
import com.cool.store.response.bigdata.LatestOrderDateResponse;
|
||||||
import com.cool.store.response.bigdata.ProfitDataResponse;
|
import com.cool.store.response.bigdata.ProfitDataResponse;
|
||||||
import com.cool.store.response.bigdata.ProfitRateResponse;
|
import com.cool.store.response.bigdata.ProfitRateResponse;
|
||||||
import com.cool.store.response.oppty.CityResponse;
|
import com.cool.store.response.oppty.CityResponse;
|
||||||
@@ -53,5 +55,11 @@ public interface ThirdBigDataService {
|
|||||||
*/
|
*/
|
||||||
ActDataResponse getActData(ProfitDataRequest requestBody);
|
ActDataResponse getActData(ProfitDataRequest requestBody);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取门店最新订货日期
|
||||||
|
* @param requestBody 最新订货日期Request
|
||||||
|
* @return 最新订货日期Response列表
|
||||||
|
*/
|
||||||
|
List<LatestOrderDateResponse> getLatestOrderDate(LatestOrderDateRequest requestBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package com.cool.store.service.impl;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.cool.store.enums.ErrorCodeEnum;
|
import com.cool.store.enums.ErrorCodeEnum;
|
||||||
import com.cool.store.exception.ServiceException;
|
import com.cool.store.exception.ServiceException;
|
||||||
|
import com.cool.store.request.bigdata.LatestOrderDateRequest;
|
||||||
import com.cool.store.request.bigdata.ProfitDataRequest;
|
import com.cool.store.request.bigdata.ProfitDataRequest;
|
||||||
import com.cool.store.request.oppty.CityRequest;
|
import com.cool.store.request.oppty.CityRequest;
|
||||||
import com.cool.store.response.bigdata.ActDataResponse;
|
import com.cool.store.response.bigdata.*;
|
||||||
import com.cool.store.response.bigdata.ApiResponse;
|
|
||||||
import com.cool.store.response.bigdata.ProfitDataResponse;
|
|
||||||
import com.cool.store.response.bigdata.ProfitRateResponse;
|
|
||||||
import com.cool.store.response.oppty.CityResponse;
|
import com.cool.store.response.oppty.CityResponse;
|
||||||
import com.cool.store.response.oppty.OpportunityApiResponse;
|
import com.cool.store.response.oppty.OpportunityApiResponse;
|
||||||
import com.cool.store.response.oppty.OpportunityDetailResponse;
|
import com.cool.store.response.oppty.OpportunityDetailResponse;
|
||||||
@@ -96,6 +94,15 @@ public class ThirdBigDataServiceImpl implements ThirdBigDataService {
|
|||||||
return executeApiCall(url, requestBody, ActDataResponse.class);
|
return executeApiCall(url, requestBody, ActDataResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<LatestOrderDateResponse> getLatestOrderDate(LatestOrderDateRequest requestBody) {
|
||||||
|
String url = apiUrl + "api/web/v1/buy/latest_buy_date";
|
||||||
|
JavaType javaType = objectMapper.getTypeFactory()
|
||||||
|
.constructParametricType(ApiPageResponse.class, LatestOrderDateResponse.class);
|
||||||
|
ApiPageResponse<LatestOrderDateResponse> response = executeApiCallWithGenericType(url, requestBody, javaType);
|
||||||
|
return response.getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) {
|
private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) {
|
||||||
// 1. 打印请求前日志
|
// 1. 打印请求前日志
|
||||||
@@ -136,6 +143,44 @@ public class ThirdBigDataServiceImpl implements ThirdBigDataService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> T executeApiCallWithGenericType(String url, Object requestBody, JavaType 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() != 0) {
|
||||||
|
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) {
|
private Request buildRequest(Object requestBody, String url) {
|
||||||
Map<String, Object> params = JsonUtils.parseJsonToMap(JSONObject.toJSONString(requestBody));
|
Map<String, Object> params = JsonUtils.parseJsonToMap(JSONObject.toJSONString(requestBody));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.cool.store.job;
|
package com.cool.store.job;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollStreamUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.cool.store.constants.CommonConstants;
|
import com.cool.store.constants.CommonConstants;
|
||||||
@@ -7,6 +8,7 @@ import com.cool.store.dao.*;
|
|||||||
import com.cool.store.dto.*;
|
import com.cool.store.dto.*;
|
||||||
import com.cool.store.dto.decoration.ConstructionScheduleDTO;
|
import com.cool.store.dto.decoration.ConstructionScheduleDTO;
|
||||||
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
|
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
|
||||||
|
import com.cool.store.dto.store.StoreOrderTimeDTO;
|
||||||
import com.cool.store.entity.*;
|
import com.cool.store.entity.*;
|
||||||
import com.cool.store.enums.*;
|
import com.cool.store.enums.*;
|
||||||
import com.cool.store.enums.point.ShopStatusEnum;
|
import com.cool.store.enums.point.ShopStatusEnum;
|
||||||
@@ -19,7 +21,9 @@ import com.cool.store.mapper.TrainingExperienceMapper;
|
|||||||
import com.cool.store.mq.producer.SimpleMessageService;
|
import com.cool.store.mq.producer.SimpleMessageService;
|
||||||
import com.cool.store.mq.util.HttpRestTemplateService;
|
import com.cool.store.mq.util.HttpRestTemplateService;
|
||||||
import com.cool.store.request.ZxjpApiRequest;
|
import com.cool.store.request.ZxjpApiRequest;
|
||||||
|
import com.cool.store.request.bigdata.LatestOrderDateRequest;
|
||||||
import com.cool.store.request.xfsgFirstOrderListRequest;
|
import com.cool.store.request.xfsgFirstOrderListRequest;
|
||||||
|
import com.cool.store.response.bigdata.LatestOrderDateResponse;
|
||||||
import com.cool.store.response.xfsgFirstOderListResponse;
|
import com.cool.store.response.xfsgFirstOderListResponse;
|
||||||
import com.cool.store.service.*;
|
import com.cool.store.service.*;
|
||||||
import com.cool.store.service.impl.CommonService;
|
import com.cool.store.service.impl.CommonService;
|
||||||
@@ -40,6 +44,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -111,6 +116,10 @@ public class XxlJobHandler {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
PushService pushService;
|
PushService pushService;
|
||||||
|
@Resource
|
||||||
|
StoreDao storeDao;
|
||||||
|
@Resource
|
||||||
|
ThirdBigDataService thirdBigDataService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -395,4 +404,50 @@ public class XxlJobHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@XxlJob("latestOrderDate")
|
||||||
|
public void latestOrderDate() {
|
||||||
|
log.info("------start latestOrderDate------");
|
||||||
|
boolean hasNext = true;
|
||||||
|
int pageNum = 1;
|
||||||
|
int pageSize = CommonConstants.BATCH_SIZE;
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
while (hasNext) {
|
||||||
|
PageHelper.startPage(pageNum, pageSize);
|
||||||
|
List<StoreDO> storeList = storeDao.getAllStoreIdAndNum();
|
||||||
|
if (CollectionUtils.isEmpty(storeList)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hasNext = storeList.size() >= pageSize;
|
||||||
|
List<String> storeNums = CollStreamUtil.toList(storeList, StoreDO::getStoreNum);
|
||||||
|
Map<String, String> storeIdMap = CollStreamUtil.toMap(storeList, StoreDO::getStoreNum, StoreDO::getStoreId);
|
||||||
|
LatestOrderDateRequest request = new LatestOrderDateRequest(1, pageSize, String.join(",", storeNums));
|
||||||
|
List<LatestOrderDateResponse> resList = thirdBigDataService.getLatestOrderDate(request);
|
||||||
|
log.info("接口请求门店数量:{},返回门店数:{}", storeList.size(), resList.size());
|
||||||
|
if (CollectionUtils.isNotEmpty(resList)) {
|
||||||
|
try {
|
||||||
|
List<StoreOrderTimeDTO> updateList = resList.stream()
|
||||||
|
.map(v -> {
|
||||||
|
Date date = parseDate(v, dateFormat);
|
||||||
|
return Objects.nonNull(date) ? new StoreOrderTimeDTO(storeIdMap.get(v.getStore_code()), date) : null;
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
storeDao.batchInsertOrUpdateOrderTime(updateList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取最新订货时间失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageNum++;
|
||||||
|
}
|
||||||
|
log.info("------end latestOrderDate------");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date parseDate(LatestOrderDateResponse v, DateFormat format) {
|
||||||
|
try {
|
||||||
|
return format.parse(v.getLatest_buy_date());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
log.error("日期转化失败,storeCode:{},latestBuyDate:{}", v.getStore_code(), v.getLatest_buy_date());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user