Commit 315f36e6 by Lizh

参照ts迁移商品分页查询page接口

parent 43164dcf
...@@ -311,6 +311,12 @@ public class CustomProductInfoSnakeDTO extends PageRequest { ...@@ -311,6 +311,12 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
@Schema(description = "工厂 ID 列表") @Schema(description = "工厂 ID 列表")
private List<Integer> factoryIds; private List<Integer> factoryIds;
/**
* 工厂 ID(单值,用于分页查询过滤 — 通过 product_factory_rel 表查询,对齐 TS factory_id)
*/
@Schema(description = "工厂 ID(分页过滤用,通过关联表过滤)")
private Integer factory_id;
/** 以下为ERP 专用查询字段 */ /** 以下为ERP 专用查询字段 */
@Schema(description = "DIY 模板 SKU 筛选(ERP)") @Schema(description = "DIY 模板 SKU 筛选(ERP)")
private String diySku; private String diySku;
......
...@@ -65,8 +65,8 @@ public enum CustomProductInfoStatusEnum { ...@@ -65,8 +65,8 @@ public enum CustomProductInfoStatusEnum {
return Arrays.stream(values()) return Arrays.stream(values())
.map(e -> { .map(e -> {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("code", e.code); map.put("status", e.code);
map.put("label", e.label); map.put("remark", e.label);
return map; return map;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -5,9 +5,10 @@ import com.jomalls.custom.app.dto.AddBlackListDTO; ...@@ -5,9 +5,10 @@ import com.jomalls.custom.app.dto.AddBlackListDTO;
import com.jomalls.custom.app.dto.BindDiyUserDTO; import com.jomalls.custom.app.dto.BindDiyUserDTO;
import com.jomalls.custom.app.dto.CustomProductInfoSnakeDTO; import com.jomalls.custom.app.dto.CustomProductInfoSnakeDTO;
import com.jomalls.custom.app.dto.CustomProductInfoUpdateSnakeDTO; import com.jomalls.custom.app.dto.CustomProductInfoUpdateSnakeDTO;
import com.jomalls.custom.app.vo.CraftCenterVO;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO; import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO; import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.DbDiyVO; import com.jomalls.custom.app.vo.DbDiySnakeVO;
import java.util.List; import java.util.List;
...@@ -19,7 +20,7 @@ import java.util.List; ...@@ -19,7 +20,7 @@ import java.util.List;
*/ */
public interface CustomProductInfoService { public interface CustomProductInfoService {
IPage<CustomProductInfoVO> pageList(CustomProductInfoSnakeDTO param); IPage<CustomProductInfoSnakeVO> pageList(CustomProductInfoSnakeDTO param);
/** /**
* 组合创建商品(SKU 生成 + 事务内写入主表及所有子表) * 组合创建商品(SKU 生成 + 事务内写入主表及所有子表)
...@@ -74,7 +75,7 @@ public interface CustomProductInfoService { ...@@ -74,7 +75,7 @@ public interface CustomProductInfoService {
* @param id 商品 ID * @param id 商品 ID
* @return DIY 模板列表 * @return DIY 模板列表
*/ */
List<DbDiyVO> getBindsDiyById(Integer id); List<DbDiySnakeVO> getBindsDiyById(Integer id);
/** /**
* 获取商品绑定的 DIY 用户 ID 列表 * 获取商品绑定的 DIY 用户 ID 列表
...@@ -93,12 +94,14 @@ public interface CustomProductInfoService { ...@@ -93,12 +94,14 @@ public interface CustomProductInfoService {
List<Integer> getBlackListById(Integer id); List<Integer> getBlackListById(Integer id);
/** /**
* 获取商品绑定的工艺 ID 列表 * 获取商品绑定的工艺列表
* <p>
* 对齐 TS getCraftById → getCraftByProductId,返回完整工艺实体而非仅 ID。
* *
* @param id 商品 ID * @param id 商品 ID
* @return 工艺 ID 列表 * @return 工艺实体列表
*/ */
List<Long> getCraftById(Integer id); List<CraftCenterVO> getCraftById(Integer id);
// ==================== ERP 专用接口(对齐 TS) ==================== // ==================== ERP 专用接口(对齐 TS) ====================
...@@ -112,5 +115,5 @@ public interface CustomProductInfoService { ...@@ -112,5 +115,5 @@ public interface CustomProductInfoService {
/** /**
* ERP 获取绑定 DIY(对齐 TS getBindsDiyByIdAndUserMark) * ERP 获取绑定 DIY(对齐 TS getBindsDiyByIdAndUserMark)
*/ */
List<DbDiyVO> getErpBindsDiyById(Integer id, String userMark, String namespace); List<DbDiySnakeVO> getBindsDiyByIdAndUserMark(Integer id, String userMark, String namespace);
} }
...@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service; ...@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.DbDiyPageVO; import com.jomalls.custom.app.vo.DbDiyPageVO;
import com.jomalls.custom.app.vo.DbDiyVO; import com.jomalls.custom.app.vo.DbDiySnakeVO;
import java.util.List; import java.util.List;
...@@ -17,10 +17,10 @@ public interface DbDiyService { ...@@ -17,10 +17,10 @@ public interface DbDiyService {
/** /**
* 列表查询接口 * 列表查询接口
* *
* @param dbDiyVO 条件model * @param dbDiySnakeVO 条件model
* @return list集合 * @return list集合
*/ */
List<DbDiyVO> list(DbDiyVO dbDiyVO); List<DbDiySnakeVO> list(DbDiySnakeVO dbDiySnakeVO);
/** /**
* 根据条件查询分页列表接口 * 根据条件查询分页列表接口
...@@ -28,7 +28,7 @@ public interface DbDiyService { ...@@ -28,7 +28,7 @@ public interface DbDiyService {
* @param dbDiyPageVO 分页入参model * @param dbDiyPageVO 分页入参model
* @return 分页对象 * @return 分页对象
*/ */
IPage<DbDiyVO> pageList(DbDiyPageVO dbDiyPageVO); IPage<DbDiySnakeVO> pageList(DbDiyPageVO dbDiyPageVO);
/** /**
* 根据id查询详情 * 根据id查询详情
...@@ -36,21 +36,21 @@ public interface DbDiyService { ...@@ -36,21 +36,21 @@ public interface DbDiyService {
* @param id 主键 * @param id 主键
* @return 实体model * @return 实体model
*/ */
DbDiyVO info(Integer id); DbDiySnakeVO info(Integer id);
/** /**
* 保存对象 * 保存对象
* *
* @param dbDiyVO 保存对象 * @param dbDiySnakeVO 保存对象
*/ */
void save(DbDiyVO dbDiyVO); void save(DbDiySnakeVO dbDiySnakeVO);
/** /**
* 根据id修改对象 * 根据id修改对象
* *
* @param dbDiyVO 修改对象 * @param dbDiySnakeVO 修改对象
*/ */
void updateById(DbDiyVO dbDiyVO); void updateById(DbDiySnakeVO dbDiySnakeVO);
/** /**
* 根据主键ID进行删除 * 根据主键ID进行删除
......
package com.jomalls.custom.app.service; package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.jomalls.custom.app.vo.LogCustomProductSnakeVO;
import com.jomalls.custom.app.vo.LogCustomProductPageVO;
import com.jomalls.custom.app.vo.LogCustomProductVO;
import java.util.List; import java.util.List;
...@@ -15,49 +13,13 @@ import java.util.List; ...@@ -15,49 +13,13 @@ import java.util.List;
public interface LogCustomProductService { public interface LogCustomProductService {
/** /**
* 列表查询接口 * 根据商品 ID 查询日志列表(对齐 TS list 方法)
* <p>
* 按 product_id 查询所有日志记录,按 id 降序排序。
* *
* @param logCustomProductVO 条件model * @param productId 商品 ID
* @return list集合 * @return 日志列表
*/ */
List<LogCustomProductVO> list(LogCustomProductVO logCustomProductVO); List<LogCustomProductSnakeVO> getListByProductId(Integer productId);
/**
* 根据条件查询分页列表接口
*
* @param logCustomProductPageVO 分页入参model
* @return 分页对象
*/
IPage<LogCustomProductVO> pageList(LogCustomProductPageVO logCustomProductPageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
LogCustomProductVO info(Integer id);
/**
* 保存对象
*
* @param logCustomProductVO 保存对象
*/
void save(LogCustomProductVO logCustomProductVO);
/**
* 根据id修改对象
*
* @param logCustomProductVO 修改对象
*/
void updateById(LogCustomProductVO logCustomProductVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(Integer id);
} }
...@@ -17,9 +17,9 @@ import com.jomalls.custom.app.utils.CustomAsserts; ...@@ -17,9 +17,9 @@ import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.app.vo.*; import com.jomalls.custom.app.vo.*;
import com.jomalls.custom.dal.entity.*; import com.jomalls.custom.dal.entity.*;
import com.jomalls.custom.domain.service.*; import com.jomalls.custom.domain.service.*;
import com.jomalls.custom.integrate.model.BaseCategoryInfoModel; import com.jomalls.custom.integrate.model.CategoryInfoModel;
import com.jomalls.custom.integrate.model.BasePropertyModel; import com.jomalls.custom.integrate.model.PropertyModel;
import com.jomalls.custom.integrate.model.BasePropertyValueModel; import com.jomalls.custom.integrate.model.PropertyValueModel;
import com.jomalls.custom.integrate.service.SaasAdminService; import com.jomalls.custom.integrate.service.SaasAdminService;
import com.jomalls.custom.security.LoginUser; import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils; import com.jomalls.custom.security.SecurityUtils;
...@@ -73,6 +73,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -73,6 +73,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
private final ProductTemplateInfoDomainService productTemplateInfoDomainService; private final ProductTemplateInfoDomainService productTemplateInfoDomainService;
private final DbDiyXiaoguotuDomainService dbDiyXiaoguotuDomainService; private final DbDiyXiaoguotuDomainService dbDiyXiaoguotuDomainService;
private final DiyUserService diyUserService; private final DiyUserService diyUserService;
private final DbDiyUserDomainService dbDiyUserDomainService;
private final CraftCenterDomainService craftCenterDomainService;
private final ThreadPoolExecutor threadPoolExecutor; private final ThreadPoolExecutor threadPoolExecutor;
/** 图片类型:普通图片 */ /** 图片类型:普通图片 */
...@@ -84,13 +86,17 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -84,13 +86,17 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
@Override @Override
public IPage<CustomProductInfoVO> pageList(CustomProductInfoSnakeDTO param) { public IPage<CustomProductInfoSnakeVO> pageList(CustomProductInfoSnakeDTO param) {
CustomAsserts.nonNull(param, "分页查询参数不能为空"); CustomAsserts.nonNull(param, "分页查询参数不能为空");
QueryWrapper<CustomProductInfoEntity> queryWrapper = new QueryWrapper<>(); QueryWrapper<CustomProductInfoEntity> queryWrapper = new QueryWrapper<>();
// 构造查询条件 // 构造查询条件
toQueryWrapper(param, queryWrapper); toQueryWrapper(param, queryWrapper);
IPage<CustomProductInfoEntity> page = customProductInfoDomainService.selectPage(queryWrapper, param); IPage<CustomProductInfoEntity> page = customProductInfoDomainService.selectPage(queryWrapper, param);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductInfoVO.class)); return page.convert(e -> {
CustomProductInfoSnakeVO snakeVO = BeanMapper.snakeCase().convert(e, CustomProductInfoSnakeVO.class);
snakeVO.setColorImageList(Arrays.asList(e.getColorImages().split(",")));
return snakeVO;
});
} }
/** 标准分页查询条件构建(非 ERP) */ /** 标准分页查询条件构建(非 ERP) */
...@@ -106,31 +112,51 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -106,31 +112,51 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
private void toQueryWrapper(CustomProductInfoSnakeDTO param, QueryWrapper<CustomProductInfoEntity> queryWrapper, boolean isErp) { private void toQueryWrapper(CustomProductInfoSnakeDTO param, QueryWrapper<CustomProductInfoEntity> queryWrapper, boolean isErp) {
// 分类层级过滤 // 分类层级过滤
if (param.getCategory_id() != null) { if (param.getCategory_id() != null) {
List<BaseCategoryInfoModel> cateList = saasAdminService.getAllList(); List<CategoryInfoModel> cateList = saasAdminService.getAllList();
if (cateList == null) { if (CollectionUtils.isEmpty(cateList)) {
cateList = Collections.emptyList(); cateList = Collections.emptyList();
} }
BaseCategoryInfoModel cate = cateList.stream() // 从获取所有类别选出该类别
.filter(c -> c.getId().equals(param.getCategory_id())) CategoryInfoModel cate = cateList.stream().filter(c -> c.getId().equals(param.getCategory_id()))
.findFirst() .findFirst().orElseThrow(() -> new ServiceException("不存在该类别, category_id=" + param.getCategory_id()));
.orElseThrow(() -> new ServiceException("不存在该类别, category_id=" + param.getCategory_id()));
String pids = String.valueOf(cate.getId()); String pids = String.valueOf(cate.getId());
if (cate.getPids() != null && !cate.getPids().isEmpty()) { if (cate.getPids() != null && !cate.getPids().isEmpty()) {
pids = cate.getPids() + "," + pids; pids = cate.getPids() + "," + pids;
} }
String finalPids = pids; String finalPids = pids;
// 获取该类别及子类别的 ID
List<Integer> cateIds = cateList.stream() List<Integer> cateIds = cateList.stream()
.filter(item -> { .filter(item -> {
String itemPids = item.getPids(); String itemPids = item.getPids();
return finalPids.equals(itemPids) || return finalPids.equals(itemPids) || (StringUtils.isNotEmpty(itemPids) && itemPids.startsWith(finalPids + ","));
(itemPids != null && itemPids.startsWith(finalPids + ","));
}) })
.map(BaseCategoryInfoModel::getId) .map(CategoryInfoModel::getId).collect(Collectors.toList());
.collect(Collectors.toList());
cateIds.add(cate.getId()); cateIds.add(cate.getId());
queryWrapper.in("category_id", cateIds); queryWrapper.in("category_id", cateIds);
} }
// 工厂 ID 过滤(通过 product_factory_rel M2M 表,对齐 TS:271-283)
if (param.getFactory_id() != null) {
List<Integer> factoryProductIds = productFactoryRelDomainService.list(
new LambdaQueryWrapper<ProductFactoryRelEntity>()
.eq(ProductFactoryRelEntity::getFactoryId, param.getFactory_id()))
.stream().map(ProductFactoryRelEntity::getProductId)
.distinct().collect(Collectors.toList());
if (factoryProductIds.isEmpty()) {
// 没有关联商品时返回空结果
queryWrapper.eq("id", -1);
} else {
queryWrapper.in("id", factoryProductIds);
}
}
// DIY 用户过滤与黑名单过滤(仅标准分页使用,ERP权限过滤)
if (!isErp) {
applyDiyAndBlacklistFilter(param, queryWrapper);
// 排序:按 id 降序(对齐 TS:337)
queryWrapper.orderByDesc("id");
}
// 是否九猫处理过滤 // 是否九猫处理过滤
Integer processing = param.getProcessing(); Integer processing = param.getProcessing();
if (processing != null) { if (processing != null) {
...@@ -146,26 +172,38 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -146,26 +172,38 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
if (param.getId() != null) { if (param.getId() != null) {
queryWrapper.eq("id", param.getId()); queryWrapper.eq("id", param.getId());
} }
if (param.getSku() != null && !param.getSku().isEmpty()) { // sku 支持逗号分隔多值 IN 查询(ERP查询逻辑)
if (StringUtils.isNotBlank(param.getSku())) {
String[] skuArr = param.getSku().split(",");
if (skuArr.length > 1) {
queryWrapper.in("sku", (Object[]) skuArr);
} else {
queryWrapper.eq("sku", param.getSku()); queryWrapper.eq("sku", param.getSku());
} }
}
if (param.getStatus() != null) { if (param.getStatus() != null) {
queryWrapper.eq("status", param.getStatus()); queryWrapper.eq("status", param.getStatus());
} }
if (param.getProduct_type() != null && !param.getProduct_type().isEmpty()) { if (StringUtils.isNotBlank(param.getProduct_type())) {
queryWrapper.eq("product_type", param.getProduct_type()); queryWrapper.eq("product_type", param.getProduct_type());
} }
if (param.getProduct_no() != null && !param.getProduct_no().isEmpty()) { // 货号:逗号分隔多值 IN 查询,单个值模糊 LIKE 查询(对齐 TS:774-779)
queryWrapper.eq("product_no", param.getProduct_no()); if (StringUtils.isNotBlank(param.getProduct_no())) {
String[] productNoArr = param.getProduct_no().split(",");
if (productNoArr.length > 1) {
queryWrapper.in("product_no", (Object[]) productNoArr);
} else {
queryWrapper.like("product_no", param.getProduct_no());
}
} }
if (param.getPrint_type() != null) { if (param.getPrint_type() != null) {
queryWrapper.eq("print_type", param.getPrint_type()); queryWrapper.eq("print_type", param.getPrint_type());
} }
if (param.getName() != null && !param.getName().isEmpty()) { if (StringUtils.isNotBlank(param.getName())) {
queryWrapper.like("name", param.getName()); queryWrapper.like("name", param.getName());
} }
// ERP: title 关键词同时搜索 name 和 title 两列(对齐 TS:610-611) // ERP: title 关键词同时搜索 name 和 title 两列(对齐 TS:610-611)
if (param.getTitle() != null && !param.getTitle().isEmpty()) { if (StringUtils.isNotBlank(param.getTitle())) {
if (isErp) { if (isErp) {
queryWrapper.and(w -> w.like("name", param.getTitle()).or().like("title", param.getTitle())); queryWrapper.and(w -> w.like("name", param.getTitle()).or().like("title", param.getTitle()));
} else { } else {
...@@ -173,68 +211,55 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -173,68 +211,55 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
} }
} }
// 工厂过滤(factory_id 是 custom_product_info 的直接列 // 工厂过滤(factoryIds 直接列 — 用于创建/更新场景,保留兼容
if (param.getFactoryIds() != null) { if (param.getFactoryIds() != null) {
queryWrapper.in("factory_id", param.getFactoryIds()); queryWrapper.in("factory_id", param.getFactoryIds());
} }
// DIY 用户过滤与黑名单过滤(仅标准分页使用,ERP 走 native SQL 权限过滤)
if (!isErp) {
applyDiyAndBlacklistFilter(param, queryWrapper);
}
} }
/** DIY 用户与黑名单过滤(标准分页专用) */ /**
* DIY 用户与黑名单过滤(标准分页专用)
* <p>
* 对齐 TS page:284-322 — diyUserId 与 blackUserId 互斥(else if),
* diyUserId=-1 使用 LEFT JOIN 语义查找无绑定的商品。
*/
private void applyDiyAndBlacklistFilter(CustomProductInfoSnakeDTO param, QueryWrapper<CustomProductInfoEntity> queryWrapper) { private void applyDiyAndBlacklistFilter(CustomProductInfoSnakeDTO param, QueryWrapper<CustomProductInfoEntity> queryWrapper) {
List<Integer> idListFromDiyUser = null;
List<Integer> idListFromBlacklist = null;
if (param.getDiyUserId() != null) { if (param.getDiyUserId() != null) {
// diyUserId 过滤
List<Integer> productIds;
if (param.getDiyUserId() == -1) { if (param.getDiyUserId() == -1) {
List<Integer> boundIds = customProductDiyUserRelDomainService.list().stream() // 查找无任何 diy_user 绑定的商品(对齐 TS:287-295 LEFT JOIN WHERE IS NULL)
.map(CustomProductDiyUserRelEntity::getProductId) // 通过 Domain 层 Mapper XML 的 selectIdsWithoutDiyUserBind 执行 LEFT JOIN 查询
.distinct() List<Integer> unboundIds = customProductInfoDomainService.selectIdsWithoutDiyUserBind();
.collect(Collectors.toList()); if (CollectionUtils.isEmpty(unboundIds)) {
if (!boundIds.isEmpty()) { queryWrapper.eq("id", -1); // 无匹配结果
queryWrapper.notIn("id", boundIds); } else {
queryWrapper.in("id", unboundIds);
} }
} else { } else {
idListFromDiyUser = customProductDiyUserRelDomainService.list( productIds = customProductDiyUserRelDomainService.list(
new LambdaQueryWrapper<CustomProductDiyUserRelEntity>() new LambdaQueryWrapper<CustomProductDiyUserRelEntity>()
.eq(CustomProductDiyUserRelEntity::getDiyUserId, param.getDiyUserId())) .eq(CustomProductDiyUserRelEntity::getDiyUserId, param.getDiyUserId()))
.stream() .stream().map(CustomProductDiyUserRelEntity::getProductId)
.map(CustomProductDiyUserRelEntity::getProductId) .distinct().collect(Collectors.toList());
.distinct() if (CollectionUtils.isEmpty(productIds)) {
.collect(Collectors.toList()); queryWrapper.eq("id", -1); // 无匹配结果
if (idListFromDiyUser.isEmpty()) { } else {
queryWrapper.eq("id", -1); queryWrapper.in("id", productIds);
}
} }
} }
} else if (param.getBlackUserId() != null) {
if (param.getBlackUserId() != null) { // blackUserId 过滤(仅在 diyUserId 未设置时生效,对齐 TS else if:311-322)
idListFromBlacklist = customProductBlacklistDomainService.list( List<Integer> productIds = customProductBlacklistDomainService.list(
new LambdaQueryWrapper<CustomProductBlacklistEntity>() new LambdaQueryWrapper<CustomProductBlacklistEntity>()
.eq(CustomProductBlacklistEntity::getDiyUserId, param.getBlackUserId())) .eq(CustomProductBlacklistEntity::getDiyUserId, param.getBlackUserId()))
.stream() .stream().map(CustomProductBlacklistEntity::getProductId)
.map(CustomProductBlacklistEntity::getProductId) .distinct().collect(Collectors.toList());
.distinct() if (productIds.isEmpty()) {
.collect(Collectors.toList()); queryWrapper.eq("id", -1); // 无匹配结果
}
if (idListFromDiyUser != null && idListFromBlacklist != null) {
List<Integer> intersection = idListFromDiyUser.stream()
.filter(idListFromBlacklist::contains)
.collect(Collectors.toList());
if (intersection.isEmpty()) {
queryWrapper.eq("id", -1);
} else { } else {
queryWrapper.in("id", intersection); queryWrapper.in("id", productIds);
} }
} else if (idListFromDiyUser != null) {
queryWrapper.in("id", idListFromDiyUser);
} else if (idListFromBlacklist != null) {
queryWrapper.in("id", idListFromBlacklist);
} }
} }
...@@ -520,7 +545,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -520,7 +545,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
return; return;
} }
// 调用 saas admin API 获取属性定义(含 valueList) // 调用 saas admin API 获取属性定义(含 valueList)
List<BasePropertyModel> publicProperties = saasAdminService.getPropertyByIds(propIds); List<PropertyModel> publicProperties = saasAdminService.getPropertyByIds(propIds);
if (CollectionUtils.isEmpty(publicProperties)) { if (CollectionUtils.isEmpty(publicProperties)) {
return; return;
} }
...@@ -533,11 +558,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -533,11 +558,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
List<CustomProductInfoSkuPropertiesVO> skuProps = new ArrayList<>(); List<CustomProductInfoSkuPropertiesVO> skuProps = new ArrayList<>();
List<CustomProductInfoSkuPropertiesVO> normalProps = new ArrayList<>(); List<CustomProductInfoSkuPropertiesVO> normalProps = new ArrayList<>();
for (BasePropertyModel prop : publicProperties) { for (PropertyModel prop : publicProperties) {
CustomProductInfoSkuPropertiesVO propVO = BeanMapper.snakeCase().convert(prop, CustomProductInfoSkuPropertiesVO.class); CustomProductInfoSkuPropertiesVO propVO = BeanMapper.snakeCase().convert(prop, CustomProductInfoSkuPropertiesVO.class);
if (CollectionUtils.isNotEmpty(prop.getValueList())) { if (CollectionUtils.isNotEmpty(prop.getValueList())) {
// 过滤每个属性的 valueList,只保留当前商品使用的值(对齐 TS:222-233) // 过滤每个属性的 valueList,只保留当前商品使用的值(对齐 TS:222-233)
List<BasePropertyValueModel> filtered = prop.getValueList().stream() List<PropertyValueModel> filtered = prop.getValueList().stream()
.filter(v -> valueIds.contains(v.getId())).toList(); .filter(v -> valueIds.contains(v.getId())).toList();
// 转换为 CustomProductPropertiesValueVO 列表,并赋值给valueList // 转换为 CustomProductPropertiesValueVO 列表,并赋值给valueList
propVO.setValueList(filtered.stream().map(v -> BeanMapper.mapper().convert(v, CustomProductPropertiesValueVO.class)).toList()); propVO.setValueList(filtered.stream().map(v -> BeanMapper.mapper().convert(v, CustomProductPropertiesValueVO.class)).toList());
...@@ -555,33 +580,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -555,33 +580,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
CustomAsserts.nonNull(dto, "绑定参数不能为空"); CustomAsserts.nonNull(dto, "绑定参数不能为空");
CustomAsserts.nonNull(dto.getProductIds(), "商品 ID 列表不能为空"); CustomAsserts.nonNull(dto.getProductIds(), "商品 ID 列表不能为空");
// 1. 校验客户是否存在
String logStr;
if (CollectionUtils.isNotEmpty(dto.getDiyUserIds())) {
List<DbDiyUserEntity> diyUsers = dbDiyUserDomainService.listByIds(dto.getDiyUserIds());
if (CollectionUtils.isEmpty(diyUsers) || diyUsers.size() != dto.getDiyUserIds().size()) {
throw new ServiceException("未查询到所选客户");
}
logStr = "绑定客户改:" + diyUsers.stream().map(DbDiyUserEntity::getName).collect(Collectors.joining(","));
} else {
logStr = "绑定客户改为空";
}
try { try {
transactionTemplate.executeWithoutResult(status -> { transactionTemplate.executeWithoutResult(status -> {
for (Integer productId : dto.getProductIds()) { // 2. 批量删除所有传入 productIds 的现有绑定
// 先删除该商品的所有现有绑定
customProductDiyUserRelDomainService.remove( customProductDiyUserRelDomainService.remove(
new LambdaQueryWrapper<CustomProductDiyUserRelEntity>() new LambdaQueryWrapper<CustomProductDiyUserRelEntity>()
.eq(CustomProductDiyUserRelEntity::getProductId, productId)); .in(CustomProductDiyUserRelEntity::getProductId, dto.getProductIds()));
// 再插入新的绑定 // 3. 批量插入新绑定记录
if (dto.getDiyUserIds() != null && !dto.getDiyUserIds().isEmpty()) { if (CollectionUtils.isNotEmpty(dto.getDiyUserIds())) {
List<CustomProductDiyUserRelEntity> rels = dto.getDiyUserIds().stream() List<CustomProductDiyUserRelEntity> rels = dto.getProductIds().stream()
.map(diyUserId -> { .flatMap(productId -> dto.getDiyUserIds().stream().map(diyUserId -> {
CustomProductDiyUserRelEntity rel = new CustomProductDiyUserRelEntity(); CustomProductDiyUserRelEntity rel = new CustomProductDiyUserRelEntity();
rel.setProductId(productId); rel.setProductId(productId);
rel.setDiyUserId(diyUserId); rel.setDiyUserId(diyUserId);
return rel; return rel;
}) })).collect(Collectors.toList());
.collect(Collectors.toList());
customProductDiyUserRelDomainService.saveBatch(rels); customProductDiyUserRelDomainService.saveBatch(rels);
} }
}
saveLogBatch("绑定客户", dto.getProductIds()); // 4. 记日志
saveLogBatch(logStr, dto.getProductIds());
}); });
} catch (Exception e) { } catch (Exception e) {
log.error("[ bindsDiyUser ] 绑定客户失败, productIds: {}", dto.getProductIds(), e); log.error("[ bindsDiyUser ] 绑定客户失败, productIds: {}", dto.getProductIds(), e);
throw new ServiceException("绑定客户失败: " + e.getMessage()) throw new ServiceException("绑定客户失败: " + e.getMessage());
.setDetailMessage(e.toString());
} }
} }
...@@ -590,33 +625,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -590,33 +625,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
CustomAsserts.nonNull(dto, "黑名单参数不能为空"); CustomAsserts.nonNull(dto, "黑名单参数不能为空");
CustomAsserts.nonNull(dto.getProductIds(), "商品 ID 列表不能为空"); CustomAsserts.nonNull(dto.getProductIds(), "商品 ID 列表不能为空");
// 1. 校验客户是否存在(对齐 TS:563-568)
String logStr;
if (dto.getDiyUserIds() != null && !dto.getDiyUserIds().isEmpty()) {
List<DbDiyUserEntity> diyUsers = dbDiyUserDomainService.listByIds(dto.getDiyUserIds());
if (diyUsers == null || diyUsers.size() != dto.getDiyUserIds().size()) {
throw new ServiceException("未查询到所选客户");
}
logStr = "黑名单客户改:" + diyUsers.stream().map(DbDiyUserEntity::getName).collect(Collectors.joining(","));
} else {
logStr = "黑名单客户改为空";
}
try { try {
transactionTemplate.executeWithoutResult(status -> { transactionTemplate.executeWithoutResult(status -> {
for (Integer productId : dto.getProductIds()) { // 2. 批量删除所有传入 productIds 的黑名单记录(对齐 TS:29 — 单次 DELETE WHERE product_id IN (...))
// 先删除该商品的所有现有黑名单
customProductBlacklistDomainService.remove( customProductBlacklistDomainService.remove(
new LambdaQueryWrapper<CustomProductBlacklistEntity>() new LambdaQueryWrapper<CustomProductBlacklistEntity>()
.eq(CustomProductBlacklistEntity::getProductId, productId)); .in(CustomProductBlacklistEntity::getProductId, dto.getProductIds()));
// 再插入新的黑名单 // 3. 批量插入新黑名单记录(对齐 TS:574)
if (dto.getDiyUserIds() != null && !dto.getDiyUserIds().isEmpty()) { if (dto.getDiyUserIds() != null && !dto.getDiyUserIds().isEmpty()) {
List<CustomProductBlacklistEntity> blacklists = dto.getDiyUserIds().stream() List<CustomProductBlacklistEntity> blacklists = dto.getProductIds().stream()
.map(diyUserId -> { .flatMap(productId -> dto.getDiyUserIds().stream().map(diyUserId -> {
CustomProductBlacklistEntity bl = new CustomProductBlacklistEntity(); CustomProductBlacklistEntity bl = new CustomProductBlacklistEntity();
bl.setProductId(productId); bl.setProductId(productId);
bl.setDiyUserId(diyUserId); bl.setDiyUserId(diyUserId);
return bl; return bl;
}) })).collect(Collectors.toList());
.collect(Collectors.toList());
customProductBlacklistDomainService.saveBatch(blacklists); customProductBlacklistDomainService.saveBatch(blacklists);
} }
}
saveLogBatch("加入黑名单", dto.getProductIds()); // 4. 记日志(对齐 TS:575)
saveLogBatch(logStr, dto.getProductIds());
}); });
} catch (Exception e) { } catch (Exception e) {
log.error("[ addBlackList ] 加入黑名单失败, productIds: {}", dto.getProductIds(), e); log.error("[ addBlackList ] 加入黑名单失败, productIds: {}", dto.getProductIds(), e);
throw new ServiceException("加入黑名单失败: " + e.getMessage()) throw new ServiceException("加入黑名单失败: " + e.getMessage());
.setDetailMessage(e.toString());
} }
} }
...@@ -631,20 +676,31 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -631,20 +676,31 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
.set(CustomProductInfoEntity::getDiySku, diySku)); .set(CustomProductInfoEntity::getDiySku, diySku));
} }
/**
* 获取商品绑定的 DIY 模板列表(对齐 TS:513-526)
* <p>
* 通过 product_template_info 表查询商品关联的所有 diy_id,
* 再批量查询 db_diy 表返回完整模板信息。
* 与 getErpBindsDiyById 不同,此处不做用户权限过滤和状态过滤。
*/
@Override @Override
public List<DbDiyVO> getBindsDiyById(Integer id) { public List<DbDiySnakeVO> getBindsDiyById(Integer id) {
CustomAsserts.nonNull(id, "商品 ID 不能为空"); CustomAsserts.nonNull(id, "商品 ID 不能为空");
// 注:当前 custom-server 中没有 product_template_info 表, // 1. 通过 product_template_info 表查所有关联的 diy_id
// TS 版本通过该表关联 DIY。此处暂时通过默认 DIY ID 返回。 List<ProductTemplateInfoEntity> templates = productTemplateInfoDomainService.selectByProductId(id);
CustomProductInfoEntity entity = customProductInfoDomainService.getById(id); if (CollectionUtils.isEmpty(templates)) {
if (entity == null || entity.getDiyId() == null) {
return Collections.emptyList();
}
DbDiyEntity diy = dbDiyDomainService.getById(entity.getDiyId());
if (diy == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return Collections.singletonList(BeanMapper.mapper().convert(diy, DbDiyVO.class)); // 2. 提取 diy_id 列表
List<Integer> diyIds = templates.stream().map(ProductTemplateInfoEntity::getDiyId)
.filter(Objects::nonNull).distinct().collect(Collectors.toList());
// 3. 查询 db_diy 表
List<DbDiyEntity> diys = dbDiyDomainService.list(
new LambdaQueryWrapper<DbDiyEntity>().in(DbDiyEntity::getId, diyIds));
// 4. 转换为 VO 返回
return diys.stream()
.map(e -> BeanMapper.snakeCase().convert(e, DbDiySnakeVO.class))
.collect(Collectors.toList());
} }
@Override @Override
...@@ -669,23 +725,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -669,23 +725,43 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* 获取商品绑定的工艺列表(对齐 TS:786-788 → getCraftByProductId)
* <p>
* 通过 custom_product_craft_rel 查 craft_id 列表,
* 再批量查询 craft_center 表返回完整工艺实体。
*/
@Override @Override
public List<Long> getCraftById(Integer id) { public List<CraftCenterVO> getCraftById(Integer id) {
CustomAsserts.nonNull(id, "商品 ID 不能为空"); CustomAsserts.nonNull(id, "商品 ID 不能为空");
return customProductCraftRelDomainService.list( // 1. 查询关联表获取 craft_id 列表
List<Long> craftIds = customProductCraftRelDomainService.list(
new LambdaQueryWrapper<CustomProductCraftRelEntity>() new LambdaQueryWrapper<CustomProductCraftRelEntity>()
.eq(CustomProductCraftRelEntity::getProductId, id)) .eq(CustomProductCraftRelEntity::getProductId, id))
.stream() .stream()
.map(CustomProductCraftRelEntity::getCraftId) .map(CustomProductCraftRelEntity::getCraftId)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (craftIds.isEmpty()) {
return Collections.emptyList();
}
// 2. 查询 craft_center 表获取完整工艺实体
List<CraftCenterEntity> crafts = craftCenterDomainService.list(
new LambdaQueryWrapper<CraftCenterEntity>().in(CraftCenterEntity::getId, craftIds));
// 3. 转换为 VO 返回
return crafts.stream()
.map(e -> BeanMapper.mapper().convert(e, CraftCenterVO.class))
.collect(Collectors.toList());
} }
// ==================== ERP 专用接口 ==================== // ==================== ERP 专用接口 ====================
@Override @Override
public List<DbDiyVO> getErpBindsDiyById(Integer id, String userMark, String namespace) { public List<DbDiySnakeVO> getBindsDiyByIdAndUserMark(Integer id, String userMark, String namespace) {
CustomAsserts.nonNull(id, "商品 ID 不能为空"); CustomAsserts.nonNull(id, "商品 ID 不能为空");
// 1. 根据 userMark 或 namespace 查询用户 // 1. 根据 userMark 或 namespace 查询用户
if (StringUtils.isBlank(userMark) && StringUtils.isBlank(namespace)) {
throw new ServiceException("userMark和namespace至少要传一个");
}
DbDiyUserEntity user; DbDiyUserEntity user;
if (StringUtils.isNotBlank(userMark)) { if (StringUtils.isNotBlank(userMark)) {
user = diyUserService.getByUserMark(userMark); user = diyUserService.getByUserMark(userMark);
...@@ -729,11 +805,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -729,11 +805,11 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
// 6. 转换为 VO 并附带效果图 // 6. 转换为 VO 并附带效果图
return diys.stream().map(diy -> { return diys.stream().map(diy -> {
DbDiyVO vo = BeanMapper.mapper().convert(diy, DbDiyVO.class); DbDiySnakeVO vo = BeanMapper.snakeCase().convert(diy, DbDiySnakeVO.class);
List<DbDiyXiaoguotuEntity> xiaoguotus = xiaoguotuMap.getOrDefault(diy.getId(), Collections.emptyList()); List<DbDiyXiaoguotuEntity> xiaoguotus = xiaoguotuMap.getOrDefault(diy.getId(), Collections.emptyList());
if (CollectionUtils.isNotEmpty(xiaoguotus)) { if (CollectionUtils.isNotEmpty(xiaoguotus)) {
vo.setXiaoguotuList(xiaoguotus.stream() vo.setXiaoguotuList(xiaoguotus.stream()
.map(e -> BeanMapper.mapper().convert(e, DbDiyXiaoguotuVO.class)).collect(Collectors.toList())); .map(e -> BeanMapper.snakeCase().convert(e, DbDiyXiaoguotuSnakeVO.class)).collect(Collectors.toList()));
} }
return vo; return vo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
...@@ -743,24 +819,32 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService { ...@@ -743,24 +819,32 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* 检查用户是否在授权名单中(对齐 TS:774-777 FIND_IN_SET) * 检查用户是否在授权名单中(对齐 TS:774-777 FIND_IN_SET)
* <p> * <p>
* user_ids 为 null 或空字符串 = 对所有人开放。 * user_ids 为 null 或空字符串 = 对所有人开放。
* 使用 FIND_IN_SET 语义:逗号分隔值中精确匹配用户 ID。
*/ */
private boolean isUserAuthorized(String userIds, Integer userId) { private boolean isUserAuthorized(String userIds, Integer userId) {
if (StringUtils.isBlank(userIds)) { if (StringUtils.isBlank(userIds)) {
return true; return true;
} }
return Arrays.asList(userIds.split(",")).contains(String.valueOf(userId)); String targetId = String.valueOf(userId);
return Arrays.stream(userIds.split(","))
.map(String::strip)
.anyMatch(s -> s.equals(targetId));
} }
/** /**
* 检查用户是否在黑名单中(对齐 TS:778-781 FIND_IN_SET) * 检查用户是否在黑名单中(对齐 TS:778-781 FIND_IN_SET)
* <p> * <p>
* ban_user_ids 为 null 或空字符串 = 无人被禁止。 * ban_user_ids 为 null 或空字符串 = 无人被禁止。
* 使用 FIND_IN_SET 语义:逗号分隔值中精确匹配用户 ID。
*/ */
private boolean isUserBanned(String banUserIds, Integer userId) { private boolean isUserBanned(String banUserIds, Integer userId) {
if (StringUtils.isBlank(banUserIds)) { if (StringUtils.isBlank(banUserIds)) {
return false; return false;
} }
return Arrays.asList(banUserIds.split(",")).contains(String.valueOf(userId)); String targetId = String.valueOf(userId);
return Arrays.stream(banUserIds.split(","))
.map(String::strip)
.anyMatch(s -> s.equals(targetId));
} }
@Override @Override
......
...@@ -7,7 +7,7 @@ import com.jomalls.custom.app.service.DbDiyService; ...@@ -7,7 +7,7 @@ import com.jomalls.custom.app.service.DbDiyService;
import com.jomalls.custom.app.utils.BeanMapper; import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts; import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.app.vo.DbDiyPageVO; import com.jomalls.custom.app.vo.DbDiyPageVO;
import com.jomalls.custom.app.vo.DbDiyVO; import com.jomalls.custom.app.vo.DbDiySnakeVO;
import com.jomalls.custom.dal.entity.DbDiyEntity; import com.jomalls.custom.dal.entity.DbDiyEntity;
import com.jomalls.custom.domain.service.DbDiyDomainService; import com.jomalls.custom.domain.service.DbDiyDomainService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -37,34 +37,34 @@ public class DbDiyServiceImpl implements DbDiyService { ...@@ -37,34 +37,34 @@ public class DbDiyServiceImpl implements DbDiyService {
} }
@Override @Override
public List<DbDiyVO> list(DbDiyVO dbDiyVO) { public List<DbDiySnakeVO> list(DbDiySnakeVO dbDiySnakeVO) {
QueryWrapper<DbDiyEntity> queryWrapper = new QueryWrapper<>(); QueryWrapper<DbDiyEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参 // TODO 根据业务条件组装入参
List<DbDiyEntity> list = dbDiyDomainService.list(queryWrapper); List<DbDiyEntity> list = dbDiyDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, DbDiyVO.class)).collect(Collectors.toList()); return list.stream().map(e -> BeanMapper.mapper().convert(e, DbDiySnakeVO.class)).collect(Collectors.toList());
} }
@Override @Override
public IPage<DbDiyVO> pageList(DbDiyPageVO dbDiyPageVO) { public IPage<DbDiySnakeVO> pageList(DbDiyPageVO dbDiyPageVO) {
CustomAsserts.nonNull(dbDiyPageVO, "分页查询参数不能为空"); CustomAsserts.nonNull(dbDiyPageVO, "分页查询参数不能为空");
QueryWrapper<DbDiyEntity> queryWrapper = new QueryWrapper<>(); QueryWrapper<DbDiyEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参 // TODO 根据业务条件组装入参
IPage<DbDiyEntity> page = dbDiyDomainService.selectPage(queryWrapper, dbDiyPageVO); IPage<DbDiyEntity> page = dbDiyDomainService.selectPage(queryWrapper, dbDiyPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, DbDiyVO.class)); return page.convert(e -> BeanMapper.mapper().convert(e, DbDiySnakeVO.class));
} }
@Override @Override
public DbDiyVO info(Integer id) { public DbDiySnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空"); CustomAsserts.nonNull(id, "主键id不能为空");
DbDiyEntity dbDiy = dbDiyDomainService.getById(id); DbDiyEntity dbDiy = dbDiyDomainService.getById(id);
return BeanMapper.mapper().convert(dbDiy, DbDiyVO.class); return BeanMapper.mapper().convert(dbDiy, DbDiySnakeVO.class);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void save(DbDiyVO dbDiyVO) { public void save(DbDiySnakeVO dbDiySnakeVO) {
CustomAsserts.nonNull(dbDiyVO, "实体对象不能为空"); CustomAsserts.nonNull(dbDiySnakeVO, "实体对象不能为空");
DbDiyEntity dbDiyEntity = BeanMapper.mapper().convert(dbDiyVO, DbDiyEntity.class); DbDiyEntity dbDiyEntity = BeanMapper.mapper().convert(dbDiySnakeVO, DbDiyEntity.class);
try { try {
dbDiyDomainService.save(dbDiyEntity); dbDiyDomainService.save(dbDiyEntity);
} catch (DuplicateKeyException e) { } catch (DuplicateKeyException e) {
...@@ -75,9 +75,9 @@ public class DbDiyServiceImpl implements DbDiyService { ...@@ -75,9 +75,9 @@ public class DbDiyServiceImpl implements DbDiyService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void updateById(DbDiyVO dbDiyVO) { public void updateById(DbDiySnakeVO dbDiySnakeVO) {
CustomAsserts.nonNull(dbDiyVO, "实体对象不能为空"); CustomAsserts.nonNull(dbDiySnakeVO, "实体对象不能为空");
DbDiyEntity dbDiy = BeanMapper.mapper().convert(dbDiyVO, DbDiyEntity.class); DbDiyEntity dbDiy = BeanMapper.mapper().convert(dbDiySnakeVO, DbDiyEntity.class);
try { try {
dbDiyDomainService.updateById(dbDiy); dbDiyDomainService.updateById(dbDiy);
} catch (DuplicateKeyException e) { } catch (DuplicateKeyException e) {
......
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.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.jomalls.custom.app.vo.LogCustomProductSnakeVO;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.vo.LogCustomProductPageVO;
import com.jomalls.custom.app.vo.LogCustomProductVO;
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;
import com.jomalls.custom.app.utils.CustomAsserts; import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.LogCustomProductEntity; import com.jomalls.custom.dal.entity.LogCustomProductEntity;
import com.jomalls.custom.domain.service.LogCustomProductDomainService; import com.jomalls.custom.domain.service.LogCustomProductDomainService;
import lombok.extern.slf4j.Slf4j; 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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -31,66 +25,20 @@ public class LogCustomProductServiceImpl implements LogCustomProductService { ...@@ -31,66 +25,20 @@ public class LogCustomProductServiceImpl implements LogCustomProductService {
private final LogCustomProductDomainService logCustomProductDomainService; private final LogCustomProductDomainService logCustomProductDomainService;
@Autowired
public LogCustomProductServiceImpl(LogCustomProductDomainService logCustomProductDomainService) { public LogCustomProductServiceImpl(LogCustomProductDomainService logCustomProductDomainService) {
this.logCustomProductDomainService = logCustomProductDomainService; this.logCustomProductDomainService = logCustomProductDomainService;
} }
@Override @Override
public List<LogCustomProductVO> list(LogCustomProductVO logCustomProductVO) { public List<LogCustomProductSnakeVO> getListByProductId(Integer productId) {
QueryWrapper<LogCustomProductEntity> queryWrapper = new QueryWrapper<>(); CustomAsserts.nonNull(productId, "商品 ID 不能为空");
// TODO 根据业务条件组装入参 // 按 product_id 查询所有日志,按 id 降序排列
List<LogCustomProductEntity> list = logCustomProductDomainService.list(queryWrapper); List<LogCustomProductEntity> logs = logCustomProductDomainService.list(
return list.stream().map(e -> BeanMapper.mapper().convert(e, LogCustomProductVO.class)).collect(Collectors.toList()); new QueryWrapper<LogCustomProductEntity>()
.eq("product_id", productId)
.orderByDesc("id"));
return logs.stream()
.map(e -> BeanMapper.snakeCase().convert(e, LogCustomProductSnakeVO.class))
.collect(Collectors.toList());
} }
@Override
public IPage<LogCustomProductVO> pageList(LogCustomProductPageVO logCustomProductPageVO) {
CustomAsserts.nonNull(logCustomProductPageVO, "分页查询参数不能为空");
QueryWrapper<LogCustomProductEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<LogCustomProductEntity> page = logCustomProductDomainService.selectPage(queryWrapper, logCustomProductPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, LogCustomProductVO.class));
}
@Override
public LogCustomProductVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
LogCustomProductEntity logCustomProduct = logCustomProductDomainService.getById(id);
return BeanMapper.mapper().convert(logCustomProduct, LogCustomProductVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(LogCustomProductVO logCustomProductVO) {
CustomAsserts.nonNull(logCustomProductVO, "实体对象不能为空");
LogCustomProductEntity logCustomProductEntity = BeanMapper.mapper().convert(logCustomProductVO, LogCustomProductEntity.class);
try {
logCustomProductDomainService.save(logCustomProductEntity);
} catch (DuplicateKeyException e) {
log.info("[ LogCustomProductServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(LogCustomProductVO logCustomProductVO) {
CustomAsserts.nonNull(logCustomProductVO, "实体对象不能为空");
LogCustomProductEntity logCustomProduct = BeanMapper.mapper().convert(logCustomProductVO, LogCustomProductEntity.class);
try {
logCustomProductDomainService.updateById(logCustomProduct);
} catch (DuplicateKeyException e) {
log.info("[ LogCustomProductServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
logCustomProductDomainService.removeById(id);
}
} }
package com.jomalls.custom.app.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 工艺中心 VO
* <p>
* 对齐 TS 项目 {@code CraftCenter} 实体字段。
*
* @author Lizh
* @date 2026-06-11
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工艺中心")
public class CraftCenterVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "工艺编号")
private Long id;
@Schema(description = "工艺名称")
private String craftName;
@Schema(description = "工艺英文名称")
private String craftEnName;
@Schema(description = "工艺类型")
private String craftType;
@Schema(description = "工艺编码")
private String craftCode;
@Schema(description = "币种")
private String currencyCode;
@Schema(description = "工艺成本")
private String craftCost;
@Schema(description = "其他面的价格")
private String otherSideCost;
@Schema(description = "是否启用")
private Boolean craftEnable;
@Schema(description = "是否在ERP显示")
private Boolean erpDisplay;
@Schema(description = "国家代码")
private String countryCode;
@Schema(description = "创建时间")
private Date createTime;
@Schema(description = "修改时间")
private Date updateTime;
}
package com.jomalls.custom.app.vo; package com.jomalls.custom.app.vo;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.core.util.Json; import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
...@@ -22,7 +21,7 @@ import java.util.List; ...@@ -22,7 +21,7 @@ import java.util.List;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Schema(description = "VO") @Schema(description = "VO")
public class DbDiyVO implements Serializable { public class DbDiySnakeVO implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -48,7 +47,7 @@ public class DbDiyVO implements Serializable { ...@@ -48,7 +47,7 @@ public class DbDiyVO implements Serializable {
* 英文名称 * 英文名称
*/ */
@Schema(description = "英文名称") @Schema(description = "英文名称")
private String enName; private String en_name;
/** /**
* 排序 * 排序
...@@ -60,13 +59,13 @@ public class DbDiyVO implements Serializable { ...@@ -60,13 +59,13 @@ public class DbDiyVO implements Serializable {
* diy主图 * diy主图
*/ */
@Schema(description = "diy主图") @Schema(description = "diy主图")
private String imgUrl; private String img_url;
/** /**
* 图片集合,逗号分割 * 图片集合,逗号分割
*/ */
@Schema(description = "图片集合,逗号分割") @Schema(description = "图片集合,逗号分割")
private String imgArr; private String img_arr;
/** /**
* 编码 * 编码
...@@ -90,13 +89,13 @@ public class DbDiyVO implements Serializable { ...@@ -90,13 +89,13 @@ public class DbDiyVO implements Serializable {
* 1 svgToJpg 2 svgToSvg 3 svgToTiff 4 svgToPng 4 5 psdToJpg * 1 svgToJpg 2 svgToSvg 3 svgToTiff 4 svgToPng 4 5 psdToJpg
*/ */
@Schema(description = "1 svgToJpg 2 svgToSvg 3 svgToTiff 4 svgToPng 4 5 psdToJpg") @Schema(description = "1 svgToJpg 2 svgToSvg 3 svgToTiff 4 svgToPng 4 5 psdToJpg")
private Integer scImgType; private Integer sc_img_type;
/** /**
* 是否立即生成尺码 0 不生成 1 立即生成全部尺码 * 是否立即生成尺码 0 不生成 1 立即生成全部尺码
*/ */
@Schema(description = "是否立即生成尺码 0 不生成 1 立即生成全部尺码") @Schema(description = "是否立即生成尺码 0 不生成 1 立即生成全部尺码")
private Integer chimaNowRender; private Integer chima_now_render;
/** /**
* 状态 1 服务器渲染 2 前台渲染 * 状态 1 服务器渲染 2 前台渲染
...@@ -108,25 +107,37 @@ public class DbDiyVO implements Serializable { ...@@ -108,25 +107,37 @@ public class DbDiyVO implements Serializable {
* DbDiy 父级值 可以用于绑定 * DbDiy 父级值 可以用于绑定
*/ */
@Schema(description = "DbDiy 父级值 可以用于绑定") @Schema(description = "DbDiy 父级值 可以用于绑定")
private Integer parentId; private Integer parent_id;
/**
* 默认值 选择的产品
*/
@Schema(description = "默认值 选择的产品")
private Integer default_diy_id;
/** /**
* 存放的user ids * 存放的user ids
*/ */
@Schema(description = "存放的user ids") @Schema(description = "存放的user ids")
private String userIds; private String user_ids;
/** /**
* 不允许查看的用户 * 不允许查看的用户
*/ */
@Schema(description = "不允许查看的用户") @Schema(description = "不允许查看的用户")
private String banUserIds; private String ban_user_ids;
/** /**
* diy分类ID * diy分类ID
*/ */
@Schema(description = "diy分类ID") @Schema(description = "diy分类ID")
private Integer typeId; private Integer type_id;
/**
* 工厂/供应商id
*/
@Schema(description = "工厂/供应商id")
private Integer factory_id;
/** /**
* 状态 0 已下架 1 已上架 20 待上架 40 建模完成 50 多变体完善 60 产前测试 70 建模中 75 待确认 80 待分派 85 打板中 90 待审核 9 软删除 * 状态 0 已下架 1 已上架 20 待上架 40 建模完成 50 多变体完善 60 产前测试 70 建模中 75 待确认 80 待分派 85 打板中 90 待审核 9 软删除
...@@ -138,25 +149,7 @@ public class DbDiyVO implements Serializable { ...@@ -138,25 +149,7 @@ public class DbDiyVO implements Serializable {
* *
*/ */
@Schema(description = "") @Schema(description = "")
private Date createDate; private Date create_date;
/**
* 默认值 选择的产品
*/
@Schema(description = "默认值 选择的产品")
private Integer defaultDiyId;
/**
* 工厂/供应商id
*/
@Schema(description = "工厂/供应商id")
private Integer factoryId;
/**
* 印花类型 0满印 1局部印
*/
@Schema(description = "印花类型 0满印 1局部印")
private Integer printType;
/** /**
* 材质 * 材质
...@@ -165,28 +158,10 @@ public class DbDiyVO implements Serializable { ...@@ -165,28 +158,10 @@ public class DbDiyVO implements Serializable {
private String material; private String material;
/** /**
* 工艺id
*/
@Schema(description = "工艺id")
private Long craftId;
/**
* 最低价格
*/
@Schema(description = "最低价格")
private BigDecimal minPrice;
/**
* 最高价格
*/
@Schema(description = "最高价格")
private BigDecimal maxPrice;
/**
* 图片是否创建缩略图 1已创建 0未创建(临时字段) * 图片是否创建缩略图 1已创建 0未创建(临时字段)
*/ */
@Schema(description = "图片是否创建缩略图 1已创建 0未创建(临时字段)") @Schema(description = "图片是否创建缩略图 1已创建 0未创建(临时字段)")
private Boolean pictureStatus; private Boolean picture_status;
/** /**
* 备注信息 * 备注信息
...@@ -204,49 +179,49 @@ public class DbDiyVO implements Serializable { ...@@ -204,49 +179,49 @@ public class DbDiyVO implements Serializable {
* 审核人id * 审核人id
*/ */
@Schema(description = "审核人id") @Schema(description = "审核人id")
private Integer auditId; private Integer audit_id;
/** /**
* 审核人名称 * 审核人名称
*/ */
@Schema(description = "审核人名称") @Schema(description = "审核人名称")
private String auditName; private String audit_name;
/** /**
* 审核时间 * 审核时间
*/ */
@Schema(description = "审核时间") @Schema(description = "审核时间")
private Date auditDate; private Date audit_date;
/** /**
* 上架时间 * 上架时间
*/ */
@Schema(description = "上架时间") @Schema(description = "上架时间")
private Date shelfDate; private Date shelf_date;
/** /**
* 关联信息模板ID * 关联信息模板ID
*/ */
@Schema(description = "关联信息模板ID") @Schema(description = "关联信息模板ID")
private Integer templateId; private Integer template_id;
/** /**
* 关联信息模板类别ID * 关联信息模板类别ID
*/ */
@Schema(description = "关联信息模板类别ID") @Schema(description = "关联信息模板类别ID")
private Integer categoryId; private Integer category_id;
/** /**
* 分派人ID * 分派人ID
*/ */
@Schema(description = "分派人ID") @Schema(description = "分派人ID")
private Integer allocationId; private Integer allocation_id;
/** /**
* 分派人名称 * 分派人名称
*/ */
@Schema(description = "分派人名称") @Schema(description = "分派人名称")
private String allocationName; private String allocation_name;
/** /**
* 是否加急处理 0否 1是 * 是否加急处理 0否 1是
...@@ -258,19 +233,31 @@ public class DbDiyVO implements Serializable { ...@@ -258,19 +233,31 @@ public class DbDiyVO implements Serializable {
* 绑定模型id集合 * 绑定模型id集合
*/ */
@Schema(description = "绑定模型id集合") @Schema(description = "绑定模型id集合")
private String bindDiyIds; private String bind_diy_ids;
/** /**
* 是否被绑定 * 是否被绑定
*/ */
@Schema(description = "是否被绑定") @Schema(description = "是否被绑定")
private Boolean isBind; private Boolean is_bind;
/**
* 模备注
*/
@Schema(description = "模备注")
private String diy_remark;
/**
* 是否新版模
*/
@Schema(description = "是否新版模")
private Boolean new_standard;
/** /**
* 是否由美国生产 默认为false * 是否由美国生产 默认为false
*/ */
@Schema(description = "是否由美国生产 默认为false") @Schema(description = "是否由美国生产 默认为false")
private Boolean usaMade; private Boolean usa_made;
/** /**
* 厂商 * 厂商
...@@ -282,7 +269,13 @@ public class DbDiyVO implements Serializable { ...@@ -282,7 +269,13 @@ public class DbDiyVO implements Serializable {
* 款号 * 款号
*/ */
@Schema(description = "款号") @Schema(description = "款号")
private String styleNum; private String style_num;
/**
* 印花类型 0满印 1局部印
*/
@Schema(description = "印花类型 0满印 1局部印")
private Integer printType;
/** /**
* 模类型 0公模 1私模 * 模类型 0公模 1私模
...@@ -294,34 +287,39 @@ public class DbDiyVO implements Serializable { ...@@ -294,34 +287,39 @@ public class DbDiyVO implements Serializable {
* 生产终端 * 生产终端
*/ */
@Schema(description = "生产终端") @Schema(description = "生产终端")
private String productionClient; private String production_client;
/** /**
* erp的颜色尺码 * erp的颜色尺码
*/ */
@Schema(description = "erp的颜色尺码") @Schema(description = "erp的颜色尺码")
private Json erpSkuProperties; private Json erp_sku_properties;
/** /**
* 推送需求的人 * 推送需求的人
*/ */
@Schema(description = "推送需求的人") @Schema(description = "推送需求的人")
private String pushUser; private String push_user;
/** /**
* 是否新版模 * 最低价格
*/ */
@Schema(description = "是否新版模") @Schema(description = "最低价格")
private Boolean newStandard; private BigDecimal min_price;
/** /**
* 模备注 * 最高价格
*/ */
@Schema(description = "模备注") @Schema(description = "最高价格")
private String diyRemark; private BigDecimal max_price;
@Schema(description = "效果图列表") /**
private List<DbDiyXiaoguotuVO> xiaoguotuList; * 工艺id
*/
@Schema(description = "工艺id")
private Long craft_id;
@Schema(description = "效果图列表")
private List<DbDiyXiaoguotuSnakeVO> xiaoguotuList;
} }
...@@ -20,7 +20,7 @@ import java.io.Serializable; ...@@ -20,7 +20,7 @@ import java.io.Serializable;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Schema(description = "DIY 效果图") @Schema(description = "DIY 效果图")
public class DbDiyXiaoguotuVO implements Serializable { public class DbDiyXiaoguotuSnakeVO implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -35,13 +35,13 @@ public class DbDiyXiaoguotuVO implements Serializable { ...@@ -35,13 +35,13 @@ public class DbDiyXiaoguotuVO implements Serializable {
private Integer idx; private Integer idx;
@Schema(description = "效果图主图") @Schema(description = "效果图主图")
private String imgUrl; private String img_url;
@Schema(description = "PSD 链接") @Schema(description = "PSD 链接")
private String psdUrl; private String psd_url;
@Schema(description = "颜色 ID") @Schema(description = "颜色 ID")
private Integer colorId; private Integer color_id;
@Schema(description = "宽度") @Schema(description = "宽度")
private Float width; private Float width;
...@@ -53,7 +53,7 @@ public class DbDiyXiaoguotuVO implements Serializable { ...@@ -53,7 +53,7 @@ public class DbDiyXiaoguotuVO implements Serializable {
private Integer dpi; private Integer dpi;
@Schema(description = "关联的 DIY 模板 ID") @Schema(description = "关联的 DIY 模板 ID")
private Integer diyId; private Integer diy_id;
@Schema(description = "状态:1 正常 0 禁用") @Schema(description = "状态:1 正常 0 禁用")
private Integer status; private Integer status;
......
...@@ -21,7 +21,7 @@ import java.util.Date; ...@@ -21,7 +21,7 @@ import java.util.Date;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Schema(description = "VO") @Schema(description = "VO")
public class LogCustomProductVO implements Serializable { public class LogCustomProductSnakeVO implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -35,19 +35,19 @@ public class LogCustomProductVO implements Serializable { ...@@ -35,19 +35,19 @@ public class LogCustomProductVO implements Serializable {
* 商品id(custom_product_info表id) * 商品id(custom_product_info表id)
*/ */
@Schema(description = "商品id(custom_product_info表id)") @Schema(description = "商品id(custom_product_info表id)")
private Integer productId; private Integer product_id;
/** /**
* 操作人id * 操作人id
*/ */
@Schema(description = "操作人id") @Schema(description = "操作人id")
private Integer employeeId; private Integer employee_id;
/** /**
* 操作人账号 * 操作人账号
*/ */
@Schema(description = "操作人账号") @Schema(description = "操作人账号")
private String employeeAccount; private String employee_account;
/** /**
* 操作描述 * 操作描述
...@@ -59,7 +59,7 @@ public class LogCustomProductVO implements Serializable { ...@@ -59,7 +59,7 @@ public class LogCustomProductVO implements Serializable {
* 创建时间 * 创建时间
*/ */
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Date createTime; private Date create_time;
} }
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 工艺中心实体
* <p>
* 对齐 TS 项目 {@code CraftCenter} 实体(craft_center 表)。
*
* @author Lizh
* @date 2026-06-11
*/
@Data
@TableName("craft_center")
public class CraftCenterEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 工艺编号 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 工艺名称 */
@TableField("craft_name")
private String craftName;
/** 工艺英文名称 */
@TableField("craft_en_name")
private String craftEnName;
/** 工艺类型 */
@TableField("craft_type")
private String craftType;
/** 工艺编码 */
@TableField("craft_code")
private String craftCode;
/** 币种 */
@TableField("currency_code")
private String currencyCode;
/** 工艺成本 */
@TableField("craft_cost")
private String craftCost;
/** 其他面的价格 */
@TableField("other_side_cost")
private String otherSideCost;
/** 是否启用(1启用,0未启用) */
@TableField("craft_enable")
private Boolean craftEnable;
/** 是否在ERP显示 */
@TableField("erp_display")
private Boolean erpDisplay;
/** 国家代码 */
@TableField("country_code")
private String countryCode;
/** 创建时间 */
@TableField("create_time")
private Date createTime;
/** 修改时间 */
@TableField("update_time")
private Date updateTime;
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.CraftCenterEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 工艺中心 Mapper
*
* @author Lizh
* @date 2026-06-11
*/
@Mapper
public interface CraftCenterMapper extends BaseMapper<CraftCenterEntity> {
}
...@@ -35,4 +35,15 @@ public interface CustomProductInfoMapper extends BaseMapper<CustomProductInfoEnt ...@@ -35,4 +35,15 @@ public interface CustomProductInfoMapper extends BaseMapper<CustomProductInfoEnt
* @return 符合条件的商品 ID 列表(已去重) * @return 符合条件的商品 ID 列表(已去重)
*/ */
List<Integer> selectIdsByErpPermission(@Param("userId") Integer userId); List<Integer> selectIdsByErpPermission(@Param("userId") Integer userId);
/**
* 查询无任何 diy_user 绑定的商品 ID 列表
* <p>
* 对齐 TS page diyUserId=-1 时的原生 SQL(TS:287-295)。
* 使用 LEFT JOIN + WHERE IS NULL 语义:
* 找到所有在 custom_product_diy_user_rel 表中无关联记录的商品。
*
* @return 无绑定的商品 ID 列表(已去重)
*/
List<Integer> selectIdsWithoutDiyUserBind();
} }
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.CraftCenterEntity;
import com.jomalls.custom.service.IBaseService;
/**
* 工艺中心 Domain Service 接口
*
* @author Lizh
* @date 2026-06-11
*/
public interface CraftCenterDomainService extends IBaseService<CraftCenterEntity> {
}
...@@ -28,5 +28,14 @@ public interface CustomProductInfoDomainService extends IBaseService<CustomProdu ...@@ -28,5 +28,14 @@ public interface CustomProductInfoDomainService extends IBaseService<CustomProdu
* @return 符合条件的商品 ID 列表(已去重) * @return 符合条件的商品 ID 列表(已去重)
*/ */
List<Integer> selectIdsByErpPermission(Integer userId); List<Integer> selectIdsByErpPermission(Integer userId);
/**
* 查询无任何 diy_user 绑定的商品 ID 列表
* <p>
* LEFT JOIN + WHERE IS NULL,对齐 TS page diyUserId=-1 逻辑。
*
* @return 无绑定的商品 ID 列表(已去重)
*/
List<Integer> selectIdsWithoutDiyUserBind();
} }
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.CraftCenterMapper;
import com.jomalls.custom.dal.entity.CraftCenterEntity;
import com.jomalls.custom.domain.service.CraftCenterDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 工艺中心 Domain Service 实现
*
* @author Lizh
* @date 2026-06-11
*/
@Service
public class CraftCenterDomainServiceImpl
extends BaseServiceImpl<CraftCenterMapper, CraftCenterEntity>
implements CraftCenterDomainService {
@Autowired
public CraftCenterDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
}
...@@ -35,4 +35,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr ...@@ -35,4 +35,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr
public List<Integer> selectIdsByErpPermission(Integer userId) { public List<Integer> selectIdsByErpPermission(Integer userId) {
return baseMapper.selectIdsByErpPermission(userId); return baseMapper.selectIdsByErpPermission(userId);
} }
@Override
public List<Integer> selectIdsWithoutDiyUserBind() {
return baseMapper.selectIdsWithoutDiyUserBind();
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.CraftCenterMapper">
<resultMap type="com.jomalls.custom.dal.entity.CraftCenterEntity" id="craftCenterMap">
<result property="id" column="id"/>
<result property="craftName" column="craft_name"/>
<result property="craftEnName" column="craft_en_name"/>
<result property="craftType" column="craft_type"/>
<result property="craftCode" column="craft_code"/>
<result property="currencyCode" column="currency_code"/>
<result property="craftCost" column="craft_cost"/>
<result property="otherSideCost" column="other_side_cost"/>
<result property="craftEnable" column="craft_enable"/>
<result property="erpDisplay" column="erp_display"/>
<result property="countryCode" column="country_code"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="tableColumns">
id,
craft_name,
craft_en_name,
craft_type,
craft_code,
currency_code,
craft_cost,
other_side_cost,
craft_enable,
erp_display,
country_code,
create_time,
update_time
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO craft_center (craft_name, craft_en_name, craft_type, craft_code, currency_code, craft_cost, other_side_cost, craft_enable, erp_display, country_code, create_time, update_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.craftName}, #{item.craftEnName}, #{item.craftType}, #{item.craftCode}, #{item.currencyCode}, #{item.craftCost}, #{item.otherSideCost}, #{item.craftEnable}, #{item.erpDisplay}, #{item.countryCode}, #{item.createTime}, #{item.updateTime})
</foreach>
</insert>
</mapper>
...@@ -105,6 +105,17 @@ ...@@ -105,6 +105,17 @@
AND (rel.diy_user_id = #{userId} OR rel.diy_user_id IS NULL) AND (rel.diy_user_id = #{userId} OR rel.diy_user_id IS NULL)
</select> </select>
<!-- 查询无任何 diy_user 绑定的商品 ID 列表 -->
<!-- 对齐 TS page 中的原生 SQL(TS:287-295)
LEFT JOIN + WHERE IS NULL 语义:
找到所有 custom_product_diy_user_rel 表中无关联记录的商品 -->
<select id="selectIdsWithoutDiyUserBind" resultType="java.lang.Integer">
SELECT DISTINCT info.id
FROM custom_product_info info
LEFT JOIN custom_product_diy_user_rel rel ON rel.product_id = info.id
WHERE rel.diy_user_id IS NULL
</select>
<!-- 批量插入 --> <!-- 批量插入 -->
<insert id="insertBatchSomeColumn"> <insert id="insertBatchSomeColumn">
INSERT INTO custom_product_info (sku, title, name, img_url, category_id, weight, purchasing_min, factory_price, sales_price, sales_price_max, status, property1_cate_id, property2_cate_id, property3_cate_id, property1_enname, property2_enname, property3_enname, color_images, material, print_type, product_no, origin_code, origin_name_cn, origin_name_en, currency_code, currency_name, product_type, factory_id, factory_code, processing, create_time, update_time, sort, diy_id, diy_sku) VALUES INSERT INTO custom_product_info (sku, title, name, img_url, category_id, weight, purchasing_min, factory_price, sales_price, sales_price_max, status, property1_cate_id, property2_cate_id, property3_cate_id, property1_enname, property2_enname, property3_enname, color_images, material, print_type, product_no, origin_code, origin_name_cn, origin_name_en, currency_code, currency_name, product_type, factory_id, factory_code, processing, create_time, update_time, sort, diy_id, diy_sku) VALUES
......
package com.jomalls.custom.integrate.model; package com.jomalls.custom.integrate.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
...@@ -20,7 +21,7 @@ import java.util.Date; ...@@ -20,7 +21,7 @@ import java.util.Date;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Schema(description = "商品分类") @Schema(description = "商品分类")
public class BaseCategoryInfoModel implements Serializable { public class CategoryInfoModel implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -53,6 +54,9 @@ public class BaseCategoryInfoModel implements Serializable { ...@@ -53,6 +54,9 @@ public class BaseCategoryInfoModel implements Serializable {
private Boolean leaf; private Boolean leaf;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
private Boolean publicData;
} }
...@@ -16,7 +16,7 @@ import java.util.List; ...@@ -16,7 +16,7 @@ import java.util.List;
* @date 2026-06-08 * @date 2026-06-08
*/ */
@Data @Data
public class BasePropertyModel implements Serializable { public class PropertyModel implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
...@@ -47,7 +47,7 @@ public class BasePropertyModel implements Serializable { ...@@ -47,7 +47,7 @@ public class BasePropertyModel implements Serializable {
/** 属性值列表 */ /** 属性值列表 */
@JsonProperty("valueList") @JsonProperty("valueList")
private List<BasePropertyValueModel> valueList; private List<PropertyValueModel> valueList;
/** 是否公共数据 */ /** 是否公共数据 */
private Boolean publicData; private Boolean publicData;
......
...@@ -12,7 +12,7 @@ import java.io.Serializable; ...@@ -12,7 +12,7 @@ import java.io.Serializable;
* @date 2026-06-08 * @date 2026-06-08
*/ */
@Data @Data
public class BasePropertyValueModel implements Serializable { public class PropertyValueModel implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
......
...@@ -2,8 +2,8 @@ package com.jomalls.custom.integrate.service; ...@@ -2,8 +2,8 @@ package com.jomalls.custom.integrate.service;
import com.jomalls.custom.enums.CodeEnum; import com.jomalls.custom.enums.CodeEnum;
import com.jomalls.custom.integrate.client.RemoteApiClient; import com.jomalls.custom.integrate.client.RemoteApiClient;
import com.jomalls.custom.integrate.model.BaseCategoryInfoModel; import com.jomalls.custom.integrate.model.CategoryInfoModel;
import com.jomalls.custom.integrate.model.BasePropertyModel; import com.jomalls.custom.integrate.model.PropertyModel;
import com.jomalls.custom.integrate.model.SaasAdminApiResponseModel; import com.jomalls.custom.integrate.model.SaasAdminApiResponseModel;
import com.jomalls.custom.security.LoginUser; import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils; import com.jomalls.custom.security.SecurityUtils;
...@@ -67,27 +67,27 @@ public class SaasAdminService { ...@@ -67,27 +67,27 @@ public class SaasAdminService {
* @param ids 属性 ID,逗号分隔(如 "1,2,3") * @param ids 属性 ID,逗号分隔(如 "1,2,3")
* @return 属性列表,包含 valueList 和 skuProperty 等字段 * @return 属性列表,包含 valueList 和 skuProperty 等字段
*/ */
public List<BasePropertyModel> getPropertyByIds(String ids) { public List<PropertyModel> getPropertyByIds(String ids) {
if (!StringUtils.hasText(ids)) { if (!StringUtils.hasText(ids)) {
return Collections.emptyList(); return Collections.emptyList();
} }
try { try {
String url = adminBaseUrl + GET_PROPERTY_BY_IDS_URL + "?ids=" + ids; String url = adminBaseUrl + GET_PROPERTY_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<SaasAdminApiResponseModel<List<BasePropertyModel>>> response = remoteApiClient.get( ResponseEntity<SaasAdminApiResponseModel<List<PropertyModel>>> response = remoteApiClient.get(
url, url,
new ParameterizedTypeReference<>() {}, new ParameterizedTypeReference<>() {},
getHeader()); getHeader());
if (response != null && response.getBody() != null) { if (response != null && response.getBody() != null) {
log.debug("[ BasePropertyService ] getByIds 成功, ids={}, 返回 {} 条", ids, response.toString()); log.debug("[ SaasAdminService ] getByIds 成功, ids={}, 返回: {}", ids, response.toString());
SaasAdminApiResponseModel<List<BasePropertyModel>> responseBody = response.getBody(); SaasAdminApiResponseModel<List<PropertyModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) { if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData(); return responseBody.getData();
} }
} }
log.warn("[ BasePropertyService ] getByIds 返回空, ids={}", ids); log.warn("[ SaasAdminService ] getByIds 返回空, ids={}", ids);
return Collections.emptyList(); return Collections.emptyList();
} catch (Exception e) { } catch (Exception e) {
log.error("[ BasePropertyService ] getByIds 调用失败, ids={}", ids, e); log.error("[ SaasAdminService ] getByIds 调用失败, ids={}", ids, e);
return Collections.emptyList(); return Collections.emptyList();
} }
} }
...@@ -96,9 +96,9 @@ public class SaasAdminService { ...@@ -96,9 +96,9 @@ public class SaasAdminService {
* <p> * <p>
* 对齐 TS {@code getTree()} * 对齐 TS {@code getTree()}
*/ */
public List<BaseCategoryInfoModel> getTree() { public List<CategoryInfoModel> getTree() {
try { try {
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get( ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL, adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {}, new ParameterizedTypeReference<>() {},
getHeader()); getHeader());
...@@ -106,7 +106,7 @@ public class SaasAdminService { ...@@ -106,7 +106,7 @@ public class SaasAdminService {
return response.getBody(); return response.getBody();
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getTree 调用失败", e); log.error("[ SaasAdminService ] getTree 调用失败", e);
} }
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -116,13 +116,13 @@ public class SaasAdminService { ...@@ -116,13 +116,13 @@ public class SaasAdminService {
* <p> * <p>
* 对齐 TS {@code getByIds(ids)} * 对齐 TS {@code getByIds(ids)}
*/ */
public List<BaseCategoryInfoModel> getByIds(String ids) { public List<CategoryInfoModel> getByIds(String ids) {
if (ids == null || ids.isEmpty()) { if (ids == null || ids.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
try { try {
String url = adminBaseUrl + GET_BY_IDS_URL + "?ids=" + ids; String url = adminBaseUrl + GET_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get( ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
url, url,
new ParameterizedTypeReference<>() {}, new ParameterizedTypeReference<>() {},
getHeader()); getHeader());
...@@ -130,7 +130,7 @@ public class SaasAdminService { ...@@ -130,7 +130,7 @@ public class SaasAdminService {
return response.getBody(); return response.getBody();
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getByIds 调用失败, ids={}", ids, e); log.error("[ SaasAdminService ] getByIds 调用失败, ids={}", ids, e);
} }
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -140,9 +140,9 @@ public class SaasAdminService { ...@@ -140,9 +140,9 @@ public class SaasAdminService {
* <p> * <p>
* 对齐 TS {@code treeList()} * 对齐 TS {@code treeList()}
*/ */
public List<BaseCategoryInfoModel> treeList() { public List<CategoryInfoModel> treeList() {
try { try {
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get( ResponseEntity<List<CategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL, adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {}, new ParameterizedTypeReference<>() {},
getHeader()); getHeader());
...@@ -150,7 +150,7 @@ public class SaasAdminService { ...@@ -150,7 +150,7 @@ public class SaasAdminService {
return response.getBody(); return response.getBody();
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ BaseCategoryInfoService ] treeList 调用失败", e); log.error("[ SaasAdminService ] treeList 调用失败", e);
} }
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -160,19 +160,19 @@ public class SaasAdminService { ...@@ -160,19 +160,19 @@ public class SaasAdminService {
* <p> * <p>
* 对齐 TS {@code getById(id)} * 对齐 TS {@code getById(id)}
*/ */
public BaseCategoryInfoModel getById(Integer id) { public CategoryInfoModel getById(Integer id) {
if (id == null) { if (id == null) {
return null; return null;
} }
try { try {
String url = adminBaseUrl + GET_BY_ID_URL + "?id=" + id; String url = adminBaseUrl + GET_BY_ID_URL + "?id=" + id;
ResponseEntity<BaseCategoryInfoModel> response = remoteApiClient.get( ResponseEntity<CategoryInfoModel> response = remoteApiClient.get(
url, BaseCategoryInfoModel.class, null); url, CategoryInfoModel.class, null);
if (response != null) { if (response != null) {
return response.getBody(); return response.getBody();
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getById 调用失败, id={}", id, e); log.error("[ SaasAdminService ] getById 调用失败, id={}", id, e);
} }
return null; return null;
} }
...@@ -182,17 +182,21 @@ public class SaasAdminService { ...@@ -182,17 +182,21 @@ public class SaasAdminService {
* <p> * <p>
* 对齐 TS {@code allList()} * 对齐 TS {@code allList()}
*/ */
public List<BaseCategoryInfoModel> getAllList() { public List<CategoryInfoModel> getAllList() {
try { try {
ResponseEntity<List<BaseCategoryInfoModel>> 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) {
return response.getBody(); log.debug("[ SaasAdminService ] getAllList 成功, 返回: {}", response.toString());
SaasAdminApiResponseModel<List<CategoryInfoModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData();
}
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getAllList 调用失败", e); log.error("[ SaasAdminService ] getAllList 调用失败", e);
} }
return Collections.emptyList(); return Collections.emptyList();
} }
......
...@@ -59,8 +59,8 @@ public class SecurityInterceptor implements HandlerInterceptor { ...@@ -59,8 +59,8 @@ public class SecurityInterceptor implements HandlerInterceptor {
return true; return true;
} else { } else {
log.warn("用户[{}]token已过期,请求URI: {}", loginUser.getUsername(), request.getRequestURI()); log.warn("用户[{}]token已过期,请求URI: {}", loginUser.getUsername(), request.getRequestURI());
throw new InvalidTokenException(CodeEnum.UNAUTHORIZED.getCode(), "未登录或登录已过期");
} }
return false;
} }
/** /**
......
...@@ -9,7 +9,8 @@ import com.jomalls.custom.app.enums.CustomProductInfoStatusEnum; ...@@ -9,7 +9,8 @@ import com.jomalls.custom.app.enums.CustomProductInfoStatusEnum;
import com.jomalls.custom.app.service.CustomProductInfoService; import com.jomalls.custom.app.service.CustomProductInfoService;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO; import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO; import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.DbDiyVO; import com.jomalls.custom.app.vo.CraftCenterVO;
import com.jomalls.custom.app.vo.DbDiySnakeVO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
...@@ -37,12 +38,6 @@ public class CustomProductInfoController { ...@@ -37,12 +38,6 @@ public class CustomProductInfoController {
@Autowired @Autowired
private CustomProductInfoService customProductInfoService; private CustomProductInfoService customProductInfoService;
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/page", method = RequestMethod.POST)
public IPage<CustomProductInfoVO> pageList(@RequestBody CustomProductInfoSnakeDTO param) {
return customProductInfoService.pageList(param);
}
@Operation(summary = "创建商品", description = "创建商品") @Operation(summary = "创建商品", description = "创建商品")
@PostMapping("/create") @PostMapping("/create")
public void create(@RequestBody @Valid CustomProductInfoSnakeDTO dto) { public void create(@RequestBody @Valid CustomProductInfoSnakeDTO dto) {
...@@ -64,6 +59,12 @@ public class CustomProductInfoController { ...@@ -64,6 +59,12 @@ public class CustomProductInfoController {
return customProductInfoService.getByIdOrSku(id, sku, namespace); return customProductInfoService.getByIdOrSku(id, sku, namespace);
} }
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/page", method = RequestMethod.POST)
public IPage<CustomProductInfoSnakeVO> pageList(@RequestBody CustomProductInfoSnakeDTO param) {
return customProductInfoService.pageList(param);
}
@Operation(summary = "获取状态列表", description = "返回所有商品状态枚举") @Operation(summary = "获取状态列表", description = "返回所有商品状态枚举")
@GetMapping("/getStatusList") @GetMapping("/getStatusList")
public List<Map<String, Object>> getStatusList() { public List<Map<String, Object>> getStatusList() {
...@@ -81,7 +82,7 @@ public class CustomProductInfoController { ...@@ -81,7 +82,7 @@ public class CustomProductInfoController {
@Operation(summary = "获取绑定的模型", description = "获取商品绑定的 DIY 模板列表") @Operation(summary = "获取绑定的模型", description = "获取商品绑定的 DIY 模板列表")
@GetMapping("/getBindsDiyById") @GetMapping("/getBindsDiyById")
public List<DbDiyVO> getBindsDiyById(@Parameter(description = "商品 ID") @RequestParam Integer id) { public List<DbDiySnakeVO> getBindsDiyById(@Parameter(description = "商品 ID") @RequestParam Integer id) {
return customProductInfoService.getBindsDiyById(id); return customProductInfoService.getBindsDiyById(id);
} }
...@@ -109,13 +110,12 @@ public class CustomProductInfoController { ...@@ -109,13 +110,12 @@ public class CustomProductInfoController {
customProductInfoService.addBlackList(dto); customProductInfoService.addBlackList(dto);
} }
@Operation(summary = "获取绑定的工艺", description = "获取商品绑定的工艺 ID 列表") @Operation(summary = "获取绑定的工艺", description = "获取商品绑定的工艺实体列表")
@GetMapping("/getCraftById") @GetMapping("/getCraftById")
public List<Long> getCraftById(@Parameter(description = "商品 ID") @RequestParam Integer id) { public List<CraftCenterVO> getCraftById(@Parameter(description = "商品 ID") @RequestParam Integer id) {
return customProductInfoService.getCraftById(id); return customProductInfoService.getCraftById(id);
} }
// ==================== ERP 专用端点(对齐 TS ApiCustomProductInfoController) ====================
@Operation(summary = "ERP 分页查询", description = "包含黑名单过滤、用户折扣等 ERP 特定逻辑") @Operation(summary = "ERP 分页查询", description = "包含黑名单过滤、用户折扣等 ERP 特定逻辑")
@PostMapping("/erpPage") @PostMapping("/erpPage")
...@@ -125,10 +125,10 @@ public class CustomProductInfoController { ...@@ -125,10 +125,10 @@ public class CustomProductInfoController {
@Operation(summary = "ERP 获取绑定 DIY", description = "获取商品绑定的 DIY 模板(含效果图),支持按 userMark/namespace 过滤") @Operation(summary = "ERP 获取绑定 DIY", description = "获取商品绑定的 DIY 模板(含效果图),支持按 userMark/namespace 过滤")
@GetMapping("/getErpBindsDiyById") @GetMapping("/getErpBindsDiyById")
public List<DbDiyVO> getErpBindsDiyById( public List<DbDiySnakeVO> getBindsDiyByIdAndUserMark(
@Parameter(description = "商品 ID") @RequestParam Integer id, @Parameter(description = "商品 ID") @RequestParam Integer id,
@Parameter(description = "用户标识") @RequestParam(required = false) String userMark, @Parameter(description = "用户标识") @RequestParam(required = false) String userMark,
@Parameter(description = "命名空间") @RequestParam(required = false) String namespace) { @Parameter(description = "命名空间") @RequestParam(required = false) String namespace) {
return customProductInfoService.getErpBindsDiyById(id, userMark, namespace); return customProductInfoService.getBindsDiyByIdAndUserMark(id, userMark, namespace);
} }
} }
...@@ -3,7 +3,7 @@ package com.jomalls.custom.webapp.controller; ...@@ -3,7 +3,7 @@ package com.jomalls.custom.webapp.controller;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.service.DbDiyService; import com.jomalls.custom.app.service.DbDiyService;
import com.jomalls.custom.app.vo.DbDiyPageVO; import com.jomalls.custom.app.vo.DbDiyPageVO;
import com.jomalls.custom.app.vo.DbDiyVO; import com.jomalls.custom.app.vo.DbDiySnakeVO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
...@@ -33,13 +33,13 @@ public class DbDiyController { ...@@ -33,13 +33,13 @@ public class DbDiyController {
/** /**
* 列表查询接口 * 列表查询接口
* *
* @param dbDiyVO 条件model * @param dbDiySnakeVO 条件model
* @return list集合 * @return list集合
*/ */
@Operation(summary = "列表查询接口", description = "根据条件查询列表接口(不分页)") @Operation(summary = "列表查询接口", description = "根据条件查询列表接口(不分页)")
@RequestMapping(value = "/list", method = RequestMethod.POST) @RequestMapping(value = "/list", method = RequestMethod.POST)
public List<DbDiyVO> list(@RequestBody DbDiyVO dbDiyVO) { public List<DbDiySnakeVO> list(@RequestBody DbDiySnakeVO dbDiySnakeVO) {
return dbDiyService.list(dbDiyVO); return dbDiyService.list(dbDiySnakeVO);
} }
/** /**
...@@ -50,7 +50,7 @@ public class DbDiyController { ...@@ -50,7 +50,7 @@ public class DbDiyController {
*/ */
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口") @Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/pageList", method = RequestMethod.POST) @RequestMapping(value = "/pageList", method = RequestMethod.POST)
public IPage<DbDiyVO> pageList(@RequestBody DbDiyPageVO dbDiyPageVO) { public IPage<DbDiySnakeVO> pageList(@RequestBody DbDiyPageVO dbDiyPageVO) {
return dbDiyService.pageList(dbDiyPageVO); return dbDiyService.pageList(dbDiyPageVO);
} }
...@@ -63,31 +63,31 @@ public class DbDiyController { ...@@ -63,31 +63,31 @@ public class DbDiyController {
*/ */
@Operation(summary = "根据主键id查询详情", description = "根据主键id查询详情") @Operation(summary = "根据主键id查询详情", description = "根据主键id查询详情")
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET) @RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public DbDiyVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) { public DbDiySnakeVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
return dbDiyService.info(id); return dbDiyService.info(id);
} }
/** /**
* 保存对象 * 保存对象
* *
* @param dbDiyVO 保存对象 * @param dbDiySnakeVO 保存对象
*/ */
@Operation(summary = "保存对象", description = "保存对象") @Operation(summary = "保存对象", description = "保存对象")
@RequestMapping(value = "/save", method = RequestMethod.POST) @RequestMapping(value = "/save", method = RequestMethod.POST)
public void save(@RequestBody @Valid DbDiyVO dbDiyVO) { public void save(@RequestBody @Valid DbDiySnakeVO dbDiySnakeVO) {
dbDiyService.save(dbDiyVO); dbDiyService.save(dbDiySnakeVO);
} }
/** /**
* 根据id修改对象 * 根据id修改对象
* *
* @param dbDiyVO 修改对象 * @param dbDiySnakeVO 修改对象
*/ */
@Operation(summary = "根据id修改对象", description = "根据id修改对象") @Operation(summary = "根据id修改对象", description = "根据id修改对象")
@RequestMapping(value = "/updateById", method = RequestMethod.PUT) @RequestMapping(value = "/updateById", method = RequestMethod.PUT)
public void updateById(@RequestBody DbDiyVO dbDiyVO) { public void updateById(@RequestBody DbDiySnakeVO dbDiySnakeVO) {
dbDiyService.updateById(dbDiyVO); dbDiyService.updateById(dbDiySnakeVO);
} }
/** /**
......
package com.jomalls.custom.webapp.controller; package com.jomalls.custom.webapp.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.LogCustomProductPageVO;
import com.jomalls.custom.app.vo.LogCustomProductVO;
import com.jomalls.custom.app.service.LogCustomProductService; import com.jomalls.custom.app.service.LogCustomProductService;
import com.jomalls.custom.app.vo.LogCustomProductSnakeVO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
/** /**
* @author Lizh * @author Lizh
* @version 0.01 * @version 0.02
* @description: Controller * @description: 商品日志 Controller(对齐 TS ApiProductLogController)
* @date 2026-05-29 11:43:04 * @date 2026-05-29 11:43:04
*/ */
@Slf4j @Slf4j
@RestController @RestController
@Tag(name = "/logCustomProduct", description = "Controller") @Tag(name = "/api/v2/product/log", description = "商品日志接口")
@RequestMapping("/logCustomProduct") @RequestMapping("/api/v2/product/log")
public class LogCustomProductController { public class LogCustomProductController {
@Autowired @Autowired
private LogCustomProductService logCustomProductService; private LogCustomProductService logCustomProductService;
/** /**
* 列表查询接口 * 根据商品 ID 获取日志列表(对齐 TS getListByProductId)
* *
* @param logCustomProductVO 条件model * @param id 商品 ID
* @return list集合 * @return 日志列表,按创建时间降序
*/ */
@Operation(summary = "列表查询接口", description = "根据条件查询列表接口(不分页)") @Operation(summary = "根据商品 ID 获取日志列表", description = "根据商品 ID 查询所有操作日志,按时间降序排列")
@RequestMapping(value = "/list", method = RequestMethod.POST) @GetMapping("/getByProductId")
public List<LogCustomProductVO> list(@RequestBody LogCustomProductVO logCustomProductVO) { public List<LogCustomProductSnakeVO> getListByProductId(@Parameter(description = "商品 ID") @RequestParam Integer id) {
return logCustomProductService.list(logCustomProductVO); return logCustomProductService.getListByProductId(id);
}
/**
* 根据条件查询分页列表接口
*
* @param logCustomProductPageVO 分页入参model
* @return 分页对象
*/
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/pageList", method = RequestMethod.POST)
public IPage<LogCustomProductVO> pageList(@RequestBody LogCustomProductPageVO logCustomProductPageVO) {
return logCustomProductService.pageList(logCustomProductPageVO);
}
/**
* 根据主键id查询详情
*
* @param id 主键
* @return 实体model
*/
@Operation(summary = "根据主键id查询详情", description = "根据主键id查询详情")
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public LogCustomProductVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
return logCustomProductService.info(id);
}
/**
* 保存对象
*
* @param logCustomProductVO 保存对象
*/
@Operation(summary = "保存对象", description = "保存对象")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void save(@RequestBody @Valid LogCustomProductVO logCustomProductVO) {
logCustomProductService.save(logCustomProductVO);
}
/**
* 根据id修改对象
*
* @param logCustomProductVO 修改对象
*/
@Operation(summary = "根据id修改对象", description = "根据id修改对象")
@RequestMapping(value = "/updateById", method = RequestMethod.PUT)
public void updateById(@RequestBody LogCustomProductVO logCustomProductVO) {
logCustomProductService.updateById(logCustomProductVO);
}
/**
* 根据主键id进行删除
*
* @param id 主键
*/
@Operation(summary = "根据主键id进行删除", description = "根据主键id进行删除")
@RequestMapping(value = "/deleteById/{id}", method = RequestMethod.DELETE)
public void deleteById(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
logCustomProductService.deleteById(id);
} }
} }
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