Commit 43164dcf by Lizh

对照TS代码逻辑,迁移商品更新接口

parent 7b931415
package com.jomalls.custom.app.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* 组合创建商品 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code CreateCustomProductInfoDTO}。
* 包含商品基本信息 + 所有子实体列表,由 App Service 编排写入多张表。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Schema(description = "组合创建商品请求")
public class CustomProductInfoSaveDTO1 implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "商品名称")
@NotNull(message = "商品名称不能为空")
@Size(max = 255, message = "商品名称长度不能超过255个字符")
private String name;
@Schema(description = "title")
@Size(max = 255, message = "title长度不能超过255个字符")
private String title;
@Schema(description = "商品主图")
private String imgUrl;
@Schema(description = "商品类别ID")
private Integer categoryId;
@Schema(description = "重量(kg)")
private BigDecimal weight;
@Schema(description = "最小采购量")
private Integer purchasingMin;
@Schema(description = "工厂价(¥)")
private BigDecimal factoryPrice;
@Schema(description = "销售价(¥)")
private BigDecimal salesPrice;
@Schema(description = "销售价最高价(¥)")
private BigDecimal salesPriceMax;
@Schema(description = "状态:1待上架 10已上架 20已下架 30待下架 40已作废")
private Integer status;
@Schema(description = "商品属性分类ID 1")
private Integer property1CateId;
@Schema(description = "商品属性分类ID 2")
private Integer property2CateId;
@Schema(description = "商品属性分类ID 3")
private Integer property3CateId;
@Schema(description = "商品属性英文名称 1")
private String property1Enname;
@Schema(description = "商品属性英文名称 2")
private String property2Enname;
@Schema(description = "商品属性英文名称 3")
private String property3Enname;
@Schema(description = "颜色图(JSON字符串)")
private String colorImages;
@Schema(description = "材质")
private String material;
@Schema(description = "印花类型:0满印 1局部印")
private Integer printType;
@Schema(description = "货号")
@Size(max = 20, message = "货号长度不能超过20个字符")
private String productNo;
@Schema(description = "产地编码")
private String originCode;
@Schema(description = "产地中文名")
private String originNameCn;
@Schema(description = "产地英文名")
private String originNameEn;
@Schema(description = "币种编码")
private String currencyCode;
@Schema(description = "币种名称")
private String currencyName;
@Schema(description = "产品类型:platform/customer")
private String productType;
@Schema(description = "工厂ID")
private Integer factoryId;
@Schema(description = "是否九猫处理")
private Integer processing;
@Schema(description = "排序")
private Integer sort;
// ==================== 子实体列表 ====================
@Schema(description = "SKU 子项列表")
private List<CustomProductItemSnakeDTO> productList;
@Schema(description = "普通图片列表")
private List<CustomProductImageSnakeDTO> imageList;
@Schema(description = "尺码图片列表(type=1)")
private List<CustomProductImageSnakeDTO> sizeList;
@Schema(description = "SKU 属性集合")
private List<CustomProductInfoPropertyDTO> skuProperties;
@Schema(description = "普通属性集合")
private List<CustomProductInfoPropertyDTO> normalProperties;
@Schema(description = "工厂价格关联列表")
private List<FactoryPriceRelDTO> factoryPriceList;
@Schema(description = "工厂 ID 列表")
private List<Integer> factoryIds;
@Schema(description = "仓库 ID 列表")
private List<Integer> warehouseIds;
@Schema(description = "DIY 用户 ID 列表")
private List<Integer> diyUserIds;
@Schema(description = "工艺 ID 列表")
private List<Integer> craftIds;
@Schema(description = "工厂价格区间关联列表")
private List<FactoryPriceIntervalRelDTO> factoryPriceIntervalList;
@Schema(description = "英文备注")
private String remark;
@Schema(description = "中文备注")
private String cnRemark;
}
package com.jomalls.custom.app.dto;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Digits;
......@@ -135,10 +136,24 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
private Integer status;
/**
* 是否九猫处理
* 是否九猫处理(0=否 1=是 2=不确定/未设置)
* <p>
* 兼容前端发送 Boolean(true→1, false→0)和 Number(0/1/2)。
*/
@Schema(description = "是否九猫处理")
private Boolean processing;
@Schema(description = "是否九猫处理(0=否 1=是 2=未设置,也支持 true/false)")
private Integer processing;
/** Jackson 兼容 Boolean→Integer 反序列化 */
@JsonSetter("processing")
public void setProcessingValue(Object value) {
if (value instanceof Boolean) {
this.processing = (Boolean) value ? 1 : 0;
} else if (value instanceof Number) {
this.processing = ((Number) value).intValue();
} else {
this.processing = null;
}
}
/**
* 英文备注
......@@ -180,7 +195,7 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
* 工厂价格关联列表
*/
@Schema(description = "工厂价格关联列表")
private List<FactoryPriceRelDTO> factoryPriceList;
private List<FactoryPriceRelSnakeDTO> factoryPriceList;
/**
* SKU 属性集合
......@@ -271,7 +286,7 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
* 工厂价格区间关联列表
*/
@Schema(description = "工厂价格区间关联列表")
private List<FactoryPriceIntervalRelDTO> factoryPriceIntervalList;
private List<FactoryPriceIntervalRelSnakeDTO> factoryPriceIntervalList;
/**
* DIY 用户 ID 列表(绑定客户)
......@@ -296,8 +311,7 @@ public class CustomProductInfoSnakeDTO extends PageRequest {
@Schema(description = "工厂 ID 列表")
private List<Integer> factoryIds;
// ==================== ERP 专用查询字段(对齐 TS ERPQueryProductInfoDTO) ====================
/** 以下为ERP 专用查询字段 */
@Schema(description = "DIY 模板 SKU 筛选(ERP)")
private String diySku;
......
package com.jomalls.custom.app.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
......@@ -15,12 +16,12 @@ import java.util.List;
* 继承 SaveDTO 的字段,额外增加变更列表用于差异化更新。
*
* @author Lizh
* @date 2026-06-06
* @date 2026-06-10
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Schema(description = "组合更新商品请求")
public class CustomProductInfoUpdateDTO extends CustomProductInfoSaveDTO1 implements Serializable {
public class CustomProductInfoUpdateSnakeDTO extends CustomProductInfoSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -28,17 +29,23 @@ public class CustomProductInfoUpdateDTO extends CustomProductInfoSaveDTO1 implem
@Schema(description = "商品 ID(必填)")
private Integer id;
@Schema(description = "子项变更列表(增/删/改)", implementation = ProductChangeDTO.class)
private ProductChangeDTO productChange;
@Schema(description = "子项变更列表(增/删/改)", implementation = ProductChangeSnakeDTO.class)
private ProductChangeSnakeDTO productChange;
@JsonProperty("factoryPriceChange")
@Schema(description = "工厂价格变更列表(增/删/改)", implementation = ProductFactoryPriceChangeDTO.class)
private ProductFactoryPriceChangeDTO productFactoryPriceChange;
private ProductFactoryPriceChangeDTO factoryPriceChange;
@JsonProperty("imageChange")
@Schema(description = "图片变更列表(增/删/改)", implementation = ProductImageChangeDTO.class)
private ProductImageChangeDTO productImageChange;
private ProductImageChangeDTO imageChange;
@JsonProperty("sizeChange")
@Schema(description = "尺码图变更列表(增/删/改)", implementation = ProductImageChangeDTO.class)
private ProductImageChangeDTO productSizeChange;
private ProductImageChangeDTO sizeChange;
@Schema(description = "DIY 用户 ID 列表(绑定客户)")
private List<Integer> diyUserIds;
/**
* 工厂价格变更 DTO
......@@ -46,13 +53,14 @@ public class CustomProductInfoUpdateDTO extends CustomProductInfoSaveDTO1 implem
@Data
@Schema(description = "工厂价格变更")
public static class ProductFactoryPriceChangeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "新增列表")
private List<FactoryPriceRelDTO> addList;
private List<FactoryPriceRelSnakeDTO> addList;
@Schema(description = "修改列表")
private List<FactoryPriceRelDTO> updateList;
private List<FactoryPriceRelSnakeDTO> updateList;
@Schema(description = "删除 ID 列表")
private List<Integer> removeList;
......@@ -64,11 +72,15 @@ public class CustomProductInfoUpdateDTO extends CustomProductInfoSaveDTO1 implem
@Data
@Schema(description = "图片变更")
public static class ProductImageChangeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "新增列表")
private List<CustomProductImageSnakeDTO> addList;
@Schema(description = "修改列表")
private List<CustomProductImageSnakeDTO> updateList;
@Schema(description = "删除 ID 列表")
private List<Integer> removeList;
}
......
......@@ -6,6 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
......@@ -15,23 +16,24 @@ import java.math.BigDecimal;
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code FactoryPriceIntervalRelDTO}。
*
* @author Lizh
* @date 2026-06-06
* @date 2026-06-10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工厂价格区间关联")
public class FactoryPriceIntervalRelDTO implements Serializable {
public class FactoryPriceIntervalRelSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "币种编码")
private String currencyCode;
private String currency_code;
@Schema(description = "系统成本最低价")
private BigDecimal priceMin;
private BigDecimal price_min;
@Schema(description = "系统成本最高价")
private BigDecimal priceMax;
private BigDecimal price_max;
}
......@@ -16,36 +16,36 @@ import java.math.BigDecimal;
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code CreateFactoryPriceRelDTO}。
*
* @author Lizh
* @date 2026-06-06
* @date 2026-06-10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工厂价格关联")
public class FactoryPriceRelDTO implements Serializable {
public class FactoryPriceRelSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "子项 ID(custom_product_item 的 id)")
private Integer itemId;
private Integer item_id;
@Schema(description = "子项 SKU")
private String itemSku;
private String item_sku;
@Schema(description = "工厂 ID")
private Integer factoryId;
private Integer factory_id;
@Schema(description = "工厂价格")
private BigDecimal factoryPrice;
private BigDecimal factory_price;
@Schema(description = "销售价格")
private BigDecimal salesPrice;
private BigDecimal sales_price;
@Schema(description = "工厂币种编码")
private String factoryCurrencyCode;
private String factory_currency_code;
@Schema(description = "销售币种编码")
private String salesCurrencyCode;
private String sales_currency_code;
}
......@@ -14,7 +14,7 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "商品变更Dto")
public class ProductChangeDTO implements Serializable {
public class ProductChangeSnakeDTO implements Serializable {
@Schema(description = "添加集合", implementation = CustomProductItemSnakeDTO.class)
private List<CustomProductItemSnakeDTO> addList;
......
......@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelPageVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelSnakeVO;
import java.util.List;
......@@ -17,10 +17,10 @@ public interface CustomProductFactoryPriceRelService {
/**
* 列表查询接口
*
* @param customProductFactoryPriceRelVO 条件model
* @param customProductFactoryPriceRelSnakeVO 条件model
* @return list集合
*/
List<CustomProductFactoryPriceRelVO> list(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO);
List<CustomProductFactoryPriceRelSnakeVO> list(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO);
/**
* 根据条件查询分页列表接口
......@@ -28,7 +28,7 @@ public interface CustomProductFactoryPriceRelService {
* @param customProductFactoryPriceRelPageVO 分页入参model
* @return 分页对象
*/
IPage<CustomProductFactoryPriceRelVO> pageList(CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO);
IPage<CustomProductFactoryPriceRelSnakeVO> pageList(CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO);
/**
* 根据id查询详情
......@@ -36,21 +36,21 @@ public interface CustomProductFactoryPriceRelService {
* @param id 主键
* @return 实体model
*/
CustomProductFactoryPriceRelVO info(Integer id);
CustomProductFactoryPriceRelSnakeVO info(Integer id);
/**
* 保存对象
*
* @param customProductFactoryPriceRelVO 保存对象
* @param customProductFactoryPriceRelSnakeVO 保存对象
*/
void save(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO);
void save(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO);
/**
* 根据id修改对象
*
* @param customProductFactoryPriceRelVO 修改对象
* @param customProductFactoryPriceRelSnakeVO 修改对象
*/
void updateById(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO);
void updateById(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO);
/**
* 根据主键ID进行删除
......
......@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
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.CustomProductInfoUpdateDTO;
import com.jomalls.custom.app.dto.CustomProductInfoUpdateSnakeDTO;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.DbDiyVO;
......@@ -33,7 +33,7 @@ public interface CustomProductInfoService {
*
* @param dto 组合更新 DTO
*/
void updateFull(CustomProductInfoUpdateDTO dto);
void updateFull(CustomProductInfoUpdateSnakeDTO dto);
/**
* 根据 ID 或 SKU 加载商品完整数据(并行单表查询后在 Java 层组合)
......
......@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelPageVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelSnakeVO;
import com.jomalls.custom.app.service.CustomProductFactoryPriceRelService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
......@@ -37,34 +37,34 @@ public class CustomProductFactoryPriceRelServiceImpl implements CustomProductFac
}
@Override
public List<CustomProductFactoryPriceRelVO> list(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
public List<CustomProductFactoryPriceRelSnakeVO> list(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
QueryWrapper<CustomProductFactoryPriceRelEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<CustomProductFactoryPriceRelEntity> list = customProductFactoryPriceRelDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductFactoryPriceRelVO.class)).collect(Collectors.toList());
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductFactoryPriceRelSnakeVO.class)).collect(Collectors.toList());
}
@Override
public IPage<CustomProductFactoryPriceRelVO> pageList(CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO) {
public IPage<CustomProductFactoryPriceRelSnakeVO> pageList(CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO) {
CustomAsserts.nonNull(customProductFactoryPriceRelPageVO, "分页查询参数不能为空");
QueryWrapper<CustomProductFactoryPriceRelEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<CustomProductFactoryPriceRelEntity> page = customProductFactoryPriceRelDomainService.selectPage(queryWrapper, customProductFactoryPriceRelPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductFactoryPriceRelVO.class));
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductFactoryPriceRelSnakeVO.class));
}
@Override
public CustomProductFactoryPriceRelVO info(Integer id) {
public CustomProductFactoryPriceRelSnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductFactoryPriceRelEntity customProductFactoryPriceRel = customProductFactoryPriceRelDomainService.getById(id);
return BeanMapper.mapper().convert(customProductFactoryPriceRel, CustomProductFactoryPriceRelVO.class);
return BeanMapper.mapper().convert(customProductFactoryPriceRel, CustomProductFactoryPriceRelSnakeVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
CustomAsserts.nonNull(customProductFactoryPriceRelVO, "实体对象不能为空");
CustomProductFactoryPriceRelEntity customProductFactoryPriceRelEntity = BeanMapper.mapper().convert(customProductFactoryPriceRelVO, CustomProductFactoryPriceRelEntity.class);
public void save(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
CustomAsserts.nonNull(customProductFactoryPriceRelSnakeVO, "实体对象不能为空");
CustomProductFactoryPriceRelEntity customProductFactoryPriceRelEntity = BeanMapper.mapper().convert(customProductFactoryPriceRelSnakeVO, CustomProductFactoryPriceRelEntity.class);
try {
customProductFactoryPriceRelDomainService.save(customProductFactoryPriceRelEntity);
} catch (DuplicateKeyException e) {
......@@ -75,9 +75,9 @@ public class CustomProductFactoryPriceRelServiceImpl implements CustomProductFac
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
CustomAsserts.nonNull(customProductFactoryPriceRelVO, "实体对象不能为空");
CustomProductFactoryPriceRelEntity customProductFactoryPriceRel = BeanMapper.mapper().convert(customProductFactoryPriceRelVO, CustomProductFactoryPriceRelEntity.class);
public void updateById(CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
CustomAsserts.nonNull(customProductFactoryPriceRelSnakeVO, "实体对象不能为空");
CustomProductFactoryPriceRelEntity customProductFactoryPriceRel = BeanMapper.mapper().convert(customProductFactoryPriceRelSnakeVO, CustomProductFactoryPriceRelEntity.class);
try {
customProductFactoryPriceRelDomainService.updateById(customProductFactoryPriceRel);
} catch (DuplicateKeyException e) {
......
......@@ -70,9 +70,9 @@ public class DiyUserServiceImpl implements DiyUserService {
// 工厂价格关联的 sales_price(对齐 TS:348-352)
if (vo.getFactoryPriceList() != null) {
for (CustomProductFactoryPriceRelVO fp : vo.getFactoryPriceList()) {
if (fp.getSalesPrice() != null) {
fp.setSalesPrice(fp.getSalesPrice().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
for (CustomProductFactoryPriceRelSnakeVO fp : vo.getFactoryPriceList()) {
if (fp.getSales_price() != null) {
fp.setSales_price(fp.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
}
}
......
......@@ -22,7 +22,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "VO")
public class CustomProductFactoryPriceRelVO implements Serializable {
public class CustomProductFactoryPriceRelSnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -36,61 +36,61 @@ public class CustomProductFactoryPriceRelVO implements Serializable {
* custom_product_info表id
*/
@Schema(description = "custom_product_info表id")
private Integer productId;
private Integer product_id;
/**
* custom_product_item表id
*/
@Schema(description = "custom_product_item表id")
private Integer itemId;
private Integer item_id;
/**
* custom_product_item表sku
*/
@Schema(description = "custom_product_item表sku")
private String itemSku;
private String item_sku;
/**
* db_diy表id
*/
@Schema(description = "db_diy表id")
private Integer factoryId;
private Integer factory_id;
/**
* 工厂价格
*/
@Schema(description = "工厂价格")
private BigDecimal factoryPrice;
private BigDecimal factory_price;
/**
* 销售价
*/
@Schema(description = "销售价")
private BigDecimal salesPrice;
private BigDecimal sales_price;
/**
* 工厂币种
*/
@Schema(description = "工厂币种")
private String factoryCurrencyCode;
private String factory_currency_code;
/**
* 售卖币种
*/
@Schema(description = "售卖币种")
private String salesCurrencyCode;
private String sales_currency_code;
/**
*
*/
@Schema(description = "")
private Date createTime;
private Date create_time;
/**
*
*/
@Schema(description = "")
private Date updateTime;
private Date update_time;
}
......@@ -153,7 +153,7 @@ public class CustomProductInfoSnakeVO implements Serializable {
private ProductRemarkVO productCnRemark;
@Schema(description = "工厂价格关联列表")
private List<CustomProductFactoryPriceRelVO> factoryPriceList;
private List<CustomProductFactoryPriceRelSnakeVO> factoryPriceList;
@Schema(description = "尺码图片列表(type=1)")
private List<CustomProductImageSnakeVO> sizeList;
......
......@@ -10,6 +10,7 @@ import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* Model
......@@ -242,5 +243,8 @@ public class CustomProductInfoVO implements Serializable {
@Schema(description = "默认模SKU")
private String diySku;
@Schema(description = "绑定的DIY模板是否已上架(ERP专用)")
private Boolean diyShelfStatus;
}
......@@ -9,6 +9,7 @@ import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* Model
......@@ -319,5 +320,8 @@ public class DbDiyVO implements Serializable {
@Schema(description = "模备注")
private String diyRemark;
@Schema(description = "效果图列表")
private List<DbDiyXiaoguotuVO> xiaoguotuList;
}
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;
/**
* DIY 效果图 VO
*
* @author Lizh
* @date 2026-06-10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "DIY 效果图")
public class DbDiyXiaoguotuVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "主键")
private Integer id;
@Schema(description = "标题")
private String title;
@Schema(description = "排序")
private Integer idx;
@Schema(description = "效果图主图")
private String imgUrl;
@Schema(description = "PSD 链接")
private String psdUrl;
@Schema(description = "颜色 ID")
private Integer colorId;
@Schema(description = "宽度")
private Float width;
@Schema(description = "高度")
private Float height;
@Schema(description = "分辨率")
private Integer dpi;
@Schema(description = "关联的 DIY 模板 ID")
private Integer diyId;
@Schema(description = "状态:1 正常 0 禁用")
private Integer status;
}
......@@ -37,7 +37,7 @@ public class LogCustomProductEntity implements Serializable {
* 操作人id
*/
@TableField("employee_id")
private Integer employeeId;
private Long employeeId;
/**
* 操作人账号
*/
......
......@@ -5,6 +5,8 @@ import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Lizh
* @version 0.01
......@@ -21,4 +23,16 @@ public interface CustomProductInfoMapper extends BaseMapper<CustomProductInfoEnt
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity selectBySku(@Param("sku") String sku);
/**
* ERP 权限过滤:查询指定用户可见的商品 ID 列表
* <p>
* 对齐 TS erpPage 中的 native SQL(TS:686-706)。
* 产品可见条件:(用户已绑定 OR 产品未绑定任何人) AND 用户未被拉黑。
* 使用单次 JOIN 查询避免 N+1 性能问题。
*
* @param userId 当前用户 ID
* @return 符合条件的商品 ID 列表(已去重)
*/
List<Integer> selectIdsByErpPermission(@Param("userId") Integer userId);
}
......@@ -3,6 +3,8 @@ package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.CustomProductInfoEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* @author Lizh
* @version 0.01
......@@ -18,5 +20,13 @@ public interface CustomProductInfoDomainService extends IBaseService<CustomProdu
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity getBySku(String sku);
/**
* ERP 权限过滤:查询指定用户可见的商品 ID 列表
*
* @param userId 当前用户 ID
* @return 符合条件的商品 ID 列表(已去重)
*/
List<Integer> selectIdsByErpPermission(Integer userId);
}
......@@ -9,6 +9,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
......@@ -28,4 +30,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr
public CustomProductInfoEntity getBySku(String sku) {
return baseMapper.selectBySku(sku);
}
@Override
public List<Integer> selectIdsByErpPermission(Integer userId) {
return baseMapper.selectIdsByErpPermission(userId);
}
}
\ No newline at end of file
......@@ -34,9 +34,9 @@
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_factory_price_rel (product_id, item_id, item_sku, factory_id, factory_price, sales_price, factory_currency_code, sales_currency_code, create_time, update_time) VALUES
INSERT INTO custom_product_factory_price_rel (product_id, item_id, item_sku, factory_id, factory_price, sales_price, factory_currency_code, sales_currency_code) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.itemId}, #{item.itemSku}, #{item.factoryId}, #{item.factoryPrice}, #{item.salesPrice}, #{item.factoryCurrencyCode}, #{item.salesCurrencyCode}, #{item.createTime}, #{item.updateTime})
(#{item.productId}, #{item.itemId}, #{item.itemSku}, #{item.factoryId}, #{item.factoryPrice}, #{item.salesPrice}, #{item.factoryCurrencyCode}, #{item.salesCurrencyCode})
</foreach>
</insert>
</mapper>
......@@ -24,9 +24,9 @@
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_image (product_id, image_url, sort, type, create_time) VALUES
INSERT INTO custom_product_image (product_id, image_url, sort, type) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.imageUrl}, #{item.sort}, #{item.type}, #{item.createTime})
(#{item.productId}, #{item.imageUrl}, #{item.sort}, #{item.type})
</foreach>
</insert>
</mapper>
......@@ -90,6 +90,21 @@
LIMIT 1
</select>
<!-- ERP 权限过滤:查询用户可见的商品 ID 列表 -->
<!-- 对齐 TS erpPage native SQL(TS:686-706)
产品可见条件:
(rel.diy_user_id = :userId OR rel.diy_user_id IS NULL) — 用户已绑定 OR 产品未绑定任何人
AND
(bl.diy_user_id != :userId OR bl.diy_user_id IS NULL) — 用户未被拉黑 -->
<select id="selectIdsByErpPermission" resultType="java.lang.Integer">
SELECT DISTINCT info.id
FROM custom_product_info info
LEFT JOIN custom_product_diy_user_rel rel ON info.id = rel.product_id
LEFT JOIN custom_product_blacklist bl ON info.id = bl.product_id
WHERE (bl.diy_user_id != #{userId} OR bl.diy_user_id IS NULL)
AND (rel.diy_user_id = #{userId} OR rel.diy_user_id IS NULL)
</select>
<!-- 批量插入 -->
<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
......
......@@ -9,6 +9,7 @@ import com.jomalls.custom.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
......@@ -20,10 +21,21 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
public class CommonExceptionHandlerAdvice {
/**
* JSON 反序列化失败(请求参数格式不匹配)
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<R<Object>> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.debug("[ JSON反序列化失败 ] {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(R.fail(CodeEnum.FAIL.getCode(), "请求参数格式错误: " + e.getLocalizedMessage()));
}
/**
* token验证失败(返回401 未登录或登录已过期)
*/
@ExceptionHandler(InvalidTokenException.class)
public ResponseEntity<R<Object>> handleInvalidTokenException(InvalidTokenException e) {
log.debug("[ Token验证失败 ] {}", e.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(R.fail(CodeEnum.UNAUTHORIZED.getCode(), e.getMessage()));
}
......@@ -33,6 +45,7 @@ public class CommonExceptionHandlerAdvice {
*/
@ExceptionHandler(PermissionDeniedException.class)
public ResponseEntity<R<Object>> handlePermissionDeniedException(PermissionDeniedException e) {
log.debug("[ 权限拒绝 ] {}", e.getMessage());
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(R.fail(CodeEnum.FORBIDDEN.getCode(), e.getMessage()));
}
......@@ -42,8 +55,9 @@ public class CommonExceptionHandlerAdvice {
*/
@ExceptionHandler(ServiceException.class)
public ResponseEntity<R<Object>> handleServiceException(ServiceException e) {
log.debug("[ 业务异常 ] {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(R.fail(e.getCode(), e.getMessage()));
.body(R.fail(e.getMessage()));
}
/**
......@@ -51,6 +65,7 @@ public class CommonExceptionHandlerAdvice {
*/
@ExceptionHandler(RemoteServiceException.class)
public ResponseEntity<R<Object>> handleRemoteServiceException(RemoteServiceException e) {
log.debug("[ 远程服务异常 ] status={}, {}", e.getStatusCode(), e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(R.fail(e.getStatusCode(), e.getMessage()));
}
......@@ -60,6 +75,7 @@ public class CommonExceptionHandlerAdvice {
*/
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<R<Object>> handleRuntimeException(Exception e) {
log.debug("[ 运行时异常 ] {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(R.fail(e.getMessage()));
}
......@@ -69,6 +85,7 @@ public class CommonExceptionHandlerAdvice {
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<R<Object>> handleException(Exception e) {
log.debug("[ 未捕获异常 ] {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(R.fail(CodeEnum.FAIL.getCode(), e.getMessage()));
}
......
......@@ -26,10 +26,6 @@ mybatis-plus.mapper-locations=classpath*:mapper/**/*.xml
mybatis-plus.type-aliases-package=com.jomalls.custom.domain.entity
mybatis-plus.configuration.call-setters-on-nulls=true
## 数据版本控制
data.version.control.switch=false
default.scp.data.version=1.0
## 时区配置
TZ=Asia/Shanghai
......
......@@ -103,7 +103,7 @@
<logger name="org.springdoc" level="WARN"/>
<!-- ==================== 根配置 ==================== -->
<root level="INFO">
<root level="DEBUG">
<appender-ref ref="console"/>
<appender-ref ref="file_info"/>
<appender-ref ref="file_warn"/>
......
......@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelPageVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelVO;
import com.jomalls.custom.app.vo.CustomProductFactoryPriceRelSnakeVO;
import com.jomalls.custom.app.service.CustomProductFactoryPriceRelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
......@@ -33,13 +33,13 @@ public class CustomProductFactoryPriceRelController {
/**
* 列表查询接口
*
* @param customProductFactoryPriceRelVO 条件model
* @param customProductFactoryPriceRelSnakeVO 条件model
* @return list集合
*/
@Operation(summary = "列表查询接口", description = "根据条件查询列表接口(不分页)")
@RequestMapping(value = "/list", method = RequestMethod.POST)
public List<CustomProductFactoryPriceRelVO> list(@RequestBody CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
return customProductFactoryPriceRelService.list(customProductFactoryPriceRelVO);
public List<CustomProductFactoryPriceRelSnakeVO> list(@RequestBody CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
return customProductFactoryPriceRelService.list(customProductFactoryPriceRelSnakeVO);
}
/**
......@@ -50,7 +50,7 @@ public class CustomProductFactoryPriceRelController {
*/
@Operation(summary = "分页列表接口", description = "根据条件查询分页列表接口")
@RequestMapping(value = "/pageList", method = RequestMethod.POST)
public IPage<CustomProductFactoryPriceRelVO> pageList(@RequestBody CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO) {
public IPage<CustomProductFactoryPriceRelSnakeVO> pageList(@RequestBody CustomProductFactoryPriceRelPageVO customProductFactoryPriceRelPageVO) {
return customProductFactoryPriceRelService.pageList(customProductFactoryPriceRelPageVO);
}
......@@ -63,31 +63,31 @@ public class CustomProductFactoryPriceRelController {
*/
@Operation(summary = "根据主键id查询详情", description = "根据主键id查询详情")
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public CustomProductFactoryPriceRelVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
public CustomProductFactoryPriceRelSnakeVO info(@Parameter(description = "主键id", required = true) @PathVariable("id") Integer id) {
return customProductFactoryPriceRelService.info(id);
}
/**
* 保存对象
*
* @param customProductFactoryPriceRelVO 保存对象
* @param customProductFactoryPriceRelSnakeVO 保存对象
*/
@Operation(summary = "保存对象", description = "保存对象")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void save(@RequestBody @Valid CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
customProductFactoryPriceRelService.save(customProductFactoryPriceRelVO);
public void save(@RequestBody @Valid CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
customProductFactoryPriceRelService.save(customProductFactoryPriceRelSnakeVO);
}
/**
* 根据id修改对象
*
* @param customProductFactoryPriceRelVO 修改对象
* @param customProductFactoryPriceRelSnakeVO 修改对象
*/
@Operation(summary = "根据id修改对象", description = "根据id修改对象")
@RequestMapping(value = "/updateById", method = RequestMethod.PUT)
public void updateById(@RequestBody CustomProductFactoryPriceRelVO customProductFactoryPriceRelVO) {
customProductFactoryPriceRelService.updateById(customProductFactoryPriceRelVO);
public void updateById(@RequestBody CustomProductFactoryPriceRelSnakeVO customProductFactoryPriceRelSnakeVO) {
customProductFactoryPriceRelService.updateById(customProductFactoryPriceRelSnakeVO);
}
/**
......
......@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
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.CustomProductInfoUpdateDTO;
import com.jomalls.custom.app.dto.CustomProductInfoUpdateSnakeDTO;
import com.jomalls.custom.app.enums.CustomProductInfoStatusEnum;
import com.jomalls.custom.app.service.CustomProductInfoService;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
......@@ -51,7 +51,7 @@ public class CustomProductInfoController {
@Operation(summary = "组合更新商品", description = "事务内处理主表及子表的增/删/改差异")
@PostMapping("/update")
public void update(@RequestBody @Valid CustomProductInfoUpdateDTO dto) {
public void update(@RequestBody @Valid CustomProductInfoUpdateSnakeDTO dto) {
customProductInfoService.updateFull(dto);
}
......
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