Commit cd858559 by Lizh

优化pageList查询接口

parent 315f36e6
...@@ -3,9 +3,7 @@ package com.jomalls.custom.app.dto; ...@@ -3,9 +3,7 @@ package com.jomalls.custom.app.dto;
import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.JsonSetter;
import com.jomalls.custom.page.PageRequest; import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
...@@ -140,6 +138,8 @@ public class CustomProductInfoSnakeDTO extends PageRequest { ...@@ -140,6 +138,8 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
* <p> * <p>
* 兼容前端发送 Boolean(true→1, false→0)和 Number(0/1/2)。 * 兼容前端发送 Boolean(true→1, false→0)和 Number(0/1/2)。
*/ */
@Min(value = 0, message = "processing 不能小于0")
@Max(value = 2, message = "processing 不能大于2")
@Schema(description = "是否九猫处理(0=否 1=是 2=未设置,也支持 true/false)") @Schema(description = "是否九猫处理(0=否 1=是 2=未设置,也支持 true/false)")
private Integer processing; private Integer processing;
......
package com.jomalls.custom.app.enums;
import lombok.Getter;
/**
* @Author: Lizh
* @Date: 2026/6/11 16:47
* @Description:
* @Version: 1.0
*/
@Getter
public enum ProcessingStatus {
/** 是否九猫处理(0=否 1=是 2=未设置,也支持 true/false) */
NO(0),
YES(1),
NOT_SET(2); // 2表示IS NULL
private final int code;
ProcessingStatus(int code) {
this.code = code;
}
}
...@@ -103,8 +103,6 @@ public interface CustomProductInfoService { ...@@ -103,8 +103,6 @@ public interface CustomProductInfoService {
*/ */
List<CraftCenterVO> getCraftById(Integer id); List<CraftCenterVO> getCraftById(Integer id);
// ==================== ERP 专用接口(对齐 TS) ====================
/** /**
* ERP 分页查询(对齐 TS erpPage) * ERP 分页查询(对齐 TS erpPage)
* <p> * <p>
......
package com.jomalls.custom.app.service.impl; package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jomalls.custom.app.vo.LogCustomProductSnakeVO; import com.jomalls.custom.app.vo.LogCustomProductSnakeVO;
import com.jomalls.custom.app.service.LogCustomProductService; import com.jomalls.custom.app.service.LogCustomProductService;
import com.jomalls.custom.app.utils.BeanMapper; import com.jomalls.custom.app.utils.BeanMapper;
...@@ -32,11 +32,12 @@ public class LogCustomProductServiceImpl implements LogCustomProductService { ...@@ -32,11 +32,12 @@ public class LogCustomProductServiceImpl implements LogCustomProductService {
@Override @Override
public List<LogCustomProductSnakeVO> getListByProductId(Integer productId) { public List<LogCustomProductSnakeVO> getListByProductId(Integer productId) {
CustomAsserts.nonNull(productId, "商品 ID 不能为空"); CustomAsserts.nonNull(productId, "商品 ID 不能为空");
// 按 product_id 查询所有日志,按 id 降序排列 // 按 product_id 查询日志,按 id 降序,限制 100 条防止数据膨胀
List<LogCustomProductEntity> logs = logCustomProductDomainService.list( List<LogCustomProductEntity> logs = logCustomProductDomainService.list(
new QueryWrapper<LogCustomProductEntity>() new LambdaQueryWrapper<LogCustomProductEntity>()
.eq("product_id", productId) .eq(LogCustomProductEntity::getProductId, productId)
.orderByDesc("id")); .orderByDesc(LogCustomProductEntity::getId)
.last("LIMIT 100"));
return logs.stream() return logs.stream()
.map(e -> BeanMapper.snakeCase().convert(e, LogCustomProductSnakeVO.class)) .map(e -> BeanMapper.snakeCase().convert(e, LogCustomProductSnakeVO.class))
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -19,6 +19,7 @@ import java.util.Collections; ...@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* 商品分类服务 * 商品分类服务
...@@ -43,8 +44,14 @@ public class SaasAdminService { ...@@ -43,8 +44,14 @@ public class SaasAdminService {
private static final int DEFAULT_MAP_SIZE = 2; private static final int DEFAULT_MAP_SIZE = 2;
/** 分类列表缓存 TTL(毫秒):5 分钟 */
private static final long CACHE_TTL_MS = 5 * 60 * 1000;
private final RemoteApiClient remoteApiClient; private final RemoteApiClient remoteApiClient;
/** 分类列表本地缓存 */
private final AtomicReference<CacheEntry<List<CategoryInfoModel>>> categoryCache = new AtomicReference<>();
@Value("${server.admin.base-url:https://admin.jomalls.com}") @Value("${server.admin.base-url:https://admin.jomalls.com}")
private String adminBaseUrl; private String adminBaseUrl;
...@@ -178,26 +185,54 @@ public class SaasAdminService { ...@@ -178,26 +185,54 @@ public class SaasAdminService {
} }
/** /**
* 查询所有分类 * 查询所有分类(带本地缓存,TTL 5 分钟)
* <p> * <p>
* 对齐 TS {@code allList()} * 对齐 TS {@code allList()}。分类数据不频繁变动,
* 使用本地缓存避免每次分页查询都发起远程 HTTP 调用。
*/ */
public List<CategoryInfoModel> getAllList() { public List<CategoryInfoModel> getAllList() {
// 命中缓存且未过期 → 直接返回
CacheEntry<List<CategoryInfoModel>> entry = categoryCache.get();
if (entry != null && !entry.isExpired()) {
return entry.data;
}
// 未命中或已过期 → 远程调用刷新
try { try {
ResponseEntity<SaasAdminApiResponseModel<List<CategoryInfoModel>>> response = remoteApiClient.get( ResponseEntity<SaasAdminApiResponseModel<List<CategoryInfoModel>>> response = remoteApiClient.get(
adminBaseUrl + GET_ALL_LIST_URL, adminBaseUrl + GET_ALL_LIST_URL,
new ParameterizedTypeReference<>() {}, new ParameterizedTypeReference<>() {},
getHeader()); getHeader());
if (response != null && response.getBody() != null) { if (response != null && response.getBody() != null) {
log.debug("[ SaasAdminService ] getAllList 成功, 返回: {}", response.toString());
SaasAdminApiResponseModel<List<CategoryInfoModel>> responseBody = response.getBody(); SaasAdminApiResponseModel<List<CategoryInfoModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) { if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData(); List<CategoryInfoModel> data = responseBody.getData();
categoryCache.set(new CacheEntry<>(data));
return data;
} }
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ SaasAdminService ] getAllList 调用失败", e); log.error("[ SaasAdminService ] getAllList 调用失败", e);
} }
// 远程调用失败但有旧缓存 → 降级返回旧缓存
if (entry != null) {
log.warn("[ SaasAdminService ] getAllList 远程失败,降级使用过期缓存");
return entry.data;
}
return Collections.emptyList(); return Collections.emptyList();
} }
/** 简单 TTL 缓存条目 */
private static class CacheEntry<T> {
final T data;
final long expireAt;
CacheEntry(T data) {
this.data = data;
this.expireAt = System.currentTimeMillis() + CACHE_TTL_MS;
}
boolean isExpired() {
return System.currentTimeMillis() > expireAt;
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment