Commit be6c42f3 by Lizh

迁移定制商品明细(/product/item)相关的接口

parent c7f3747c
package com.jomalls.custom.app.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* 更新商品销售价格请求 DTO
* <p>
* 对齐 TS {@code UpdateCustomProductInfoSalesPriceDTO}。
*
* @author Lizh
* @date 2026-06-12
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "更新商品销售价格请求")
public class UpdateSalesPriceSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "商品ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "商品ID不能为空")
private Integer product_id;
@Schema(description = "明细价格列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "明细列表不能为空")
private List<@Valid UpdateSalesPriceItemSnakeDTO> items;
/**
* 子项 DTO — 对齐 TS {@code UpdateCustomProductItemSalesPriceDTO}
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "明细销售价格")
public static class UpdateSalesPriceItemSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "明细ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "明细ID不能为空")
private Integer id;
@Schema(description = "销售价格", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "销售价格不能为空")
@Min(value = 0, message = "销售价格不能小于0")
private BigDecimal sales_price;
}
}
......@@ -5,7 +5,7 @@ import com.jomalls.custom.app.dto.AddBlackListDTO;
import com.jomalls.custom.app.dto.BindDiyUserDTO;
import com.jomalls.custom.app.dto.CustomProductInfoSnakeDTO;
import com.jomalls.custom.app.dto.CustomProductInfoUpdateSnakeDTO;
import com.jomalls.custom.app.vo.CraftCenterVO;
import com.jomalls.custom.app.vo.CraftCenterSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.DbDiySnakeVO;
......@@ -101,7 +101,7 @@ public interface CustomProductInfoService {
* @param id 商品 ID
* @return 工艺实体列表
*/
List<CraftCenterVO> getCraftById(Integer id);
List<CraftCenterSnakeVO> getCraftById(Integer id);
/**
* ERP 分页查询(对齐 TS erpPage)
......
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductItemPageVO;
import com.jomalls.custom.app.dto.UpdateSalesPriceSnakeDTO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import java.util.List;
/**
* 定制商品明细服务接口
* <p>
* 对齐 TS 项目 {@code CustomProductItemService}。
*
* @author Lizh
* @version 0.01
* @description: 接口
* @date 2026-05-29 10:43:29
* @date 2026-06-12
*/
public interface CustomProductItemService {
/**
* 列表查询接口
*
* @param customProductItemSnakeVO 条件model
* @return list集合
*/
List<CustomProductItemSnakeVO> list(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据条件查询分页列表接口
* 根据商品 ID 查询明细列表
* <p>
* 对齐 TS {@code getByProductId(productId)}
*
* @param customProductItemPageVO 分页入参model
* @return 分页对象
* @param productId 商品 ID
* @return 明细列表
*/
IPage<CustomProductItemSnakeVO> pageList(CustomProductItemPageVO customProductItemPageVO);
List<CustomProductItemSnakeVO> getByProductId(Integer productId);
/**
* 根据id查询详情
* 批量更新商品明细销售价
* <p>
* 对齐 TS {@code updateSalesPrice(body)}。
* 更新明细销售价 → 联动更新模板明细采购价 → 重算模板成本价 → 更新商品主表售价区间 → 写日志。
*
* @param id 主键
* @return 实体model
* @param dto 更新请求
*/
CustomProductItemSnakeVO info(Integer id);
void updateSalesPrice(UpdateSalesPriceSnakeDTO dto);
/**
* 保存对象
* 根据 SKU 列表查询明细
* <p>
* 对齐 TS {@code getBySkus(skus, namespace)}。
* 查询明细并附加工厂信息,可选应用用户折扣定价。
*
* @param customProductItemSnakeVO 保存对象
* @param skus SKU 列表
* @param namespace 可选用户 namespace(用于折扣计算)
* @return 明细列表
*/
void save(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据id修改对象
*
* @param customProductItemSnakeVO 修改对象
*/
void updateById(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(Integer id);
List<CustomProductItemSnakeVO> getBySkus(List<String> skus, String namespace);
}
package com.jomalls.custom.app.service;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
import java.util.List;
/**
* DIY 用户服务
* <p>
......@@ -40,4 +44,21 @@ public interface DiyUserService {
* @param vo 商品完整详情
*/
void setProductExternalPrice(DbDiyUserEntity user, CustomProductInfoSnakeVO vo);
/**
* 对商品明细应用用户折扣外部定价
* <p>
* 对齐 TS {@code setProductItemExternalPrice(user, customProductItem)}。
* 根据用户折扣比例,对明细的销售价、工厂价格关联的销售价、
* 以及关联商品信息的销售价进行打折。
*
* @param user 用户(含 discount 折扣字段)
* @param item 商品明细
* @param factoryPriceList 该明细的工厂价格关联列表(可为 null)
* @param productInfo 关联的商品信息(可为 null)
*/
void setProductItemExternalPrice(DbDiyUserEntity user,
CustomProductItemSnakeVO item,
List<CustomProductFactoryPriceRelSnakeVO> factoryPriceList,
CustomProductInfoSnakeVO productInfo);
}
......@@ -755,7 +755,7 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
* 再批量查询 craft_center 表返回完整工艺实体。
*/
@Override
public List<CraftCenterVO> getCraftById(Integer id) {
public List<CraftCenterSnakeVO> getCraftById(Integer id) {
CustomAsserts.nonNull(id, "商品 ID 不能为空");
// 1. 查询关联表获取 craft_id 列表
List<Long> craftIds = customProductCraftRelDomainService.list(
......@@ -770,9 +770,8 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
// 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))
// 3. 转换为 Snake命名规则的VO 返回
return crafts.stream().map(e -> BeanMapper.snakeCase().convert(e, CraftCenterSnakeVO.class))
.collect(Collectors.toList());
}
......
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.dto.UpdateSalesPriceSnakeDTO;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.vo.CustomProductItemPageVO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import com.jomalls.custom.app.service.CustomProductItemService;
import com.jomalls.custom.app.service.DiyUserService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.CustomProductItemEntity;
import com.jomalls.custom.domain.service.CustomProductItemDomainService;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import com.jomalls.custom.dal.entity.*;
import com.jomalls.custom.domain.service.*;
import com.jomalls.custom.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
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 org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
* 定制商品明细服务实现
* <p>
* 对齐 TS 项目 {@code CustomProductItemService}。
*
* @author Lizh
* @version 0.01
* @description: 接口实现
* @date 2026-05-29 10:43:29
* @date 2026-06-12
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomProductItemServiceImpl implements CustomProductItemService {
private final CustomProductItemDomainService customProductItemDomainService;
private final CustomProductInfoDomainService customProductInfoDomainService;
private final ProductTemplateItemDomainService productTemplateItemDomainService;
private final ProductTemplateInfoDomainService productTemplateInfoDomainService;
private final LogCustomProductDomainService logCustomProductDomainService;
private final LogProductTemplateDomainService logProductTemplateDomainService;
private final DiyUserService diyUserService;
private final TransactionTemplate transactionTemplate;
@Autowired
public CustomProductItemServiceImpl(CustomProductItemDomainService customProductItemDomainService) {
this.customProductItemDomainService = customProductItemDomainService;
}
@Override
public List<CustomProductItemSnakeVO> list(CustomProductItemSnakeVO customProductItemSnakeVO) {
QueryWrapper<CustomProductItemEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<CustomProductItemEntity> list = customProductItemDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductItemSnakeVO.class)).collect(Collectors.toList());
public List<CustomProductItemSnakeVO> getByProductId(Integer productId) {
if (productId == null) {
throw new ServiceException("商品ID不能为空");
}
List<CustomProductItemEntity> items = customProductItemDomainService.selectByProductId(productId);
return items.stream().map(e -> BeanMapper.snakeCase().convert(e, CustomProductItemSnakeVO.class))
.collect(Collectors.toList());
}
@Override
public IPage<CustomProductItemSnakeVO> pageList(CustomProductItemPageVO customProductItemPageVO) {
CustomAsserts.nonNull(customProductItemPageVO, "分页查询参数不能为空");
QueryWrapper<CustomProductItemEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<CustomProductItemEntity> page = customProductItemDomainService.selectPage(queryWrapper, customProductItemPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductItemSnakeVO.class));
public void updateSalesPrice(UpdateSalesPriceSnakeDTO dto) {
if (dto.getProduct_id() == null) {
throw new ServiceException("商品ID不能为空");
}
if (CollectionUtils.isEmpty(dto.getItems())) {
throw new ServiceException("明细列表不能为空");
}
@Override
public CustomProductItemSnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductItemEntity customProductItem = customProductItemDomainService.getById(id);
return BeanMapper.mapper().convert(customProductItem, CustomProductItemSnakeVO.class);
// ① 查询商品信息(对齐 TS:30-38)
CustomProductInfoEntity productInfo = customProductInfoDomainService.getById(dto.getProduct_id());
if (productInfo == null) {
throw new ServiceException("商品信息不存在");
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductItemSnakeVO customProductItemSnakeVO) {
CustomAsserts.nonNull(customProductItemSnakeVO, "实体对象不能为空");
CustomProductItemEntity customProductItemEntity = BeanMapper.mapper().convert(customProductItemSnakeVO, CustomProductItemEntity.class);
try {
customProductItemDomainService.save(customProductItemEntity);
} catch (DuplicateKeyException e) {
log.info("[ CustomProductItemServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
// ② 查询商品下所有明细
List<CustomProductItemEntity> customProductItems =
customProductItemDomainService.selectByProductId(dto.getProduct_id());
// ③ 构建 priceMap:{ itemId → newSalesPrice }(对齐 TS:42-46)
Map<Integer, BigDecimal> priceMap = new HashMap<>();
for (UpdateSalesPriceSnakeDTO.UpdateSalesPriceItemSnakeDTO item : dto.getItems()) {
priceMap.put(item.getId(), item.getSales_price());
}
// ④ 批量查询明细关联的模板子项(对齐 TS include ProductTemplateItem)
// 一次 IN 查询替代 N 次单查,避免 N+1 问题
final Map<Integer, List<ProductTemplateItemEntity>> templateItemsMap;
if (!CollectionUtils.isEmpty(customProductItems)) {
// 批量获取id集合
List<Integer> itemIds = customProductItems.stream().map(CustomProductItemEntity::getId)
.collect(Collectors.toList());
// 批量查询
List<ProductTemplateItemEntity> allTemplateItems = productTemplateItemDomainService.selectByItemIds(itemIds);
templateItemsMap = CollectionUtils.isEmpty(allTemplateItems)
? Collections.emptyMap()
: allTemplateItems.stream()
.collect(Collectors.groupingBy(ProductTemplateItemEntity::getItemId));
} else {
templateItemsMap = Collections.emptyMap();
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductItemSnakeVO customProductItemSnakeVO) {
CustomAsserts.nonNull(customProductItemSnakeVO, "实体对象不能为空");
CustomProductItemEntity customProductItem = BeanMapper.mapper().convert(customProductItemSnakeVO, CustomProductItemEntity.class);
// ⑤ 编程式事务(对齐 TS:47 transaction)
try {
customProductItemDomainService.updateById(customProductItem);
} catch (DuplicateKeyException e) {
log.info("[ CustomProductItemServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
transactionTemplate.executeWithoutResult(status -> {
BigDecimal salesPriceMin = new BigDecimal(Integer.MAX_VALUE);
BigDecimal salesPriceMax = new BigDecimal(Integer.MIN_VALUE);
for (CustomProductItemEntity item : customProductItems) {
BigDecimal newPrice = priceMap.get(item.getId());
if (newPrice == null) {
continue;
}
// 计算全局最大/最小售价(对齐 TS:49-58)
if (newPrice.compareTo(salesPriceMax) > 0) {
salesPriceMax = newPrice;
}
if (newPrice.compareTo(salesPriceMin) < 0) {
salesPriceMin = newPrice;
}
// 价格未变则跳过(对齐 TS:60)
if (newPrice.compareTo(item.getSalesPrice()) == 0) {
continue;
}
// 更新明细销售价(对齐 TS:61)
item.setSalesPrice(newPrice);
customProductItemDomainService.updateById(item);
// 日志:SKU 更改销售价格(对齐 TS:62)
saveCustomProductLog(item.getProductId(),
item.getSku() + "更改销售价格为" + newPrice);
// 如果明细有关联模板子项,联动更新采购价(对齐 TS:63-68)
List<ProductTemplateItemEntity> templateItems = templateItemsMap.get(item.getId());
if (!CollectionUtils.isEmpty(templateItems)) {
for (ProductTemplateItemEntity templateItem : templateItems) {
updateCostPrice(newPrice, templateItem);
// 日志:SKU 更改采购价格(对齐 TS:66)
saveProductTemplateLog(templateItem.getTemplateId(), templateItem.getSku() + "更改采购价格为" + newPrice);
}
}
}
// ⑥ 更新商品主表的售价区间(对齐 TS:70-83)
StringBuilder productLog = new StringBuilder();
// 商品最低售价有修改
if (salesPriceMin.compareTo(new BigDecimal(Integer.MAX_VALUE)) != 0) {
String newSalesPriceMin = salesPriceMin.stripTrailingZeros().toPlainString();
// 商品最低售价未变则跳过
if (productInfo.getSalesPrice() == null || productInfo.getSalesPrice().compareTo(salesPriceMin) != 0) {
productLog.append("商品最低售价由").append(productInfo.getSalesPrice()).append("改为").append(newSalesPriceMin);
productInfo.setSalesPrice(salesPriceMin);
}
}
// 商品最高售价有修改
if (salesPriceMax.compareTo(new BigDecimal(Integer.MIN_VALUE)) != 0) {
String newSalesPriceMax = salesPriceMax.stripTrailingZeros().toPlainString();
// 商品最高售价未变则跳过
if (productInfo.getSalesPriceMax() == null || productInfo.getSalesPriceMax().compareTo(salesPriceMax) != 0) {
if (!productLog.isEmpty()) {
productLog.append(",");
}
productLog.append("商品最高售价由").append(productInfo.getSalesPriceMax()).append("改为").append(newSalesPriceMax);
productInfo.setSalesPriceMax(salesPriceMax);
}
}
if (!productLog.isEmpty()) {
customProductInfoDomainService.updateById(productInfo);
saveCustomProductLog(productInfo.getId(), productLog.toString());
}
});
} catch (Exception e) {
log.error("[ updateSalesPrice ] 更新销售价格失败", e);
throw new ServiceException("更新销售价格失败: " + e.getMessage());
}
}
/**
* 更新模板子项的采购价,并重算模板成本价区间(对齐 TS updateCostPrice:102-127)
*/
private void updateCostPrice(BigDecimal newPrice, ProductTemplateItemEntity templateItem) {
// 更新当前模板子项的 cost_price(对齐 TS:103)
templateItem.setCostPrice(newPrice);
productTemplateItemDomainService.updateById(templateItem);
// 查询该模板下所有子项,重算 cost_price 最大/最小值(对齐 TS:104-118)
Integer templateId = templateItem.getTemplateId();
List<ProductTemplateItemEntity> allTemplateItems =
productTemplateItemDomainService.selectByTemplateId(templateId);
BigDecimal maxCostPrice = BigDecimal.ZERO;
BigDecimal minCostPrice = new BigDecimal(Integer.MAX_VALUE);
boolean hasCostPrice = false;
for (ProductTemplateItemEntity item : allTemplateItems) {
if (item.getCostPrice() == null) {
continue;
}
hasCostPrice = true;
BigDecimal price = item.getCostPrice();
if (price.compareTo(maxCostPrice) > 0) {
maxCostPrice = price;
}
if (price.compareTo(minCostPrice) < 0) {
minCostPrice = price;
}
}
if (!hasCostPrice) {
return;
}
// 更新模板信息表的 cost_price / cost_price_max(对齐 TS:119-126)
ProductTemplateInfoEntity templateInfo = productTemplateInfoDomainService.getById(templateId);
if (templateInfo != null) {
templateInfo.setCostPrice(minCostPrice);
if (maxCostPrice.compareTo(minCostPrice) != 0) {
templateInfo.setCostPriceMax(maxCostPrice);
} else {
templateInfo.setCostPriceMax(null);
}
productTemplateInfoDomainService.updateById(templateInfo);
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
customProductItemDomainService.removeById(id);
public List<CustomProductItemSnakeVO> getBySkus(List<String> skus, String namespace) {
if (CollectionUtils.isEmpty(skus)) {
throw new ServiceException("SKU不能为空");
}
// ① 查询明细(含关联商品信息的工厂字段)(对齐 TS:152-157)
List<CustomProductItemEntity> items = customProductItemDomainService.selectBySkusWithInfo(skus);
// ② 如果传了 namespace,查询用户并应用折扣(对齐 TS:165-174)
if (StringUtils.hasText(namespace)) {
DbDiyUserEntity user = diyUserService.getByNamespace(namespace);
if (user == null) {
throw new ServiceException("用户信息不存在");
}
// 计算用户折扣率(对齐 TS:357-360)
BigDecimal discountBase = new BigDecimal("100");
BigDecimal discountRate = user.getDiscount() != null
? user.getDiscount().divide(discountBase, 4, RoundingMode.HALF_UP)
: BigDecimal.ONE;
if (discountRate.compareTo(BigDecimal.ONE) != 0) {
for (CustomProductItemEntity item : items) {
if (item.getSalesPrice() != null) {
item.setSalesPrice(item.getSalesPrice().multiply(discountRate)
.setScale(2, RoundingMode.HALF_UP));
}
}
}
}
// ③ 转换实体为响应 VO,附加工厂信息和 print_type(对齐 TS:158-164)
return items.stream().map(item -> {
CustomProductItemSnakeVO vo = BeanMapper.snakeCase().convert(item, CustomProductItemSnakeVO.class);
// 附加工厂信息(来自 JOIN custom_product_info)
vo.setFactory_id(item.getInfoFactoryId());
vo.setFactory_code(item.getInfoFactoryCode());
// print_type 使用商品主表的 print_type 覆盖明细自身的(对齐 TS: temp.print_type = item.customProductInfo?.print_type)
if (item.getInfoPrintType() != null) {
vo.setPrint_type(item.getInfoPrintType());
}
return vo;
}).collect(Collectors.toList());
}
/**
* 保存定制商品日志(对齐 TS customProductLogService.saveTransaction)
*/
private void saveCustomProductLog(Integer productId, String description) {
LogCustomProductEntity log = new LogCustomProductEntity();
log.setProductId(productId);
log.setDescription(description);
log.setEmployeeId(SecurityUtils.getUserId());
log.setEmployeeAccount(SecurityUtils.getUsername());
log.setCreateTime(new Date());
logCustomProductDomainService.save(log);
}
/**
* 保存产品模板日志(对齐 TS productTemplateLogService.saveTransaction)
*/
private void saveProductTemplateLog(Integer templateId, String description) {
LogProductTemplateEntity log = new LogProductTemplateEntity();
log.setTemplateId(templateId);
log.setDescription(description);
log.setEmployeeId(SecurityUtils.getUserId());
log.setEmployeeAccount(SecurityUtils.getUsername());
log.setCreateTime(new Date());
logProductTemplateDomainService.save(log);
}
}
......@@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
/**
* DIY 用户服务实现
......@@ -77,4 +78,44 @@ public class DiyUserServiceImpl implements DiyUserService {
}
}
}
@Override
public void setProductItemExternalPrice(DbDiyUserEntity user,
CustomProductItemSnakeVO item,
List<CustomProductFactoryPriceRelSnakeVO> factoryPriceList,
CustomProductInfoSnakeVO productInfo) {
if (user == null || user.getDiscount() == null) {
return;
}
// discount 如 85 → 折扣率 0.85(对齐 TS:357-358)
BigDecimal discountRate = user.getDiscount().divide(DISCOUNT_BASE, 4, RoundingMode.HALF_UP);
if (discountRate.compareTo(BigDecimal.ONE) == 0) {
return;
}
log.debug("[ setProductItemExternalPrice ] 用户={}, 折扣率={}", user.getName(), discountRate);
// 明细的 sales_price(对齐 TS:363-365)
if (item != null && item.getSales_price() != null) {
item.setSales_price(item.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
// 工厂价格关联的 sales_price(对齐 TS:366-371)
if (factoryPriceList != null) {
for (CustomProductFactoryPriceRelSnakeVO fp : factoryPriceList) {
if (fp.getSales_price() != null) {
fp.setSales_price(fp.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
}
}
// 关联商品信息的 sales_price / sales_price_max(对齐 TS:373-380)
if (productInfo != null) {
if (productInfo.getSales_price() != null) {
productInfo.setSales_price(productInfo.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
if (productInfo.getSales_price_max() != null) {
productInfo.setSales_price_max(productInfo.getSales_price_max().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
}
}
}
......@@ -23,7 +23,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工艺中心")
public class CraftCenterVO implements Serializable {
public class CraftCenterSnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -31,38 +31,38 @@ public class CraftCenterVO implements Serializable {
private Long id;
@Schema(description = "工艺名称")
private String craftName;
private String craft_name;
@Schema(description = "工艺英文名称")
private String craftEnName;
private String craft_en_name;
@Schema(description = "工艺类型")
private String craftType;
private String craft_type;
@Schema(description = "工艺编码")
private String craftCode;
private String craft_code;
@Schema(description = "币种")
private String currencyCode;
private String currency_code;
@Schema(description = "工艺成本")
private String craftCost;
private String craft_cost;
@Schema(description = "其他面的价格")
private String otherSideCost;
private String other_side_cost;
@Schema(description = "是否启用")
private Boolean craftEnable;
private Boolean craft_enable;
@Schema(description = "是否在ERP显示")
private Boolean erpDisplay;
private Boolean erp_display;
@Schema(description = "国家代码")
private String countryCode;
private String country_code;
@Schema(description = "创建时间")
private Date createTime;
private Date create_time;
@Schema(description = "修改时间")
private Date updateTime;
private Date update_time;
}
......@@ -189,6 +189,18 @@ public class CustomProductItemSnakeVO implements Serializable {
private Integer size_type;
/**
* 关联商品信息的工厂ID(仅 getBySkus 接口填充,非表字段)
*/
@Schema(description = "关联商品信息的工厂ID")
private Integer factory_id;
/**
* 关联商品信息的工厂编码(仅 getBySkus 接口填充,非表字段)
*/
@Schema(description = "关联商品信息的工厂编码")
private String factory_code;
/**
* 排序
*/
@Schema(description = "排序")
......
......@@ -175,4 +175,22 @@ public class CustomProductItemEntity implements Serializable {
@TableField("update_time")
private Date updateTime;
/**
* 关联 custom_product_info 表的 factory_id(仅查询时填充,非表字段)
*/
@TableField(exist = false)
private Integer infoFactoryId;
/**
* 关联 custom_product_info 表的 factory_code(仅查询时填充,非表字段)
*/
@TableField(exist = false)
private String infoFactoryCode;
/**
* 关联 custom_product_info 表的 print_type(仅查询时填充,非表字段)
*/
@TableField(exist = false)
private Integer infoPrintType;
}
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 LogProductTemplate} 实体(log_product_template 表)。
*
* @author Lizh
* @date 2026-06-12
*/
@Data
@TableName("log_product_template")
public class LogProductTemplateEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 模板 ID(product_template_info 表 id) */
@TableField("template_id")
private Integer templateId;
/** 操作人 ID */
@TableField("employee_id")
private Long employeeId;
/** 操作人账号 */
@TableField("employee_account")
private String employeeAccount;
/** 操作描述 */
@TableField("description")
private String description;
/** 创建时间 */
@TableField("create_time")
private Date createTime;
}
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.math.BigDecimal;
import java.util.Date;
/**
* 产品模板明细实体
* <p>
* 对齐 TS 项目 {@code ProductTemplateItem} 实体(product_template_item 表)。
*
* @author Lizh
* @date 2026-06-12
*/
@Data
@TableName("product_template_item")
public class ProductTemplateItemEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/** product_template_info 表 ID */
@TableField("template_id")
private Integer templateId;
/** sku */
@TableField("sku")
private String sku;
/** sku 商品名称 */
@TableField("sku_name")
private String skuName;
/** 封面图 */
@TableField("image")
private String image;
/** 图片集 */
@TableField("image_ary")
private String imageAry;
/** 效果图 ID */
@TableField("xgt_id")
private Integer xgtId;
/** 属性分类 ID1 */
@TableField("property_cate_id1")
private Integer propertyCateId1;
/** 属性分类 ID2 */
@TableField("property_cate_id2")
private Integer propertyCateId2;
/** 属性分类 ID3 */
@TableField("property_cate_id3")
private Integer propertyCateId3;
@TableField("property1_id")
private Integer property1Id;
@TableField("property2_id")
private Integer property2Id;
@TableField("property3_id")
private Integer property3Id;
/** 属性编码1 */
@TableField("property_code1")
private String propertyCode1;
/** 属性编码2 */
@TableField("property_code2")
private String propertyCode2;
@TableField("property_code3")
private String propertyCode3;
/** 属性名称1 */
@TableField("option_enname1")
private String optionEnname1;
/** 属性名称2 */
@TableField("option_enname2")
private String optionEnname2;
@TableField("option_enname3")
private String optionEnname3;
@TableField("custom_value1")
private String customValue1;
@TableField("custom_value2")
private String customValue2;
@TableField("custom_value3")
private String customValue3;
/** 采购价 */
@TableField("cost_price")
private BigDecimal costPrice;
/** 销售价 */
@TableField("sales_price")
private BigDecimal salesPrice;
/** 印花类型 0满印 1局部印 */
@TableField("print_type")
private Integer printType;
/** 排序 */
@TableField("sort")
private Integer sort;
/** 关联生产文件 IDS */
@TableField("relation_ids")
private String relationIds;
/** 关联生产文件 (JSON) */
@TableField("relation")
private String relation;
/** 创建时间 */
@TableField("create_time")
private Date createTime;
/** 更新时间 */
@TableField("update_time")
private Date updateTime;
/** custom_product_item 表 ID */
@TableField("item_id")
private Integer itemId;
/** custom_product_item 表 sku */
@TableField("item_sku")
private String itemSku;
/** 货号 */
@TableField("catalog_number")
private String catalogNumber;
/** 针对局部印 稿件宽度 */
@TableField("mss_width")
private Integer mssWidth;
/** 针对局部印 稿件高度 */
@TableField("mss_height")
private Integer mssHeight;
/** 尺码类型 1正常码 2大码 */
@TableField("size_type")
private Integer sizeType;
}
......@@ -3,6 +3,9 @@ package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.CustomProductItemEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Lizh
......@@ -12,4 +15,20 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface CustomProductItemMapper extends BaseMapper<CustomProductItemEntity> {
/**
* 根据商品 ID 查询明细列表
*
* @param productId 商品 ID
* @return 明细列表
*/
List<CustomProductItemEntity> selectByProductId(@Param("productId") Integer productId);
/**
* 根据 SKU 列表查询明细(含关联 custom_product_info 的 factory_id / factory_code / print_type)
*
* @param skus SKU 列表
* @return 明细列表(附加 factory_id, factory_code, info_print_type 字段)
*/
List<CustomProductItemEntity> selectBySkusWithInfo(@Param("skus") List<String> skus);
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.LogProductTemplateEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* LogProductTemplate Mapper
*
* @author Lizh
* @date 2026-06-12
*/
@Mapper
public interface LogProductTemplateMapper extends BaseMapper<LogProductTemplateEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.ProductTemplateItemEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* ProductTemplateItem Mapper
*
* @author Lizh
* @date 2026-06-12
*/
@Mapper
public interface ProductTemplateItemMapper extends BaseMapper<ProductTemplateItemEntity> {
/**
* 根据模板 ID 查询明细列表
*
* @param templateId 模板 ID
* @return 明细列表
*/
List<ProductTemplateItemEntity> selectByTemplateId(@Param("templateId") Integer templateId);
/**
* 根据 item_id(custom_product_item 表 ID)查询明细列表
*
* @param itemId custom_product_item 表 ID
* @return 明细列表
*/
List<ProductTemplateItemEntity> selectByItemId(@Param("itemId") Integer itemId);
/**
* 根据 item_id 列表批量查询明细(一次 IN 查询替代 N 次单查)
*
* @param itemIds custom_product_item 表 ID 列表
* @return 明细列表
*/
List<ProductTemplateItemEntity> selectByItemIds(@Param("itemIds") List<Integer> itemIds);
/**
* 根据 SKU 列表查询明细(含关联 custom_product_item)
*
* @param skus SKU 列表
* @return 明细列表
*/
List<ProductTemplateItemEntity> selectBySkus(@Param("skus") List<String> skus);
}
......@@ -3,6 +3,8 @@ package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.CustomProductItemEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* @author Lizh
* @version 0.01
......@@ -11,5 +13,14 @@ import com.jomalls.custom.service.IBaseService;
*/
public interface CustomProductItemDomainService extends IBaseService<CustomProductItemEntity> {
/**
* 根据商品 ID 查询明细列表
*/
List<CustomProductItemEntity> selectByProductId(Integer productId);
/**
* 根据 SKU 列表查询明细(含关联 custom_product_info 的工厂信息)
*/
List<CustomProductItemEntity> selectBySkusWithInfo(List<String> skus);
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.LogProductTemplateEntity;
import com.jomalls.custom.service.IBaseService;
/**
* LogProductTemplate 领域服务接口
*
* @author Lizh
* @date 2026-06-12
*/
public interface LogProductTemplateDomainService extends IBaseService<LogProductTemplateEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.ProductTemplateItemEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* ProductTemplateItem 领域服务接口
*
* @author Lizh
* @date 2026-06-12
*/
public interface ProductTemplateItemDomainService extends IBaseService<ProductTemplateItemEntity> {
/**
* 根据模板 ID 查询明细列表
*/
List<ProductTemplateItemEntity> selectByTemplateId(Integer templateId);
/**
* 根据 item_id(custom_product_item 表 ID)查询明细列表
*/
List<ProductTemplateItemEntity> selectByItemId(Integer itemId);
/**
* 根据 item_id 列表批量查询明细
*/
List<ProductTemplateItemEntity> selectByItemIds(List<Integer> itemIds);
}
......@@ -8,6 +8,8 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Lizh
......@@ -22,6 +24,18 @@ public class CustomProductItemDomainServiceImpl extends BaseServiceImpl<CustomPr
public CustomProductItemDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
@Override
public List<CustomProductItemEntity> selectByProductId(Integer productId) {
return baseMapper.selectByProductId(productId);
}
@Override
public List<CustomProductItemEntity> selectBySkusWithInfo(List<String> skus) {
if (skus == null || skus.isEmpty()) {
return List.of();
}
return baseMapper.selectBySkusWithInfo(skus);
}
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.entity.LogProductTemplateEntity;
import com.jomalls.custom.dal.mapper.LogProductTemplateMapper;
import com.jomalls.custom.domain.service.LogProductTemplateDomainService;
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;
/**
* LogProductTemplate 领域服务实现
*
* @author Lizh
* @date 2026-06-12
*/
@Service
public class LogProductTemplateDomainServiceImpl
extends BaseServiceImpl<LogProductTemplateMapper, LogProductTemplateEntity>
implements LogProductTemplateDomainService {
@Autowired
public LogProductTemplateDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
}
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.entity.ProductTemplateItemEntity;
import com.jomalls.custom.dal.mapper.ProductTemplateItemMapper;
import com.jomalls.custom.domain.service.ProductTemplateItemDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* ProductTemplateItem 领域服务实现
*
* @author Lizh
* @date 2026-06-12
*/
@Slf4j
@Service
public class ProductTemplateItemDomainServiceImpl
extends BaseServiceImpl<ProductTemplateItemMapper, ProductTemplateItemEntity>
implements ProductTemplateItemDomainService {
@Autowired
public ProductTemplateItemDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
@Override
public List<ProductTemplateItemEntity> selectByTemplateId(Integer templateId) {
return baseMapper.selectByTemplateId(templateId);
}
@Override
public List<ProductTemplateItemEntity> selectByItemId(Integer itemId) {
return baseMapper.selectByItemId(itemId);
}
@Override
public List<ProductTemplateItemEntity> selectByItemIds(List<Integer> itemIds) {
if (itemIds == null || itemIds.isEmpty()) {
return List.of();
}
return baseMapper.selectByItemIds(itemIds);
}
}
......@@ -70,6 +70,43 @@
update_time
</sql>
<!-- 根据商品 ID 查询明细列表 -->
<select id="selectByProductId" resultMap="customProductItemMap">
SELECT <include refid="tableColumns"/>
FROM custom_product_item
WHERE product_id = #{productId}
</select>
<!-- 根据 SKU 列表查询明细 -->
<select id="selectBySkusWithInfo" resultMap="customProductItemWithInfoMap">
SELECT
ci.id, ci.product_id, ci.sku, ci.sku_name, ci.image, ci.image_ary,
ci.property_cate_id1, ci.property_cate_id2, ci.property_cate_id3,
ci.property1_id, ci.property2_id, ci.property3_id,
ci.property_code1, ci.property_code2, ci.property_code3,
ci.option_enname1, ci.option_enname2, ci.option_enname3,
ci.custom_value1, ci.custom_value2, ci.custom_value3,
ci.factory_price, ci.sales_price, ci.sku_weight,
ci.print_type, ci.sort, ci.product_no, ci.size_type,
ci.create_time, ci.update_time,
cpi.factory_id AS info_factory_id,
cpi.factory_code AS info_factory_code,
cpi.print_type AS info_print_type
FROM custom_product_item ci
LEFT JOIN custom_product_info cpi ON ci.product_id = cpi.id
WHERE ci.sku IN
<foreach collection="skus" item="sku" open="(" separator="," close=")">
#{sku}
</foreach>
</select>
<!-- 带 product_info 扩展字段的 resultMap -->
<resultMap type="com.jomalls.custom.dal.entity.CustomProductItemEntity" id="customProductItemWithInfoMap" extends="customProductItemMap">
<result property="infoFactoryId" column="info_factory_id"/>
<result property="infoFactoryCode" column="info_factory_code"/>
<result property="infoPrintType" column="info_print_type"/>
</resultMap>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_item (product_id, sku, sku_name, image, image_ary, property_cate_id1, property_cate_id2, property_cate_id3, property1_id, property2_id, property3_id, property_code1, property_code2, property_code3, option_enname1, option_enname2, option_enname3, custom_value1, custom_value2, custom_value3, factory_price, sales_price, sku_weight, print_type, sort, product_no, size_type, create_time, update_time) VALUES
......
<?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.LogProductTemplateMapper">
<resultMap type="com.jomalls.custom.dal.entity.LogProductTemplateEntity" id="logProductTemplateMap">
<result property="id" column="id"/>
<result property="templateId" column="template_id"/>
<result property="employeeId" column="employee_id"/>
<result property="employeeAccount" column="employee_account"/>
<result property="description" column="description"/>
<result property="createTime" column="create_time"/>
</resultMap>
<sql id="tableColumns">
id, template_id, employee_id, employee_account, description, create_time
</sql>
</mapper>
<?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.ProductTemplateItemMapper">
<resultMap type="com.jomalls.custom.dal.entity.ProductTemplateItemEntity" id="productTemplateItemMap">
<result property="id" column="id"/>
<result property="templateId" column="template_id"/>
<result property="sku" column="sku"/>
<result property="skuName" column="sku_name"/>
<result property="image" column="image"/>
<result property="imageAry" column="image_ary"/>
<result property="xgtId" column="xgt_id"/>
<result property="propertyCateId1" column="property_cate_id1"/>
<result property="propertyCateId2" column="property_cate_id2"/>
<result property="propertyCateId3" column="property_cate_id3"/>
<result property="property1Id" column="property1_id"/>
<result property="property2Id" column="property2_id"/>
<result property="property3Id" column="property3_id"/>
<result property="propertyCode1" column="property_code1"/>
<result property="propertyCode2" column="property_code2"/>
<result property="propertyCode3" column="property_code3"/>
<result property="optionEnname1" column="option_enname1"/>
<result property="optionEnname2" column="option_enname2"/>
<result property="optionEnname3" column="option_enname3"/>
<result property="customValue1" column="custom_value1"/>
<result property="customValue2" column="custom_value2"/>
<result property="customValue3" column="custom_value3"/>
<result property="costPrice" column="cost_price"/>
<result property="salesPrice" column="sales_price"/>
<result property="printType" column="print_type"/>
<result property="sort" column="sort"/>
<result property="relationIds" column="relation_ids"/>
<result property="relation" column="relation"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="itemId" column="item_id"/>
<result property="itemSku" column="item_sku"/>
<result property="catalogNumber" column="catalog_number"/>
<result property="mssWidth" column="mss_width"/>
<result property="mssHeight" column="mss_height"/>
<result property="sizeType" column="size_type"/>
</resultMap>
<sql id="tableColumns">
id, template_id, sku, sku_name, image, image_ary, xgt_id,
property_cate_id1, property_cate_id2, property_cate_id3,
property1_id, property2_id, property3_id,
property_code1, property_code2, property_code3,
option_enname1, option_enname2, option_enname3,
custom_value1, custom_value2, custom_value3,
cost_price, sales_price, print_type, sort,
relation_ids, relation, create_time, update_time,
item_id, item_sku, catalog_number, mss_width, mss_height, size_type
</sql>
<!-- 根据模板 ID 查询明细列表 -->
<select id="selectByTemplateId" resultMap="productTemplateItemMap">
SELECT <include refid="tableColumns"/>
FROM product_template_item
WHERE template_id = #{templateId}
</select>
<!-- 根据 item_id 查询明细列表 -->
<select id="selectByItemId" resultMap="productTemplateItemMap">
SELECT <include refid="tableColumns"/>
FROM product_template_item
WHERE item_id = #{itemId}
</select>
<!-- 根据 item_id 列表批量查询明细 -->
<select id="selectByItemIds" resultMap="productTemplateItemMap">
SELECT <include refid="tableColumns"/>
FROM product_template_item
WHERE item_id IN
<foreach collection="itemIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 根据 SKU 列表查询 -->
<select id="selectBySkus" resultMap="productTemplateItemMap">
SELECT <include refid="tableColumns"/>
FROM product_template_item
WHERE sku IN
<foreach collection="skus" item="sku" open="(" separator="," close=")">
#{sku}
</foreach>
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO product_template_item (template_id, sku, sku_name, image, image_ary, xgt_id,
property_cate_id1, property_cate_id2, property_cate_id3,
property1_id, property2_id, property3_id,
property_code1, property_code2, property_code3,
option_enname1, option_enname2, option_enname3,
custom_value1, custom_value2, custom_value3,
cost_price, sales_price, print_type, sort,
relation_ids, relation, create_time, update_time,
item_id, item_sku, catalog_number, mss_width, mss_height, size_type) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.templateId}, #{item.sku}, #{item.skuName}, #{item.image}, #{item.imageAry}, #{item.xgtId},
#{item.propertyCateId1}, #{item.propertyCateId2}, #{item.propertyCateId3},
#{item.property1Id}, #{item.property2Id}, #{item.property3Id},
#{item.propertyCode1}, #{item.propertyCode2}, #{item.propertyCode3},
#{item.optionEnname1}, #{item.optionEnname2}, #{item.optionEnname3},
#{item.customValue1}, #{item.customValue2}, #{item.customValue3},
#{item.costPrice}, #{item.salesPrice}, #{item.printType}, #{item.sort},
#{item.relationIds}, #{item.relation}, #{item.createTime}, #{item.updateTime},
#{item.itemId}, #{item.itemSku}, #{item.catalogNumber}, #{item.mssWidth}, #{item.mssHeight}, #{item.sizeType})
</foreach>
</insert>
</mapper>
......@@ -9,7 +9,7 @@ import com.jomalls.custom.app.enums.CustomProductInfoStatusEnum;
import com.jomalls.custom.app.service.CustomProductInfoService;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.CraftCenterVO;
import com.jomalls.custom.app.vo.CraftCenterSnakeVO;
import com.jomalls.custom.app.vo.DbDiySnakeVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
......@@ -112,7 +112,7 @@ public class CustomProductInfoController {
@Operation(summary = "获取绑定的工艺", description = "获取商品绑定的工艺实体列表")
@GetMapping("/getCraftById")
public List<CraftCenterVO> getCraftById(@Parameter(description = "商品 ID") @RequestParam Integer id) {
public List<CraftCenterSnakeVO> getCraftById(@Parameter(description = "商品 ID") @RequestParam Integer id) {
return customProductInfoService.getCraftById(id);
}
......
package com.jomalls.custom.webapp.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductItemPageVO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import com.jomalls.custom.app.dto.UpdateSalesPriceSnakeDTO;
import com.jomalls.custom.app.service.CustomProductItemService;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
......@@ -12,18 +11,20 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
* 定制商品明细 Controller
* <p>
* 对齐 TS 项目 {@code ApiCustomProductItemController}。
*
* @author Lizh
* @version 0.01
* @description: Controller
* @date 2026-05-29 11:43:04
* @date 2026-06-12
*/
@Slf4j
@RestController
@Tag(name = "/api/v2/product/item", description = "Controller")
@Tag(name = "/api/v2/product/item", description = "定制商品明细")
@RequestMapping("/api/v2/product/item")
public class CustomProductItemController {
......@@ -31,74 +32,49 @@ public class CustomProductItemController {
private CustomProductItemService customProductItemService;
/**
* 列表查询接口
*
* @param customProductItemSnakeVO 条件model
* @return list集合
*/
@Operation(summary = "列表查询接口", description = "根据条件查询列表接口(不分页)")
@RequestMapping(value = "/list", method = RequestMethod.POST)
public List<CustomProductItemSnakeVO> list(@RequestBody CustomProductItemSnakeVO customProductItemSnakeVO) {
return customProductItemService.list(customProductItemSnakeVO);
}
/**
* 根据条件查询分页列表接口
*
* @param customProductItemPageVO 分页入参model
* @return 分页对象
*/
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/pageList", method = RequestMethod.POST)
public IPage<CustomProductItemSnakeVO> pageList(@RequestBody CustomProductItemPageVO customProductItemPageVO) {
return customProductItemService.pageList(customProductItemPageVO);
}
/**
* 根据主键id查询详情
* 根据商品 ID 获取明细集合
* <p>
* 对齐 TS {@code GET /getByProductId}
*
* @param id 主键
* @return 实体model
* @param productId 商品 ID
* @return 明细列表
*/
@Operation(summary = "根据主键id查询详情", description = "根据主键id查询详情")
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public CustomProductItemSnakeVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
return customProductItemService.info(id);
@Operation(summary = "根据商品ID获取明细集合", description = "根据商品ID获取明细集合")
@GetMapping("/getByProductId")
public List<CustomProductItemSnakeVO> getByProductId(
@Parameter(description = "商品ID", required = true)
@RequestParam("productId") Integer productId) {
return customProductItemService.getByProductId(productId);
}
/**
* 保存对象
* 更改商品销售价格
* <p>
* 对齐 TS {@code POST /updateSalesPrice}
*
* @param customProductItemSnakeVO 保存对象
* @param dto 更新请求
*/
@Operation(summary = "保存对象", description = "保存对象")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void save(@RequestBody @Valid CustomProductItemSnakeVO customProductItemSnakeVO) {
customProductItemService.save(customProductItemSnakeVO);
@Operation(summary = "更改商品销售价格", description = "更改商品销售价格")
@PostMapping("/updateSalesPrice")
public void updateSalesPrice(@RequestBody @Valid UpdateSalesPriceSnakeDTO dto) {
customProductItemService.updateSalesPrice(dto);
}
/**
* 根据id修改对象
* 根据 SKU 获取商品明细
* <p>
* 对齐 TS {@code GET /getBySkus}
*
* @param customProductItemSnakeVO 修改对象
* @param skus 逗号分隔的 SKU 列表
* @param namespace 可选用户 namespace
* @return 明细列表
*/
@Operation(summary = "根据id修改对象", description = "根据id修改对象")
@RequestMapping(value = "/updateById", method = RequestMethod.PUT)
public void updateById(@RequestBody CustomProductItemSnakeVO customProductItemSnakeVO) {
customProductItemService.updateById(customProductItemSnakeVO);
@Operation(summary = "根据SKU获取商品明细", description = "根据SKU获取商品明细")
@GetMapping("/getBySkus")
public List<CustomProductItemSnakeVO> getBySkus(
@Parameter(description = "SKU列表(逗号分隔)", required = true) @RequestParam("skus") String skus,
@Parameter(description = "用户namespace(可选)") @RequestParam(value = "namespace", required = false) String namespace) {
List<String> skuList = Arrays.asList(skus.split(","));
return customProductItemService.getBySkus(skuList, namespace);
}
/**
* 根据主键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) {
customProductItemService.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