Commit bdb8936e by Lizh

调整integrate目录结构,删除无用代码

parent 1c5f75aa
......@@ -12,6 +12,7 @@
/logs/
.trae/
.vscode/
.claude/
CLAUDE.md
docs
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductWarehouseRelPageVO;
import com.jomalls.custom.app.vo.CustomProductWarehouseRelVO;
import com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 接口
* @date 2026-05-29 10:43:29
*/
public interface CustomProductWarehouseRelService {
/**
* 列表查询接口
*
* @param customProductWarehouseRelVO 条件model
* @return list集合
*/
List<CustomProductWarehouseRelVO> list(CustomProductWarehouseRelVO customProductWarehouseRelVO);
/**
* 根据条件查询分页列表接口
*
* @param customProductWarehouseRelPageVO 分页入参model
* @return 分页对象
*/
IPage<CustomProductWarehouseRelVO> pageList(CustomProductWarehouseRelPageVO customProductWarehouseRelPageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
CustomProductWarehouseRelVO info(Integer id);
/**
* 保存对象
*
* @param customProductWarehouseRelVO 保存对象
*/
void save(CustomProductWarehouseRelVO customProductWarehouseRelVO);
/**
* 根据id修改对象
*
* @param customProductWarehouseRelVO 修改对象
*/
void updateById(CustomProductWarehouseRelVO customProductWarehouseRelVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(Integer id);
/**
* 根据仓库ID获取关联列表
*/
List<CustomProductWarehouseRelEntity> getListByWareHouseId(Long warehouseId);
/**
* 根据产品ID获取关联列表
*/
List<CustomProductWarehouseRelEntity> getListByProductId(Long productId);
/**
* 根据产品ID获取仓库ID列表
*/
List<Long> getWarehouseIdsByProductId(Long productId);
/**
* 批量保存产品与仓库的关联
* 逻辑:先删除该产品现有的所有关联,再批量插入新的
*/
void saveBatch(Integer productId, List<Long> warehouseIds);
/**
* 根据产品ID删除关联
* 注意:原 TS 代码支持手动传入 transaction,Java 中通常使用 @Transactional 注解管理事务
*/
void deleteByProductId(Integer productId);
}
......@@ -83,6 +83,12 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
/** 并行查询超时时间(秒) */
private static final long QUERY_TIMEOUT_SECONDS = 30;
/** 最小列表长度 */
private static final int MIN_LIST_SIZE = 1;
/** 负数 1 */
private static final int NEGATIVE_ONE = -1;
@Override
public IPage<CustomProductInfoPageSnakeVO> pageList(CustomProductInfoQuerySnakeDTO param) {
......@@ -111,8 +117,9 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* @param isErp true=ERP 模式(title 双字段 OR 搜索,processing 支持 2=IS NULL,跳过 DIY/黑名单过滤)
*/
private void toQueryWrapper(CustomProductInfoQuerySnakeDTO param, LambdaQueryWrapper<CustomProductInfoEntity> queryWrapper, boolean isErp) {
// 分类层级过滤
// 分类层级过滤,获取该分类以及其子类, page查询条件
if (param.getCategory_id() != null) {
// 调用saasAdmin服务,获取所有分类信息
List<CategoryInfoModel> cateList = saasAdminService.getAllList();
if (CollectionUtils.isEmpty(cateList)) {
cateList = Collections.emptyList();
......@@ -121,9 +128,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
CategoryInfoModel cate = cateList.stream().filter(c -> c.getId().equals(param.getCategory_id()))
.findFirst().orElseThrow(() -> new ServiceException("不存在该类别, category_id=" + param.getCategory_id()));
String pids = String.valueOf(cate.getId());
// 获取该类别的父类
if (StringUtils.isNotBlank(cate.getPids())) {
pids = cate.getPids() + "," + pids;
}
// 父类id,如: 0,19,26,33
String finalPids = pids;
// 获取该类别及子类别的 ID
List<Integer> cateIds = cateList.stream()
......@@ -136,7 +145,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
queryWrapper.in(CustomProductInfoEntity::getCategoryId, cateIds);
}
// 工厂 ID 过滤(通过 product_factory_rel M2M 表
// 工厂 ID 过滤(通过 product_factory_rel M2M 表,每个工厂可以有不一样的价格), page查询条件
if (param.getFactory_id() != null) {
List<Integer> factoryProductIds = productFactoryRelDomainService.list(
new LambdaQueryWrapper<ProductFactoryRelEntity>()
......@@ -150,13 +159,13 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
}
// DIY 用户过滤与黑名单过滤(仅标准分页使用,ERP权限过滤)
// DIY 用户过滤与黑名单过滤(仅标准分页使用,ERP权限过滤), page查询条件, erpPage查询跳过
if (!isErp) {
applyDiyAndBlacklistFilter(param, queryWrapper);
queryWrapper.orderByDesc(CustomProductInfoEntity::getId);
}
// 是否九猫处理过滤(0=否 1=是 2=未设置,也支持 true/false)
// 是否九猫处理过滤(0=否 1=是 2=未设置,也支持 true/false), page查询条件, erpPage查询跳过
Integer processing = param.getProcessing();
if (processing != null ) {
if (processing == ProcessingStatus.NOT_SET.getCode()) {
......@@ -170,48 +179,51 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
if (param.getId() != null) {
queryWrapper.eq(CustomProductInfoEntity::getId, param.getId());
}
// sku 支持逗号分隔多值 IN 查询
// sku 支持逗号分隔多值 IN 查询, erpPage查询条件 TODO
if (StringUtils.isNotBlank(param.getSku())) {
String[] skuArr = param.getSku().split(",");
if (skuArr.length > 1) {
if (skuArr.length > MIN_LIST_SIZE) {
queryWrapper.in(CustomProductInfoEntity::getSku, (Object[]) skuArr);
} else {
queryWrapper.eq(CustomProductInfoEntity::getSku, param.getSku());
}
}
// 状态过滤(支持逗号分隔多值,对齐 TS status split(","))
if (param.getStatusList() != null && !param.getStatusList().isEmpty()) {
queryWrapper.in(CustomProductInfoEntity::getStatus, param.getStatusList());
} else if (param.getStatus() != null) {
queryWrapper.eq(CustomProductInfoEntity::getStatus, param.getStatus());
// ERP: title 关键词同时搜索 name 和 title 两列, erpPage查询条件
if (StringUtils.isNotBlank(param.getTitle())) {
if (isErp) {
queryWrapper.and(w -> w.like(CustomProductInfoEntity::getName, param.getTitle())
.or().like(CustomProductInfoEntity::getTitle, param.getTitle()));
} else {
queryWrapper.like(CustomProductInfoEntity::getTitle, param.getTitle());
}
}
// 产品归属(平台共享/客户私有), erpPage查询条件
if (StringUtils.isNotBlank(param.getProduct_type())) {
queryWrapper.eq(CustomProductInfoEntity::getProductType, param.getProduct_type());
}
// 货号:逗号分隔多值 IN 查询,单个值模糊 LIKE 查询
// 货号:逗号分隔多值 IN 查询,单个值模糊 LIKE 查询, erpPage查询条件 TODO
if (StringUtils.isNotBlank(param.getProduct_no())) {
String[] productNoArr = param.getProduct_no().split(",");
if (productNoArr.length > 1) {
if (productNoArr.length > MIN_LIST_SIZE) {
queryWrapper.in(CustomProductInfoEntity::getProductNo, (Object[]) productNoArr);
} else {
queryWrapper.like(CustomProductInfoEntity::getProductNo, param.getProduct_no());
}
}
// 状态过滤(支持逗号分隔多值,对齐 TS status split(",")), erpPage查询条件
if (CollectionUtils.isNotEmpty(param.getStatusList())) {
queryWrapper.in(CustomProductInfoEntity::getStatus, param.getStatusList());
} else if (param.getStatus() != null) {
queryWrapper.eq(CustomProductInfoEntity::getStatus, param.getStatus());
}
// 商品类型(局部印/满印), erpPage查询条件
if (param.getPrint_type() != null) {
queryWrapper.eq(CustomProductInfoEntity::getPrintType, param.getPrint_type());
}
if (StringUtils.isNotBlank(param.getName())) {
queryWrapper.like(CustomProductInfoEntity::getName, param.getName());
}
// ERP: title 关键词同时搜索 name 和 title 两列
if (StringUtils.isNotBlank(param.getTitle())) {
if (isErp) {
queryWrapper.and(w -> w.like(CustomProductInfoEntity::getName, param.getTitle())
.or().like(CustomProductInfoEntity::getTitle, param.getTitle()));
} else {
queryWrapper.like(CustomProductInfoEntity::getTitle, param.getTitle());
}
}
// 工厂过滤(factoryIds 直接列 — 用于创建/更新场景,保留兼容)
if (param.getFactoryIds() != null) {
......@@ -220,18 +232,18 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* DIY 用户与黑名单过滤(标准分页专用)
* DIY 用户与黑名单过滤(标准分页专用), page查询条件
* <p>
* diyUserId 与 blackUserId 互斥(else if),
* diyUserId=-1 使用 LEFT JOIN 语义查找无绑定的商品。
*/
private void applyDiyAndBlacklistFilter(CustomProductInfoQuerySnakeDTO param, LambdaQueryWrapper<CustomProductInfoEntity> queryWrapper) {
if (param.getDiyUserId() != null) {
if (param.getDiyUserId() == -1) {
if (param.getDiyUserId() == NEGATIVE_ONE) {
// 查找无任何 diy_user 绑定的商品(通过 Domain 层 LEFT JOIN 查询)
List<Integer> unboundIds = customProductInfoDomainService.selectIdsWithoutDiyUserBind();
if (CollectionUtils.isEmpty(unboundIds)) {
queryWrapper.eq(CustomProductInfoEntity::getId, -1);
queryWrapper.eq(CustomProductInfoEntity::getId, NEGATIVE_ONE);
} else {
queryWrapper.in(CustomProductInfoEntity::getId, unboundIds);
}
......@@ -242,7 +254,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
.stream().map(CustomProductDiyUserRelEntity::getProductId)
.distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(productIds)) {
queryWrapper.eq(CustomProductInfoEntity::getId, -1);
queryWrapper.eq(CustomProductInfoEntity::getId, NEGATIVE_ONE);
} else {
queryWrapper.in(CustomProductInfoEntity::getId, productIds);
}
......@@ -255,7 +267,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
.stream().map(CustomProductBlacklistEntity::getProductId)
.distinct().collect(Collectors.toList());
if (productIds.isEmpty()) {
queryWrapper.eq(CustomProductInfoEntity::getId, -1);
queryWrapper.eq(CustomProductInfoEntity::getId, NEGATIVE_ONE);
} else {
queryWrapper.in(CustomProductInfoEntity::getId, productIds);
}
......@@ -416,7 +428,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
return fullVO;
}
/** 校验并查询商品主表实体 */
/**
* 校验并查询商品主表实体 , getByIdOrSku 接口检查
* @param id 商品 ID
* @param sku 商品 SKU
*/
private CustomProductInfoEntity validateAndQueryEntity(Integer id, String sku) {
CustomProductInfoEntity entity;
if (id != null) {
......@@ -433,7 +449,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* 并行查询所有子表数据,带超时保护
* 并行查询所有子表数据,带超时保护, getByIdOrSku 接口组装数据
* @param productId 商品 ID
*/
private ProductRelatedData queryRelatedDataInParallel(Integer productId) {
CompletableFuture<List<CustomProductItemEntity>> itemsFuture = CompletableFuture.supplyAsync(() ->
......@@ -520,7 +537,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* 并行查询结果聚合
* 并行查询结果聚合, getByIdOrSku 接口组装数据
*/
private record ProductRelatedData(
List<CustomProductItemEntity> items,
......@@ -537,14 +554,14 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
/**
* 通过 AdminPropertyService 解析属性名称,填充到 FullVO 的 skuProperties / normalProperties 中
* <p>
* 对齐ts代码,将数据库中存储的 property_id/value_id 转换为带名称的属性列表。
* 对齐ts代码,将数据库中存储的 property_id/value_id 转换为带名称的属性列表。getByIdOrSku 接口组装数据
*
* @param properties 数据库原始属性记录
* @param fullVO 待填充的商品完整详情
*/
private void resolvePropertyNames(List<CustomProductInfoPropertyEntity> properties,
CustomProductInfoSnakeVO fullVO) {
if (properties == null || properties.isEmpty()) {
if (CollectionUtils.isEmpty(properties)) {
return;
}
fullVO.setProperties(properties.stream().map(e -> BeanMapper.snakeCase()
......@@ -875,20 +892,19 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
diyWrapper.eq(DbDiyEntity::getNamespace, param.getSource());
}
List<DbDiyEntity> diys = dbDiyDomainService.list(diyWrapper);
if (diys.isEmpty()) {
if (CollectionUtils.isEmpty(diys)) {
return emptyPage(param);
}
List<Integer> diyIds = diys.stream().map(DbDiyEntity::getId).collect(Collectors.toList());
List<ProductTemplateInfoEntity> temps = productTemplateInfoDomainService.selectByDiyIds(diyIds);
if (temps.isEmpty()) {
if (CollectionUtils.isEmpty(temps)) {
return emptyPage(param);
}
List<Integer> productIds = temps.stream()
.map(ProductTemplateInfoEntity::getProductId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (productIds.isEmpty()) {
.distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(productIds)) {
return emptyPage(param);
}
queryWrapper.in(CustomProductInfoEntity::getId, productIds);
......@@ -899,14 +915,14 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
List<CustomWarehouseInfoEntity> warehouses = customWarehouseInfoDomainService.list(
new LambdaQueryWrapper<CustomWarehouseInfoEntity>()
.eq(CustomWarehouseInfoEntity::getCountryCode, param.getWarehouseCountry()));
if (warehouses.isEmpty()) {
if (CollectionUtils.isEmpty(warehouses)) {
return emptyPage(param);
}
List<Integer> wIds = warehouses.stream()
.map(w -> w.getId().intValue())
.collect(Collectors.toList());
List<CustomProductWarehouseRelEntity> rels = customProductWarehouseRelDomainService.selectByWarehouseIds(wIds);
if (rels.isEmpty()) {
if (CollectionUtils.isEmpty(rels)) {
return emptyPage(param);
}
List<Integer> productIds = rels.stream()
......@@ -917,7 +933,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
// 5. ERP 权限过滤
if (user != null) {
List<Integer> allowedIds = customProductInfoDomainService.selectIdsByErpPermission(user.getId());
if (allowedIds.isEmpty()) {
if (CollectionUtils.isEmpty(allowedIds)) {
return emptyPage(param);
}
queryWrapper.in(CustomProductInfoEntity::getId, allowedIds);
......@@ -931,8 +947,10 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
queryWrapper.orderByDesc(CustomProductInfoEntity::getId);
}
} else {
// 默认排序需要 sort IS NULL ASC 确保 NULL 排在非 NULL 之后(对齐 TS Sequelize.literal)
queryWrapper.last(" ORDER BY sort IS NULL ASC, sort ASC, id DESC");
// 默认排序:sort 升序(未设置排序的排最后),同值按 id 倒序
// sort 字段在 save/update 时已将 NULL 替换为 SORT_UNSET,无需 sort IS NULL 表达式
queryWrapper.orderByAsc(CustomProductInfoEntity::getSort)
.orderByDesc(CustomProductInfoEntity::getId);
}
// 7. 执行分页查询
......@@ -995,7 +1013,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* 批量查询 DIY 模板上架状态,返回 diyId → isShelf 映射
* 批量查询 DIY 模板上架状态,返回 diyId → isShelf 映射,erpPage 接口中使用
* <p>
* 使用单次 IN 查询代替 N+1 逐条查询。
*/
......@@ -1005,7 +1023,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (diyIds.isEmpty()) {
if (CollectionUtils.isEmpty(diyIds)) {
return Collections.emptyMap();
}
List<DbDiyEntity> diys = dbDiyDomainService.list(
......@@ -1021,19 +1039,19 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* 批量查询工艺关联(对齐 TS erpPage include: CraftCenter → BelongsToMany → CustomProductCraftRel)
* <p>
* 每个 craft VO 嵌套一份 CustomProductCraftRel 数据(product_id + craft_id),
* 对齐 TS Sequelize BelongsToMany 自动包含的 junction 表数据
* 对齐 TS Sequelize BelongsToMany 自动包含的 junction 表数据,erpPage 接口中使用
*
* @return productId → List&lt;CraftCenterSnakeVO&gt;
*/
private Map<Integer, List<CraftCenterSnakeVO>> batchLoadCraftsByProductIds(List<Integer> productIds) {
if (productIds.isEmpty()) {
if (CollectionUtils.isEmpty(productIds)) {
return Collections.emptyMap();
}
// 1. 关联表
List<CustomProductCraftRelEntity> rels = customProductCraftRelDomainService.list(
new LambdaQueryWrapper<CustomProductCraftRelEntity>()
.in(CustomProductCraftRelEntity::getProductId, productIds));
if (rels.isEmpty()) {
if (CollectionUtils.isEmpty(rels)) {
return Collections.emptyMap();
}
// 2. 工艺实体
......@@ -1061,18 +1079,20 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
/**
* 批量查询仓库关联(对齐 TS erpPage include: CustomWarehouseInfo → BelongsToMany → CustomProductWarehouseRel)
* <p>
* erpPage 接口中使用
*
* @return productId → List&lt;CustomWarehouseInfoSnakeVO&gt;
* @return productId → List<CustomWarehouseInfoSnakeVO>
*/
private Map<Integer, List<CustomWarehouseInfoSnakeVO>> batchLoadWarehousesByProductIds(List<Integer> productIds) {
if (productIds.isEmpty()) {
if (CollectionUtils.isEmpty(productIds)) {
return Collections.emptyMap();
}
// 1. 关联表
List<CustomProductWarehouseRelEntity> rels = customProductWarehouseRelDomainService.list(
new LambdaQueryWrapper<CustomProductWarehouseRelEntity>()
.in(CustomProductWarehouseRelEntity::getProductId, productIds));
if (rels.isEmpty()) {
if (CollectionUtils.isEmpty(rels)) {
return Collections.emptyMap();
}
// 2. 仓库实体
......@@ -1099,17 +1119,18 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
/**
* 批量查询工厂价格区间关联(对齐 TS erpPage include: CustomProductFactoryPriceIntervalRel → HasMany)
*
* @return productId → List&lt;FactoryPriceIntervalRelSnakeVO&gt;
* <p>
* erpPage 接口中使用
* @return productId → List<FactoryPriceIntervalRelSnakeVO>
*/
private Map<Integer, List<FactoryPriceIntervalRelSnakeVO>> batchLoadFactoryPriceIntervalsByProductIds(List<Integer> productIds) {
if (productIds.isEmpty()) {
if (CollectionUtils.isEmpty(productIds)) {
return Collections.emptyMap();
}
List<CustomProductFactoryPriceIntervalRelEntity> rels = customProductFactoryPriceIntervalRelDomainService.list(
new LambdaQueryWrapper<CustomProductFactoryPriceIntervalRelEntity>()
.in(CustomProductFactoryPriceIntervalRelEntity::getProductId, productIds));
if (rels.isEmpty()) {
if (CollectionUtils.isEmpty(rels)) {
return Collections.emptyMap();
}
List<FactoryPriceIntervalRelSnakeVO> voList = rels.stream().map(r -> {
......@@ -1128,7 +1149,21 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
/**
* 从事务外的子项列表中计算主表的 factory_price / sales_price / sales_price_max
* <p>
* factory_price 取子项中的最小值,sales_price 取子项中的最大值,sales_price_max 取子项中的最大值。
* factory_price 取子项中的最大值,sales_price 取子项中的最大值,sales_price_max 取子项中的最大值。
* <p>
* 参考TS 代码如下:
* if (productInfo.factory_price == null || new Decimal(productInfo.factory_price).lessThan(new Decimal(item.factory_price))) {
* productInfo.factory_price = item.factory_price;
* }
* if (productInfo.sales_price == null || new Decimal(productInfo.sales_price).lessThan(new Decimal(item.sales_price))) {
* productInfo.sales_price = item.sales_price;
* }
* if (productInfo.sales_price_max == null || new Decimal(productInfo.sales_price_max).greaterThan(new Decimal(item.sales_price))) {
* productInfo.sales_price_max = item.sales_price;
* }
*
* saveFull 批量保存时使用
*
*/
private void computeProductPricesFromItems(CustomProductInfoSaveSnakeDTO dto) {
if (dto.getProductList() == null || dto.getProductList().isEmpty()) {
......@@ -1171,6 +1206,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* <p>
* SaveDTO 使用驼峰命名,与 Entity 字段名一致,直接用默认 mapper 转换。
* 对于蛇形命名的 {@link CustomProductInfoSaveSnakeDTO},调用方需先用 {@code BeanMapper.snakeCase()} 转为 SaveDTO。
* <p>
* saveFull 批量保存时使用
*
* @param dto 保存 DTO(驼峰命名)
* @param sku 生成的 SKU(创建时传入,更新时传 null)
......@@ -1188,6 +1225,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* 逐条保存子项并返回原始 SKU → 已保存实体的映射
* <p>
* 逐条保存是为了获取每条记录的自增 ID,供后续工厂价格关联的 item_id 填充使用。
* <p>
* saveFull 批量保存时使用
*
* @return Map<原始DTO中的SKU, 已保存的实体(含自增ID和替换后的SKU)>
*/
......@@ -1222,6 +1261,9 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* 保存工厂价格关联(利用 itemMap 替换 item_sku 为生成的 SKU 并填充 item_id)
* <p>
* 对齐 TS {@code save}
* <p>
* saveFull 批量保存时使用
*
*/
private void saveFactoryPriceRels(List<FactoryPriceRelSnakeDTO> factoryPriceList,
Integer productId,
......@@ -1669,7 +1711,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* 重建关联关系(先删后插)
* 重建关联关系(先删后插),update接口使用
*/
private void rebuildRels(List<Integer> factoryIds, List<Integer> warehouseIds,
List<Integer> craftIds, List<Integer> diyUserIds,
......@@ -1750,7 +1792,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
}
/**
* 将并行查询结果组装为 FullVO
* 将并行查询结果组装为 FullVO, getByIdOrSku接口使用
*/
private CustomProductInfoSnakeVO buildProductFullVO(CustomProductInfoEntity entity,
List<CustomProductItemEntity> items,
......
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.vo.CustomProductWarehouseRelPageVO;
import com.jomalls.custom.app.vo.CustomProductWarehouseRelVO;
import com.jomalls.custom.app.service.CustomProductWarehouseRelService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity;
import com.jomalls.custom.domain.service.CustomProductWarehouseRelDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 接口实现
* @date 2026-05-29 10:43:29
*/
@Slf4j
@Service
public class CustomProductWarehouseRelServiceImpl implements CustomProductWarehouseRelService {
private final CustomProductWarehouseRelDomainService customProductWarehouseRelDomainService;
@Autowired
public CustomProductWarehouseRelServiceImpl(CustomProductWarehouseRelDomainService customProductWarehouseRelDomainService) {
this.customProductWarehouseRelDomainService = customProductWarehouseRelDomainService;
}
@Override
public List<CustomProductWarehouseRelVO> list(CustomProductWarehouseRelVO customProductWarehouseRelVO) {
QueryWrapper<CustomProductWarehouseRelEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<CustomProductWarehouseRelEntity> list = customProductWarehouseRelDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductWarehouseRelVO.class)).collect(Collectors.toList());
}
@Override
public IPage<CustomProductWarehouseRelVO> pageList(CustomProductWarehouseRelPageVO customProductWarehouseRelPageVO) {
CustomAsserts.nonNull(customProductWarehouseRelPageVO, "分页查询参数不能为空");
QueryWrapper<CustomProductWarehouseRelEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<CustomProductWarehouseRelEntity> page = customProductWarehouseRelDomainService.selectPage(queryWrapper, customProductWarehouseRelPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductWarehouseRelVO.class));
}
@Override
public CustomProductWarehouseRelVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductWarehouseRelEntity customProductWarehouseRel = customProductWarehouseRelDomainService.getById(id);
return BeanMapper.mapper().convert(customProductWarehouseRel, CustomProductWarehouseRelVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductWarehouseRelVO customProductWarehouseRelVO) {
CustomAsserts.nonNull(customProductWarehouseRelVO, "实体对象不能为空");
CustomProductWarehouseRelEntity customProductWarehouseRelEntity = BeanMapper.mapper().convert(customProductWarehouseRelVO, CustomProductWarehouseRelEntity.class);
try {
customProductWarehouseRelDomainService.save(customProductWarehouseRelEntity);
} catch (DuplicateKeyException e) {
log.info("[ CustomProductWarehouseRelServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductWarehouseRelVO customProductWarehouseRelVO) {
CustomAsserts.nonNull(customProductWarehouseRelVO, "实体对象不能为空");
CustomProductWarehouseRelEntity customProductWarehouseRel = BeanMapper.mapper().convert(customProductWarehouseRelVO, CustomProductWarehouseRelEntity.class);
try {
customProductWarehouseRelDomainService.updateById(customProductWarehouseRel);
} catch (DuplicateKeyException e) {
log.info("[ CustomProductWarehouseRelServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
customProductWarehouseRelDomainService.removeById(id);
}
/**
* 根据仓库ID获取关联列表
*/
@Override
public List<CustomProductWarehouseRelEntity> getListByWareHouseId(Long warehouseId) {
return customProductWarehouseRelDomainService.list(new LambdaQueryWrapper<CustomProductWarehouseRelEntity>()
.eq(CustomProductWarehouseRelEntity::getWarehouseId, warehouseId));
}
/**
* 根据产品ID获取关联列表
*/
@Override
public List<CustomProductWarehouseRelEntity> getListByProductId(Long productId) {
return customProductWarehouseRelDomainService.list(new LambdaQueryWrapper<CustomProductWarehouseRelEntity>()
.eq(CustomProductWarehouseRelEntity::getProductId, productId));
}
/**
* 根据产品ID获取仓库ID列表
*/
@Override
public List<Long> getWarehouseIdsByProductId(Long productId) {
List<CustomProductWarehouseRelEntity> rels = customProductWarehouseRelDomainService.list(new LambdaQueryWrapper<CustomProductWarehouseRelEntity>()
.eq(CustomProductWarehouseRelEntity::getProductId, productId)
.select(CustomProductWarehouseRelEntity::getWarehouseId)); // 只查询需要的字段以提高性能
if (CollectionUtils.isEmpty(rels)) {
return null;
}
return rels.stream()
.map(CustomProductWarehouseRelEntity::getWarehouseId)
.collect(Collectors.toList());
}
/**
* 根据产品ID删除关联
* 注意:原 TS 代码支持手动传入 transaction,Java 中通常使用 @Transactional 注解管理事务
*/
@Override
public void deleteByProductId(Integer productId) {
customProductWarehouseRelDomainService.remove(new LambdaQueryWrapper<CustomProductWarehouseRelEntity>()
.eq(CustomProductWarehouseRelEntity::getProductId, productId));
}
/**
* 批量保存产品与仓库的关联
* 逻辑:先删除该产品现有的所有关联,再批量插入新的
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveBatch(Integer productId, List<Long> warehouseIds) {
this.deleteByProductId(productId);
if (CollectionUtils.isEmpty(warehouseIds)) {
return;
}
List<CustomProductWarehouseRelEntity> relList = new ArrayList<>();
for (Long warehouseId : warehouseIds) {
CustomProductWarehouseRelEntity rel = new CustomProductWarehouseRelEntity();
rel.setProductId(productId);
rel.setWarehouseId(warehouseId);
relList.add(rel);
}
customProductWarehouseRelDomainService.saveBatch(relList);
}
}
......@@ -42,15 +42,14 @@ public class DiyUserServiceImpl implements DiyUserService {
if (StringUtils.isBlank(namespace)) {
return null;
}
DbDiyUserEntity user = dbDiyUserDomainService.getByNamespace(namespace);
if (user == null) {
throw new ServiceException("用户不存在, namespace=" + namespace);
}
return user;
return dbDiyUserDomainService.getByNamespace(namespace);
}
@Override
public DbDiyUserEntity getByUserMark(String userMark) {
if (StringUtils.isBlank(userMark)) {
return null;
}
return dbDiyUserDomainService.getByUserMark(userMark);
}
......
......@@ -24,7 +24,7 @@ import java.util.List;
*/
@Getter
@AllArgsConstructor
public class PageAdaptter<T> implements Serializable {
public class PageAdapter<T> implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -51,8 +51,8 @@ public class PageAdaptter<T> implements Serializable {
* @param <T> 数据类型
* @return 老服务格式的分页结果
*/
public static <T> PageAdaptter<T> from(IPage<T> page) {
return new PageAdaptter<>(
public static <T> PageAdapter<T> from(IPage<T> page) {
return new PageAdapter<>(
page.getRecords(),
page.getCurrent(),
page.getTotal(),
......
......@@ -8,6 +8,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
......@@ -50,11 +51,11 @@ public class CraftCenterEntity implements Serializable {
/** 工艺成本 */
@TableField("craft_cost")
private String craftCost;
private BigDecimal craftCost;
/** 其他面的价格 */
@TableField("other_side_cost")
private String otherSideCost;
private BigDecimal otherSideCost;
/** 是否启用(1启用,0未启用) */
@TableField("craft_enable")
......
......@@ -33,44 +33,6 @@
create_by, create_time, update_by, update_time, remark
</sql>
<!-- 根据用户名查询用户 -->
<select id="selectByUsername" resultMap="sysUserMap">
SELECT <include refid="tableColumns"/>
FROM sys_user
WHERE user_name = #{userName}
AND status = '0'
AND del_flag = '0'
</select>
<!-- 根据邮箱查询用户 -->
<select id="selectByEmail" resultMap="sysUserMap">
SELECT <include refid="tableColumns"/>
FROM sys_user
WHERE email = #{email}
AND status = '0'
AND del_flag = '0'
</select>
<!-- 分页查询用户列表 -->
<select id="selectUserPage" resultMap="sysUserMap">
SELECT <include refid="tableColumns"/>
FROM sys_user
WHERE del_flag = '0'
<if test="status != null">
AND status = #{status}
</if>
ORDER BY create_time DESC
</select>
<!-- 查询所有启用状态的用户 -->
<select id="selectAllActiveUsers" resultMap="sysUserMap">
SELECT <include refid="tableColumns"/>
FROM sys_user
WHERE status = '0'
AND del_flag = '0'
ORDER BY create_time DESC
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_user (user_name, nick_name, user_type,
......
......@@ -44,7 +44,7 @@ public class WebClientConfig {
public ConnectionProvider connectionProvider() {
return ConnectionProvider.builder("custom-server-http-pool")
.maxConnections(poolMaxConnections)
.pendingAcquireMaxCount(-1)
.pendingAcquireMaxCount(100)
.pendingAcquireTimeout(Duration.ofMillis(poolAcquireTimeout))
.maxIdleTime(Duration.ofSeconds(60))
.maxLifeTime(Duration.ofMinutes(5))
......
......@@ -27,44 +27,10 @@ import java.util.concurrent.atomic.AtomicReference;
* 调用 admin API 获取商品分类数据。
* 对齐 TS 项目 {@code baseCategoryInfoService}。
*
* @author zhengcunwen
* @author Lizh (Java 迁移)
* @since 2019-09-02
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SaasAdminService {
private static final String GET_TREE_URL = "/api/manage/rest/baseCategoryInfo/tree_list";
private static final String GET_BY_IDS_URL = "/api/manage/rest/baseCategoryInfo/getDataByIds";
private static final String GET_BY_ID_URL = "/api/manage/rest/baseCategoryInfo/get";
private static final String GET_ALL_LIST_URL = "/api/manage/rest/baseCategoryInfo/all_list";
private static final String GET_PROPERTY_BY_IDS_URL = "/api/manage/rest/baseProperty/getByIds";
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 AtomicReference<CacheEntry<List<CategoryInfoModel>>> categoryCache = new AtomicReference<>();
@Value("${server.admin.base-url:https://admin.jomalls.com}")
private String adminBaseUrl;
private Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>(DEFAULT_MAP_SIZE);
headers.put("Content-Type", "application/json");
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return headers;
}
headers.put("jwt-token", loginUser.getToken());
return headers;
}
public interface SaasAdminService {
/**
* 根据属性 ID 列表批量查询属性(含属性值列表)
......@@ -74,115 +40,7 @@ public class SaasAdminService {
* @param ids 属性 ID,逗号分隔(如 "1,2,3")
* @return 属性列表,包含 valueList 和 skuProperty 等字段
*/
public List<PropertyModel> getPropertyByIds(String ids) {
if (!StringUtils.hasText(ids)) {
return Collections.emptyList();
}
try {
String url = adminBaseUrl + GET_PROPERTY_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<SaasAdminApiResponseModel<List<PropertyModel>>> response = remoteApiClient.get(
url,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
log.debug("[ SaasAdminService ] getByIds 成功, ids={}, 返回: {}", ids, response.toString());
SaasAdminApiResponseModel<List<PropertyModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData();
}
}
log.warn("[ SaasAdminService ] getByIds 返回空, ids={}", ids);
return Collections.emptyList();
} catch (Exception e) {
log.error("[ SaasAdminService ] getByIds 调用失败, ids={}", ids, e);
return Collections.emptyList();
}
}
/**
* 获取分类树
* <p>
* 对齐 TS {@code getTree()}
*/
public List<CategoryInfoModel> getTree() {
try {
ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ SaasAdminService ] getTree 调用失败", e);
}
return Collections.emptyList();
}
/**
* 根据 ID 列表批量查询
* <p>
* 对齐 TS {@code getByIds(ids)}
*/
public List<CategoryInfoModel> getByIds(String ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
try {
String url = adminBaseUrl + GET_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
url,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ SaasAdminService ] getByIds 调用失败, ids={}", ids, e);
}
return Collections.emptyList();
}
/**
* 获取带有风格属性的树形结构
* <p>
* 对齐 TS {@code treeList()}
*/
public List<CategoryInfoModel> treeList() {
try {
ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ SaasAdminService ] treeList 调用失败", e);
}
return Collections.emptyList();
}
/**
* 根据 ID 查询单个分类
* <p>
* 对齐 TS {@code getById(id)}
*/
public CategoryInfoModel getById(Integer id) {
if (id == null) {
return null;
}
try {
String url = adminBaseUrl + GET_BY_ID_URL + "?id=" + id;
ResponseEntity<CategoryInfoModel> response = remoteApiClient.get(
url, CategoryInfoModel.class, null);
if (response != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ SaasAdminService ] getById 调用失败, id={}", id, e);
}
return null;
}
List<PropertyModel> getPropertyByIds(String ids);
/**
* 查询所有分类(带本地缓存,TTL 5 分钟)
......@@ -190,49 +48,5 @@ public class SaasAdminService {
* 对齐 TS {@code allList()}。分类数据不频繁变动,
* 使用本地缓存避免每次分页查询都发起远程 HTTP 调用。
*/
public List<CategoryInfoModel> getAllList() {
// 命中缓存且未过期 → 直接返回
CacheEntry<List<CategoryInfoModel>> entry = categoryCache.get();
if (entry != null && !entry.isExpired()) {
return entry.data;
}
// 未命中或已过期 → 远程调用刷新
try {
ResponseEntity<SaasAdminApiResponseModel<List<CategoryInfoModel>>> response = remoteApiClient.get(
adminBaseUrl + GET_ALL_LIST_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
SaasAdminApiResponseModel<List<CategoryInfoModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
List<CategoryInfoModel> data = responseBody.getData();
categoryCache.set(new CacheEntry<>(data));
return data;
}
}
} catch (Exception e) {
log.error("[ SaasAdminService ] getAllList 调用失败", e);
}
// 远程调用失败但有旧缓存 → 降级返回旧缓存
if (entry != null) {
log.warn("[ SaasAdminService ] getAllList 远程失败,降级使用过期缓存");
return entry.data;
}
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;
}
}
List<CategoryInfoModel> getAllList();
}
package com.jomalls.custom.integrate.service.impl;
import com.jomalls.custom.enums.CodeEnum;
import com.jomalls.custom.integrate.client.RemoteApiClient;
import com.jomalls.custom.integrate.model.CategoryInfoModel;
import com.jomalls.custom.integrate.model.PropertyModel;
import com.jomalls.custom.integrate.model.SaasAdminApiResponseModel;
import com.jomalls.custom.integrate.service.SaasAdminService;
import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* 商品分类服务
* <p>
* 调用 admin API 获取商品分类数据。
* 对齐 TS 项目 {@code baseCategoryInfoService}。
*
* @author Lizh (Java 迁移)
* @since 2019-09-02
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SaasAdminServiceImpl implements SaasAdminService {
private static final String GET_ALL_LIST_URL = "/api/manage/rest/baseCategoryInfo/all_list";
private static final String GET_PROPERTY_BY_IDS_URL = "/api/manage/rest/baseProperty/getByIds";
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 AtomicReference<CacheEntry<List<CategoryInfoModel>>> categoryCache = new AtomicReference<>();
@Value("${server.admin.base-url:https://admin.jomalls.com}")
private String adminBaseUrl;
private Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>(DEFAULT_MAP_SIZE);
headers.put("Content-Type", "application/json");
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return headers;
}
headers.put("jwt-token", loginUser.getToken());
return headers;
}
/**
* 根据属性 ID 列表批量查询属性(含属性值列表)
* <p>
* 对齐 TS {@code getByIds(ids)} 方法。
*
* @param ids 属性 ID,逗号分隔(如 "1,2,3")
* @return 属性列表,包含 valueList 和 skuProperty 等字段
*/
public List<PropertyModel> getPropertyByIds(String ids) {
if (!StringUtils.hasText(ids)) {
return Collections.emptyList();
}
try {
String url = adminBaseUrl + GET_PROPERTY_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<SaasAdminApiResponseModel<List<PropertyModel>>> response = remoteApiClient.get(
url,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
log.debug("[ SaasAdminService ] getByIds 成功, ids={}, 返回: {}", ids, response.toString());
SaasAdminApiResponseModel<List<PropertyModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData();
}
}
log.warn("[ SaasAdminService ] getByIds 返回空, ids={}", ids);
return Collections.emptyList();
} catch (Exception e) {
log.error("[ SaasAdminService ] getByIds 调用失败, ids={}", ids, e);
return Collections.emptyList();
}
}
/**
* 查询所有分类(带本地缓存,TTL 5 分钟)
* <p>
* 对齐 TS {@code allList()}。分类数据不频繁变动,
* 使用本地缓存避免每次分页查询都发起远程 HTTP 调用。
*/
public List<CategoryInfoModel> getAllList() {
// 命中缓存且未过期 → 直接返回
CacheEntry<List<CategoryInfoModel>> entry = categoryCache.get();
if (entry != null && !entry.isExpired()) {
return entry.data;
}
// 未命中或已过期 → 远程调用刷新
try {
ResponseEntity<SaasAdminApiResponseModel<List<CategoryInfoModel>>> response = remoteApiClient.get(
adminBaseUrl + GET_ALL_LIST_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
SaasAdminApiResponseModel<List<CategoryInfoModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
List<CategoryInfoModel> data = responseBody.getData();
categoryCache.set(new CacheEntry<>(data));
return data;
}
}
} catch (Exception e) {
log.error("[ SaasAdminService ] getAllList 调用失败", e);
}
// 远程调用失败但有旧缓存 → 降级返回旧缓存
if (entry != null) {
log.warn("[ SaasAdminService ] getAllList 远程失败,降级使用过期缓存");
return entry.data;
}
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;
}
}
}
......@@ -3,7 +3,7 @@ package com.jomalls.custom.config;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jomalls.custom.enums.CodeEnum;
import com.jomalls.custom.page.PageAdaptter;
import com.jomalls.custom.page.PageAdapter;
import org.jspecify.annotations.NonNull;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
......@@ -63,7 +63,7 @@ public class RestResponseBodyConfig implements ResponseBodyAdvice<Object> {
} else {
// 分页结果转为老服务(TS)格式:records→list, current→curPage, total→totalRow, pages→totalPage
if (body instanceof IPage<?> page) {
body = PageAdaptter.from(page);
body = PageAdapter.from(page);
}
if (body instanceof String) {
try {
......
......@@ -8,7 +8,7 @@ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#最小空闲连接数
spring.datasource.hikari.minimum-idle=5
#最大连接池大小
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.maximum-pool-size=50
#连接超时时间(60秒)
spring.datasource.hikari.connection-timeout=60000
#空闲连接超时时间(600秒)
......
......@@ -5,7 +5,7 @@ server.servlet.context-path=/
## Tomcat配置
server.tomcat.uri-encoding=UTF-8
server.tomcat.accept-count=1000
server.tomcat.threads.max=800
server.tomcat.threads.max=200
server.tomcat.threads.min-spare=100
## Spring配置
......@@ -35,7 +35,7 @@ server.needAuthentication=true
token.header=Authorization
# 令牌密钥(兼容旧版本)
token.secret=custom
# 令牌有效期(默认30分钟)
# 令牌有效期(单位:分钟)
token.expireTime=720
# HTTP Client Configuration
......
......@@ -69,7 +69,7 @@ public class CustomProductInfoController {
}
@Operation(summary = "绑定默认模型", description = "设置商品的默认 DIY 模板")
@GetMapping("/bindDefaultDiy")
@PostMapping("/bindDefaultDiy")
public void bindDefaultDiy(
@Parameter(description = "商品 ID") @RequestParam Integer id,
@Parameter(description = "DIY 模板 ID") @RequestParam Integer diyId,
......
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