Commit 7b931415 by Lizh

按照ts代码逻辑迁移商品保存与根据商品id或sku查询商品详情接口

parent 627d26f8
package com.jomalls.custom.app.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 批量加入黑名单 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code AddBlackListDTO}。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Schema(description = "批量加入黑名单请求")
public class AddBlackListDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "商品 ID 列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "商品 ID 列表不能为空")
private List<Integer> productIds;
@Schema(description = "DIY 用户 ID 列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "DIY 用户 ID 列表不能为空")
private List<Integer> diyUserIds;
}
package com.jomalls.custom.app.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 批量绑定/解绑 DIY 用户 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code BindDiyUserDTO}。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Schema(description = "批量绑定DIY用户请求")
public class BindDiyUserDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "商品 ID 列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "商品 ID 列表不能为空")
private List<Integer> productIds;
@Schema(description = "DIY 用户 ID 列表(传空列表表示解绑所有)", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Integer> diyUserIds;
}
......@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
*
......@@ -20,7 +19,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "图片Dto")
public class CustomProductImageDTO implements Serializable {
public class CustomProductImageSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -34,13 +33,13 @@ public class CustomProductImageDTO implements Serializable {
* 商品ID
*/
@Schema(description = "商品ID")
private Integer productId;
private Integer product_id;
/**
* 图片地址
*/
@Schema(description = "图片地址")
private String imageUrl;
private String image_url;
/**
* 排序
......@@ -54,11 +53,4 @@ public class CustomProductImageDTO implements Serializable {
@Schema(description = "类型 0普通图片 1尺码图")
private Integer type;
/**
*
*/
@Schema(description = "")
private Date createTime;
}
package com.jomalls.custom.app.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.NotBlank;
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;
/**
* Entity
*
* @author huanying
* @date 2026-06-02 19:07:12
*/
@Data
public class CustomProductInfoDTO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Integer id;
/**
* sku
*/
@Schema(description = "sku", example = "JM260602001")
@Size(max = 20, message = "sku长度不能超过20个字符")
private String sku;
/**
*
*/
@Schema(description = "title", example = "")
@Size(max = 255, message = "title长度不能超过255个字符")
private String title;
/**
* 商品名称
*/
@Schema(description = "name", example = "")
@NotNull(message= "商品名称不能为空")
@Size(max = 255, message = "sku长度不能超过255个字符")
private String name;
/**
* 商品主图
*/
@Schema(description = "图片主图", example = "")
@NotBlank(message = "商品主图不能为空")
@Size(max = 255, message = "图片主图长度不能超过255个字符")
private String imgUrl;
/**
* 商品类别ID
*/
@Schema(description = "商品类别ID", example = "")
@NotBlank(message = "商品类别不能为空")
private Integer category_id;
/**
* 重量kg
*/
@Schema(description = "重量(kg)", example = "")
@NotNull(message= "重量不能为空")
@Digits(integer = 15, fraction = 2, message = "重量(kg)数值最多保留2位小数")
private BigDecimal weight;
/**
* 最小采购量
*/
@Schema(description = "最小采购量", example = "")
private Integer purchasingMin;
/**
* 工厂价(¥)
*/
@Schema(description = "工厂价(¥)", example = "")
@Digits(integer = 15, fraction = 2, message = "工厂价数值最多保留2位小数")
private BigDecimal factoryPrice;
/**
* 销售价(¥)
*/
@Schema(description = "销售价(¥)", example = "")
@Digits(integer = 15, fraction = 2, message = "销售价数值最多保留2位小数")
private BigDecimal salesPrice;
/**
* 销售价最大值(¥)
*/
@Schema(description = "销售价最高价(¥)", example = "")
@Digits(integer = 15, fraction = 2, message = "销售价最高价数值最多保留2位小数")
private BigDecimal salesPriceMax;
/**
* 1待上架 10已上架 20已下架 30待下架 40已作废
*/
@Schema(description = "状态:1待上架 10已上架 20已下架 30待下架 40已作废", example = "")
private Integer status;
/**
* 挂起前的状态
*/
private Integer preSuspendStatus;
/**
*
*/
@Schema(description = "商品属性ID 1", example = "")
@NotNull(message= "商品属性不能为空")
private Integer property1CateId;
/**
*
*/
@Schema(description = "商品属性ID 2", example = "")
private Integer property2CateId;
/**
*
*/
@Schema(description = "商品属性ID 3", example = "")
private Integer property3CateId;
/**
*
*/
@Schema(description = "商品属性英文名称 1", example = "")
@NotNull(message= "商品属性名不能为空")
private String property1Enname;
/**
*
*/
@Schema(description = "商品属性英文名称 2", example = "")
private String property2Enname;
/**
*
*/
@Schema(description = "商品属性英文名称 3", example = "")
private String property3Enname;
/**
* 颜色图
*/
@Schema(description = "颜色图", example = "")
private String colorImages;
/**
* 材质
*/
@Schema(description = "材质", example = "")
@NotNull(message= "材质不能为空")
private String material;
/**
* 印花类型 0满印 1局部印
*/
@Schema(description = "印花类型 0满印 1局部印", example = "")
private Integer printType;
/**
* 货号
*/
@Schema(description = "货号", example = "")
@Size(max = 20, message = "货号长度不能超过20个字符")
private String productNo;
/**
* 产地code
*/
@Schema(description = "产地code", example = "")
@NotNull(message= "产地不能为空")
@Size(max = 20, message = "产地编码长度不能超过20个字符")
private String originCode;
/**
* 产地中文名字
*/
@Schema(description = "产地中文名字", example = "")
@NotNull(message= "产地中文名字不能为空")
@Size(max = 20, message = "产地中文名字长度不能超过20个字符")
private String originNameCn;
/**
* 产地英文名字
*/
@Schema(description = "产地英文名字", example = "")
@NotNull(message= "产地英文名字不能为空")
@Size(max = 20, message = "产地英文名字长度不能超过20个字符")
private String originNameEn;
/**
* 币种code
*/
@Schema(description = "币种编码", example = "")
@NotNull(message= "币种名字不能为空")
@Size(max = 20, message = "币种编码长度不能超过20个字符")
private String currencyCode;
/**
* 币种
*/
@Schema(description = "currency_name", example = "")
@NotNull(message= "币种名字不能为空")
@Size(max = 20, message = "币种名称长度不能超过20个字符")
private String currencyName;
/**
* 平台直营-platform 客户自营-customer
*/
@Schema(description = "平台直营-platform 客户自营-customer", example = "")
@NotNull(message= "产品类型不能为空")
private String productType;
/**
* 工厂id
*/
@Schema(description = "工厂ID", example = "")
@NotNull(message= "工厂ID不能为空")
private Integer factoryId;
/**
* 是否九猫处理
*/
@Schema(description = "是否九猫处理", example = "")
private Integer processing;
/**
*
*/
@TableField("sort")
private Integer sort;
/**
* 默认模ID
*/
@Schema(description = "模型ID", example = "")
private Integer diyId;
@Schema(description = "商品明细", implementation = ProductChangeDTO.class)
private ProductChangeDTO productChange;
@Schema(description = "商品明细", implementation = CustomProductItemDTO.class)
private List<CustomProductItemDTO> productList;
@Schema(description = "普通属性集合", implementation = CustomProductInfoPropertyDTO.class)
private List<CustomProductInfoPropertyDTO> normalProperties;
@Schema(description = "sku属性集合", implementation = CustomProductInfoPropertyDTO.class)
private List<CustomProductInfoPropertyDTO> skuProperties;
@Schema(description = "商品图片集合", implementation = CustomProductImageDTO.class)
private List<CustomProductImageDTO> imageList;
@Schema(description = "尺码图片集合", implementation = CustomProductImageDTO.class)
private List<CustomProductImageDTO> sizeList;
}
......@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* @author huanying
......@@ -23,28 +24,29 @@ public class CustomProductInfoPropertyDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
* ID
*/
@Schema(description = "")
private Integer id;
/**
* custom_product_info表id
* 中文名称
*/
@Schema(description = "custom_product_info表id")
private Integer infoId;
@Schema(description = "中文名称")
private String cnname;
/**
* 属性类ID
* 英文名称
*/
@Schema(description = "属性类ID")
private Integer propertyId;
@Schema(description = "英文名称")
private String enname;
/**
* 属性值ID
* 排序
*/
@Schema(description = "属性值ID")
private Integer valueId;
@Schema(description = "排序")
private Integer sort;
/**
* 是否为SKU属性
......@@ -52,5 +54,39 @@ public class CustomProductInfoPropertyDTO implements Serializable {
@Schema(description = "是否为SKU属性")
private Boolean skuProperty;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private Boolean multi;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private Boolean enable;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private String categoryInfoId;
/**
* SKU属性值列表
*/
@Schema(description = "SKU属性值列表")
private List<CustomProductPropertiesValueDTO> valueList;
/**
* publicData
*/
@Schema(description = "publicData")
private Boolean publicData;
/**
* publicData
*/
@Schema(description = "propertyValueIds")
private List<String> propertyValueIds;
}
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.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.List;
/**
* Entity
*
* @author huanying
* @date 2026-06-02 19:07:12
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class CustomProductInfoSnakeDTO extends PageRequest {
@Serial
private static final long serialVersionUID = 1L;
/**
* 商品 ID(必填)
*/
@Schema(description = "商品 ID(必填)")
private Integer id;
/**
* SKU 筛选
*/
@Schema(description = "SKU 筛选")
@Size(max = 20, message = "sku长度不能超过20个字符")
private String sku;
/**
* 商品名称
*/
@Schema(description = "name", example = "")
@NotNull(message= "商品名称不能为空")
@Size(max = 255, message = "商品名称长度不能超过255个字符")
private String name;
/**
* 商品类别ID
*/
@Schema(description = "商品类别ID", example = "")
@NotNull(message = "商品类别不能为空")
private Integer category_id;
/**
* 材质
*/
@Schema(description = "材质", example = "")
@NotNull(message= "材质不能为空")
private String material;
/**
* 印花类型:0满印 1局部印
*/
@Schema(description = "印花类型:0满印 1局部印")
private Integer print_type;
/**
* 货号
*/
@Schema(description = "货号")
@Size(max = 20, message = "货号长度不能超过20个字符")
private String product_no;
/**
* 产地编码
*/
@Schema(description = "产地编码")
private String origin_code;
/**
* 产地中文名
*/
@Schema(description = "产地中文名")
private String origin_name_cn;
/**
* 产地英文名
*/
@Schema(description = "产地英文名")
private String origin_name_en;
/**
* 币种编码
*/
@Schema(description = "币种编码")
private String currency_code;
/**
* 币种名称
*/
@Schema(description = "币种名称")
private String currency_name;
/**
* 产品类型:platform/customer
*/
@Schema(description = "产品类型:platform/customer")
private String product_type;
/**
* 仓库 ID 列表
*/
@Schema(description = "仓库 ID 列表")
private List<Integer> warehouseIds;
/**
* 商品title
*/
@Schema(description = "title")
@Size(max = 255, message = "title长度不能超过255个字符")
private String title;
/**
* 工艺 ID 列表
*/
@Schema(description = "工艺 ID 列表")
private List<Integer> craftIds;
/**
* 状态:1待上架 10已上架 20已下架 30待下架 40已作废
*/
@Schema(description = "状态:1待上架 10已上架 20已下架 30待下架 40已作废")
private Integer status;
/**
* 是否九猫处理
*/
@Schema(description = "是否九猫处理")
private Boolean processing;
/**
* 英文备注
*/
@Schema(description = "英文备注")
private String remark;
/**
* 中文备注
*/
@Schema(description = "中文备注")
private String cnRemark;
/**
* 图片列表
*/
@Schema(description = "普通图片列表")
private List<CustomProductImageSnakeDTO> imageList;
/**
* 尺码图片列表
*/
@Schema(description = "尺码图片列表(type=1)")
private List<CustomProductImageSnakeDTO> sizeList;
/**
* 颜色图
*/
@Schema(description = "颜色图(JSON字符串)")
private String color_images;
/**
* 商品主图
*/
@Schema(description = "商品主图")
private String img_url;
/**
* 工厂价格关联列表
*/
@Schema(description = "工厂价格关联列表")
private List<FactoryPriceRelDTO> factoryPriceList;
/**
* SKU 属性集合
*/
@Schema(description = "SKU 属性集合")
private List<CustomProductInfoPropertyDTO> skuProperties;
/**
* 商品明细
*/
@Schema(description = "商品明细", implementation = CustomProductItemSnakeDTO.class)
private List<CustomProductItemSnakeDTO> productList;
/**
* 工厂价(¥)
*/
@Schema(description = "工厂价(¥)", example = "")
@Digits(integer = 15, fraction = 2, message = "工厂价数值最多保留2位小数")
private BigDecimal factory_price;
/**
* 销售价(¥)
*/
@Schema(description = "销售价(¥)")
@Digits(integer = 15, fraction = 2, message = "工厂价数值最多保留2位小数")
private BigDecimal sales_price;
/**
* 销售价最高价(¥)
*/
@Schema(description = "销售价最高价(¥)")
@Digits(integer = 15, fraction = 2, message = "工厂价数值最多保留2位小数")
private BigDecimal sales_price_max;
/**
* 排序
*/
@Schema(description = "排序")
private Integer sort;
/**
*
*/
@Schema(description = "商品属性ID 1", example = "")
@NotNull(message= "商品属性不能为空")
private Integer property1_cate_id;
/**
*
*/
@Schema(description = "商品属性英文名称 1", example = "")
@NotNull(message= "商品属性名不能为空")
private String property1_enname;
/**
*
*/
@Schema(description = "商品属性ID 2", example = "")
private Integer property2_cate_id;
/**
*
*/
@Schema(description = "商品属性英文名称 2", example = "")
private String property2_enname;
/**
*
*/
@Schema(description = "商品属性ID 3", example = "")
private Integer property3_cate_id;
/**
*
*/
@Schema(description = "商品属性英文名称 3", example = "")
private String property3_enname;
/**
* 重量kg
*/
@Schema(description = "重量(kg)", example = "")
@NotNull(message= "重量不能为空")
@Digits(integer = 15, fraction = 2, message = "重量(kg)数值最多保留2位小数")
private BigDecimal weight;
/**
* 工厂价格区间关联列表
*/
@Schema(description = "工厂价格区间关联列表")
private List<FactoryPriceIntervalRelDTO> factoryPriceIntervalList;
/**
* DIY 用户 ID 列表(绑定客户)
*/
@Schema(description = "DIY 用户 ID 列表")
private Integer diyUserId;
/**
* 普通属性集合
*/
@Schema(description = "普通属性集合")
private List<CustomProductInfoPropertyDTO> normalProperties;
/**
* 黑名单ID
*/
@Schema(description = "黑名单ID")
private Integer blackUserId;
@Schema(description = "工厂 ID 列表")
private List<Integer> factoryIds;
// ==================== ERP 专用查询字段(对齐 TS ERPQueryProductInfoDTO) ====================
@Schema(description = "DIY 模板 SKU 筛选(ERP)")
private String diySku;
@Schema(description = "用户标识(ERP userMark)")
private String userMark;
@Schema(description = "来源筛选(ERP namespace)")
private String source;
@Schema(description = "仓库国家筛选(ERP)")
private String warehouseCountry;
@Schema(description = "DIY 模板 ID(ERP)")
private Integer diyId;
}
package com.jomalls.custom.app.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 组合更新商品 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code UpdateCustomProductInfoDTO}。
* 继承 SaveDTO 的字段,额外增加变更列表用于差异化更新。
*
* @author Lizh
* @date 2026-06-06
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Schema(description = "组合更新商品请求")
public class CustomProductInfoUpdateDTO extends CustomProductInfoSaveDTO1 implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "商品 ID(必填)")
private Integer id;
@Schema(description = "子项变更列表(增/删/改)", implementation = ProductChangeDTO.class)
private ProductChangeDTO productChange;
@Schema(description = "工厂价格变更列表(增/删/改)", implementation = ProductFactoryPriceChangeDTO.class)
private ProductFactoryPriceChangeDTO productFactoryPriceChange;
@Schema(description = "图片变更列表(增/删/改)", implementation = ProductImageChangeDTO.class)
private ProductImageChangeDTO productImageChange;
@Schema(description = "尺码图变更列表(增/删/改)", implementation = ProductImageChangeDTO.class)
private ProductImageChangeDTO productSizeChange;
/**
* 工厂价格变更 DTO
*/
@Data
@Schema(description = "工厂价格变更")
public static class ProductFactoryPriceChangeDTO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "新增列表")
private List<FactoryPriceRelDTO> addList;
@Schema(description = "修改列表")
private List<FactoryPriceRelDTO> updateList;
@Schema(description = "删除 ID 列表")
private List<Integer> removeList;
}
/**
* 图片变更 DTO
*/
@Data
@Schema(description = "图片变更")
public static class ProductImageChangeDTO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "新增列表")
private List<CustomProductImageSnakeDTO> addList;
@Schema(description = "删除 ID 列表")
private List<Integer> removeList;
}
}
......@@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* Model
......@@ -22,7 +22,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "skuItem Dto")
public class CustomProductItemDTO implements Serializable {
public class CustomProductItemSnakeDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -33,10 +33,10 @@ public class CustomProductItemDTO implements Serializable {
private Integer id;
/**
* 商品ID
* 排序
*/
@Schema(description = "商品ID")
private Integer productId;
@Schema(description = "排序")
private Integer sort;
/**
* sku
......@@ -48,163 +48,144 @@ public class CustomProductItemDTO implements Serializable {
* sku商品名称
*/
@Schema(description = "sku商品名称")
private String skuName;
private String sku_name;
/**
* 封面图
* sku克重
*/
@Schema(description = "封面图")
private String image;
@Schema(description = "sku克重")
private BigDecimal sku_weight;
/**
* 图片集
*
*/
@Schema(description = "图片集")
private String imageAry;
@Schema(description = "")
private Integer property1_id;
/**
* 属性分类ID1
* 属性名称1
*/
@Schema(description = "属性分类ID1")
private Integer propertyCateId1;
@Schema(description = "属性名称1")
private String option_enname1;
/**
* 属性分类ID2
*
*/
@Schema(description = "属性分类ID2")
private Integer propertyCateId2;
@Schema(description = "")
private String custom_value1;
/**
* 属性分类ID3
* 属性分类ID1
*/
@Schema(description = "属性分类ID3")
private Integer propertyCateId3;
@Schema(description = "属性分类ID1")
private String property_code1;
/**
*
* 属性分类ID1
*/
@Schema(description = "")
private Integer property1Id;
@Schema(description = "属性分类ID1")
private Integer property_cate_id1;
/**
*
*
*/
@Schema(description = "")
private Integer property2Id;
private Integer property2_id;
/**
*
* 属性名称2
*/
@Schema(description = "属性名称2")
private String option_enname2;
/**
*
*/
@Schema(description = "")
private Integer property3Id;
private String custom_value2;
/**
* 属性编码1
* 属性分类ID2
*/
@Schema(description = "属性编码1")
private String propertyCode1;
@Schema(description = "属性分类ID2")
private String property_code2;
/**
* 属性编码2
* 属性分类ID2
*/
@Schema(description = "属性编码2")
private String propertyCode2;
@Schema(description = "属性分类ID2")
private Integer property_cate_id2;
/**
*
*
*/
@Schema(description = "")
private String propertyCode3;
private Integer property3_id;
/**
* 属性名称1
* 属性名称3
*/
@Schema(description = "属性名称1")
private String optionEnname1;
@Schema(description = "属性名称3")
private String option_enname3;
/**
* 属性名称2
*
*/
@Schema(description = "属性名称2")
private String optionEnname2;
@Schema(description = "")
private String custom_value3;
/**
*
* 属性分类ID3
*/
@Schema(description = "")
private String optionEnname3;
@Schema(description = "属性分类ID3")
private String property_code3;
/**
*
* 属性分类ID3
*/
@Schema(description = "")
private String customValue1;
@Schema(description = "属性分类ID3")
private Integer property_cate_id3;
/**
*
*
*/
@Schema(description = "")
private String customValue2;
private String relation_ids;
/**
*
*
*/
@Schema(description = "")
private String customValue3;
private List<String> relation;
/**
* 工厂价
*/
@Schema(description = "工厂价")
private BigDecimal factoryPrice;
private BigDecimal factory_price;
/**
* 销售价
*/
@Schema(description = "销售价")
private BigDecimal salesPrice;
private BigDecimal sales_price;
/**
* sku克重
*/
@Schema(description = "sku克重")
private BigDecimal skuWeight;
/**
* 印花类型 0满印 1局部印
*/
@Schema(description = "印花类型 0满印 1局部印")
private Integer printType;
/**
* 排序
* 封面图
*/
@Schema(description = "排序")
private Integer sort;
@Schema(description = "封面图")
private String image;
/**
* 货号
* 图片集Json串
*/
@Schema(description = "货号")
private String productNo;
@Schema(description = "图片集Json串")
private String image_ary;
/**
* 1正常码 2大码
*/
@Schema(description = "1正常码 2大码")
private Integer sizeType;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private Date updateTime;
private Integer size_type;
}
package com.jomalls.custom.app.dto;
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;
/**
*
* @author huanying
* @date 2026-06-03 11:57:01
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "图片Dto")
public class CustomProductPropertiesValueDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@Schema(description = "")
private Integer id;
/**
* 类别编码
*/
@Schema(description = "类别编码")
private String cateCode;
/**
* 类别名称
*/
@Schema(description = "类别名称")
private String cateName;
/**
* 编码
*/
@Schema(description = "编码")
private String code;
/**
* 中文名称
*/
@Schema(description = "中文名称")
private String cnname;
/**
* 英文名称
*/
@Schema(description = "英文名称")
private String enname;
/**
* 前景色
*/
@Schema(description = "前景色")
private String fontColor;
/**
* 背景色
*/
@Schema(description = "背景色")
private String bgColor;
/**
*
*/
@Schema(description = "")
private Boolean battery;
/**
*
*/
@Schema(description = "")
private Boolean liquid;
/**
*
*/
@Schema(description = "")
private Boolean knife;
/**
*
*/
@Schema(description = "")
private Integer selected;
/**
*
*/
@Schema(description = "")
private Boolean publicData;
}
package com.jomalls.custom.app.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 工厂价格区间关联 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code FactoryPriceIntervalRelDTO}。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工厂价格区间关联")
public class FactoryPriceIntervalRelDTO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "币种编码")
private String currencyCode;
@Schema(description = "系统成本最低价")
private BigDecimal priceMin;
@Schema(description = "系统成本最高价")
private BigDecimal priceMax;
}
package com.jomalls.custom.app.dto;
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.math.BigDecimal;
/**
* 工厂价格关联 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code CreateFactoryPriceRelDTO}。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "工厂价格关联")
public class FactoryPriceRelDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "子项 ID(custom_product_item 的 id)")
private Integer itemId;
@Schema(description = "子项 SKU")
private String itemSku;
@Schema(description = "工厂 ID")
private Integer factoryId;
@Schema(description = "工厂价格")
private BigDecimal factoryPrice;
@Schema(description = "销售价格")
private BigDecimal salesPrice;
@Schema(description = "工厂币种编码")
private String factoryCurrencyCode;
@Schema(description = "销售币种编码")
private String salesCurrencyCode;
}
......@@ -15,11 +15,11 @@ import java.util.List;
@AllArgsConstructor
@Schema(description = "商品变更Dto")
public class ProductChangeDTO implements Serializable {
@Schema(description = "添加集合", implementation = CustomProductItemDTO.class)
private List<CustomProductItemDTO> addList;
@Schema(description = "添加集合", implementation = CustomProductItemSnakeDTO.class)
private List<CustomProductItemSnakeDTO> addList;
@Schema(description = "修改集合", implementation = CustomProductItemDTO.class)
private List<CustomProductItemDTO> updateList;
@Schema(description = "修改集合", implementation = CustomProductItemSnakeDTO.class)
private List<CustomProductItemSnakeDTO> updateList;
@Schema(description = "删除集合", implementation = Integer.class)
private List<Integer> removeList;
......
package com.jomalls.custom.app.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 定制商品状态枚举
* <p>
* 对齐 TS 项目 {@code enums/CustomProductInfoStatus.ts} 中的状态定义。
*
* @author Lizh
* @date 2026-06-06
*/
@Getter
public enum CustomProductInfoStatusEnum {
/** 待上架 */
TO_BE_SHELF(1, "待上架"),
/** 已上架 */
SHELF(10, "已上架"),
/** 已下架 */
REMOVED(20, "已下架"),
/** 待下架 */
TO_BE_REMOVED(30, "待下架"),
/** 已作废 */
VOIDED(40, "已作废");
private final int code;
private final String label;
CustomProductInfoStatusEnum(int code, String label) {
this.code = code;
this.label = label;
}
/**
* 根据状态码获取枚举
*
* @param code 状态码
* @return 对应的枚举实例,未匹配时返回 null
*/
public static CustomProductInfoStatusEnum getByCode(int code) {
return Arrays.stream(values())
.filter(e -> e.code == code)
.findFirst()
.orElse(null);
}
/**
* 获取所有状态列表(供前端下拉框使用)
*
* @return [{code, label}, ...]
*/
public static List<Map<String, Object>> getAllStatusList() {
return Arrays.stream(values())
.map(e -> {
Map<String, Object> map = new HashMap<>();
map.put("code", e.code);
map.put("label", e.label);
return map;
})
.collect(Collectors.toList());
}
}
package com.jomalls.custom.app.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
/**
* 模板状态枚举
* <p>
* 对齐 TS 项目 {@code TemplateStatus}。
*
* @author Lizh
* @date 2026-06-08
*/
@Getter
public enum TemplateStatus {
REMOVED(0, "已下架"),
SHELF(1, "已上架"),
WAIT_SHELF(20, "待上架"),
COMPLETE(40, "建模完成"),
REFINE(50, "多变体完善"),
TEST(60, "产前测试"),
IN_BUILD(70, "建模中"),
TO_BE_CONFIRMED(75, "待确认"),
WAIT_ASSIGNMENT(80, "待分派"),
IN_THE_PLATE(85, "打板中"),
TO_BE_REVIEWED(90, "待审核");
private final int code;
private final String remark;
TemplateStatus(int code, String remark) {
this.code = code;
this.remark = remark;
}
public static TemplateStatus getByCode(int code) {
return Arrays.stream(values())
.filter(s -> s.code == code)
.findFirst()
.orElse(null);
}
/** demo 用户可见的状态列表 */
public static final List<Integer> DEMO_CODE_LIST = Arrays.asList(
TEST.code, REFINE.code, COMPLETE.code, WAIT_SHELF.code, SHELF.code);
/** 上架状态码 */
public static final int SHELF_CODE = SHELF.code;
}
......@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductImagePageVO;
import com.jomalls.custom.app.vo.CustomProductImageVO;
import com.jomalls.custom.app.vo.CustomProductImageSnakeVO;
import java.util.List;
......@@ -17,10 +17,10 @@ public interface CustomProductImageService {
/**
* 列表查询接口
*
* @param customProductImageVO 条件model
* @param customProductImageSnakeVO 条件model
* @return list集合
*/
List<CustomProductImageVO> list(CustomProductImageVO customProductImageVO);
List<CustomProductImageSnakeVO> list(CustomProductImageSnakeVO customProductImageSnakeVO);
/**
* 根据条件查询分页列表接口
......@@ -28,7 +28,7 @@ public interface CustomProductImageService {
* @param customProductImagePageVO 分页入参model
* @return 分页对象
*/
IPage<CustomProductImageVO> pageList(CustomProductImagePageVO customProductImagePageVO);
IPage<CustomProductImageSnakeVO> pageList(CustomProductImagePageVO customProductImagePageVO);
/**
* 根据id查询详情
......@@ -36,21 +36,21 @@ public interface CustomProductImageService {
* @param id 主键
* @return 实体model
*/
CustomProductImageVO info(Integer id);
CustomProductImageSnakeVO info(Integer id);
/**
* 保存对象
*
* @param customProductImageVO 保存对象
* @param customProductImageSnakeVO 保存对象
*/
void save(CustomProductImageVO customProductImageVO);
void save(CustomProductImageSnakeVO customProductImageSnakeVO);
/**
* 根据id修改对象
*
* @param customProductImageVO 修改对象
* @param customProductImageSnakeVO 修改对象
*/
void updateById(CustomProductImageVO customProductImageVO);
void updateById(CustomProductImageSnakeVO customProductImageSnakeVO);
/**
* 根据主键ID进行删除
......
......@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO;
import com.jomalls.custom.app.vo.CustomProductInfoPropertyVO;
import com.jomalls.custom.app.vo.CustomProductInfoPropertySnakeVO;
import java.util.List;
......@@ -17,10 +17,10 @@ public interface CustomProductInfoPropertyService {
/**
* 列表查询接口
*
* @param customProductInfoPropertyVO 条件model
* @param customProductInfoPropertySnakeVO 条件model
* @return list集合
*/
List<CustomProductInfoPropertyVO> list(CustomProductInfoPropertyVO customProductInfoPropertyVO);
List<CustomProductInfoPropertySnakeVO> list(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO);
/**
* 根据条件查询分页列表接口
......@@ -28,7 +28,7 @@ public interface CustomProductInfoPropertyService {
* @param customProductInfoPropertyPageVO 分页入参model
* @return 分页对象
*/
IPage<CustomProductInfoPropertyVO> pageList(CustomProductInfoPropertyPageVO customProductInfoPropertyPageVO);
IPage<CustomProductInfoPropertySnakeVO> pageList(CustomProductInfoPropertyPageVO customProductInfoPropertyPageVO);
/**
* 根据id查询详情
......@@ -36,21 +36,21 @@ public interface CustomProductInfoPropertyService {
* @param id 主键
* @return 实体model
*/
CustomProductInfoPropertyVO info(Integer id);
CustomProductInfoPropertySnakeVO info(Integer id);
/**
* 保存对象
*
* @param customProductInfoPropertyVO 保存对象
* @param customProductInfoPropertySnakeVO 保存对象
*/
void save(CustomProductInfoPropertyVO customProductInfoPropertyVO);
void save(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO);
/**
* 根据id修改对象
*
* @param customProductInfoPropertyVO 修改对象
* @param customProductInfoPropertySnakeVO 修改对象
*/
void updateById(CustomProductInfoPropertyVO customProductInfoPropertyVO);
void updateById(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO);
/**
* 根据主键ID进行删除
......
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.dto.CustomProductInfoDTO;
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.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.app.vo.CustomProductInfoVO;
import com.jomalls.custom.app.vo.DbDiyVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 接口
* @description: 定制商品服务接口
* @date 2026-05-29 10:43:29
*/
public interface CustomProductInfoService {
IPage<CustomProductInfoVO> pageList(CustomProductInfoSnakeDTO param);
/**
* 列表查询接口
* 组合创建商品(SKU 生成 + 事务内写入主表及所有子表)
*
* @param customProductInfoVO 条件model
* @return list集合
* @param dto 组合创建 DTO
*/
List<CustomProductInfoVO> list(CustomProductInfoVO customProductInfoVO);
void saveFull(CustomProductInfoSnakeDTO dto);
/**
* 根据条件查询分页列表接口
* 组合更新商品(事务内处理主表及子表的增/删/改差异)
*
* @param param 分页入参model
* @return 分页对象
* @param dto 组合更新 DTO
*/
IPage<CustomProductInfoVO> pageList(CustomProductInfoDTO param);
void updateFull(CustomProductInfoUpdateDTO dto);
/**
* 根据id查询详情
* 根据 ID 或 SKU 加载商品完整数据(并行单表查询后在 Java 层组合)
*
* @param id 主键
* @return 实体model
* @param id 商品 ID(可为 null)
* @param sku 商品 SKU(可为 null)
* @param namespace 命名空间(可选)
* @return 完整商品 VO
*/
CustomProductInfoVO info(Integer id);
CustomProductInfoSnakeVO getByIdOrSku(Integer id, String sku, String namespace);
/**
* 保存对象
* 批量绑定/解绑 DIY 用户到商品
*
* @param customProductInfoVO 保存对象
* @param dto 绑定请求 DTO
*/
void save(CustomProductInfoVO customProductInfoVO);
void bindsDiyUser(BindDiyUserDTO dto);
/**
* 根据id修改对象
* 批量将 DIY 用户加入商品黑名单
*
* @param customProductInfoVO 修改对象
* @param dto 黑名单请求 DTO
*/
void updateById(CustomProductInfoVO customProductInfoVO);
void addBlackList(AddBlackListDTO dto);
/**
* 根据主键ID进行删除
* 设置商品的默认 DIY 模板
*
* @param id 主键
* @param id 商品 ID
* @param diyId DIY 模板 ID
* @param diySku DIY 模板 SKU
*/
void deleteById(Integer id);
void bindDefaultDiy(Integer id, Integer diyId, String diySku);
}
/**
* 获取商品绑定的 DIY 模板列表
*
* @param id 商品 ID
* @return DIY 模板列表
*/
List<DbDiyVO> getBindsDiyById(Integer id);
/**
* 获取商品绑定的 DIY 用户 ID 列表
*
* @param id 商品 ID
* @return DIY 用户 ID 列表
*/
List<Integer> getBindsDiyUserById(Integer id);
/**
* 获取商品黑名单 DIY 用户 ID 列表
*
* @param id 商品 ID
* @return 黑名单用户 ID 列表
*/
List<Integer> getBlackListById(Integer id);
/**
* 获取商品绑定的工艺 ID 列表
*
* @param id 商品 ID
* @return 工艺 ID 列表
*/
List<Long> getCraftById(Integer id);
// ==================== ERP 专用接口(对齐 TS) ====================
/**
* ERP 分页查询(对齐 TS erpPage)
* <p>
* 包含黑名单过滤、用户折扣、模板上架状态等 ERP 特定逻辑。
*/
IPage<CustomProductInfoVO> erpPage(CustomProductInfoSnakeDTO param);
/**
* ERP 获取绑定 DIY(对齐 TS getBindsDiyByIdAndUserMark)
*/
List<DbDiyVO> getErpBindsDiyById(Integer id, String userMark, String namespace);
}
......@@ -2,7 +2,7 @@ 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.vo.CustomProductItemVO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import java.util.List;
......@@ -17,10 +17,10 @@ public interface CustomProductItemService {
/**
* 列表查询接口
*
* @param customProductItemVO 条件model
* @param customProductItemSnakeVO 条件model
* @return list集合
*/
List<CustomProductItemVO> list(CustomProductItemVO customProductItemVO);
List<CustomProductItemSnakeVO> list(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据条件查询分页列表接口
......@@ -28,7 +28,7 @@ public interface CustomProductItemService {
* @param customProductItemPageVO 分页入参model
* @return 分页对象
*/
IPage<CustomProductItemVO> pageList(CustomProductItemPageVO customProductItemPageVO);
IPage<CustomProductItemSnakeVO> pageList(CustomProductItemPageVO customProductItemPageVO);
/**
* 根据id查询详情
......@@ -36,21 +36,21 @@ public interface CustomProductItemService {
* @param id 主键
* @return 实体model
*/
CustomProductItemVO info(Integer id);
CustomProductItemSnakeVO info(Integer id);
/**
* 保存对象
*
* @param customProductItemVO 保存对象
* @param customProductItemSnakeVO 保存对象
*/
void save(CustomProductItemVO customProductItemVO);
void save(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据id修改对象
*
* @param customProductItemVO 修改对象
* @param customProductItemSnakeVO 修改对象
*/
void updateById(CustomProductItemVO customProductItemVO);
void updateById(CustomProductItemSnakeVO customProductItemSnakeVO);
/**
* 根据主键ID进行删除
......
package com.jomalls.custom.app.service;
import com.jomalls.custom.app.vo.CustomProductInfoSnakeVO;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
/**
* DIY 用户服务
* <p>
* 对齐 TS 项目 {@code diyUserService} 中与商品详情相关的功能。
*
* @author Lizh
* @date 2026-06-08
*/
public interface DiyUserService {
/**
* 根据 namespace 查询用户
* <p>
* 对齐 TS {@code getByNamespace(namespace)}
*
* @param namespace 用户名称
* @return 用户实体,未找到返回 null
*/
DbDiyUserEntity getByNamespace(String namespace);
/**
* 根据 userMark 查询用户
* <p>
* 对齐 TS {@code getByUserMark(userMark)}
*/
DbDiyUserEntity getByUserMark(String userMark);
/**
* 对商品详情应用用户折扣外部定价
* <p>
* 对齐 TS {@code setProductExternalPrice(user, customProductInfo)}。
* 根据用户折扣比例,对商品以及子项、工厂价格、价格区间的销售价进行打折。
*
* @param user 用户(含 discount 折扣字段)
* @param vo 商品完整详情
*/
void setProductExternalPrice(DbDiyUserEntity user, CustomProductInfoSnakeVO vo);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.ProductFactoryRelPageVO;
import com.jomalls.custom.app.vo.ProductFactoryRelVO;
import java.util.List;
/**
* 产品-工厂关联 App Service 接口
*
* @author Lizh
* @date 2026-06-06
*/
public interface ProductFactoryRelService {
List<ProductFactoryRelVO> list(ProductFactoryRelVO vo);
IPage<ProductFactoryRelVO> pageList(ProductFactoryRelPageVO param);
ProductFactoryRelVO info(Integer id);
void save(ProductFactoryRelVO vo);
void updateById(ProductFactoryRelVO vo);
void deleteById(Integer id);
}
......@@ -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.CustomProductImagePageVO;
import com.jomalls.custom.app.vo.CustomProductImageVO;
import com.jomalls.custom.app.vo.CustomProductImageSnakeVO;
import com.jomalls.custom.app.service.CustomProductImageService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
......@@ -37,34 +37,34 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
}
@Override
public List<CustomProductImageVO> list(CustomProductImageVO customProductImageVO) {
public List<CustomProductImageSnakeVO> list(CustomProductImageSnakeVO customProductImageSnakeVO) {
QueryWrapper<CustomProductImageEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<CustomProductImageEntity> list = customProductImageDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductImageVO.class)).collect(Collectors.toList());
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductImageSnakeVO.class)).collect(Collectors.toList());
}
@Override
public IPage<CustomProductImageVO> pageList(CustomProductImagePageVO customProductImagePageVO) {
public IPage<CustomProductImageSnakeVO> pageList(CustomProductImagePageVO customProductImagePageVO) {
CustomAsserts.nonNull(customProductImagePageVO, "分页查询参数不能为空");
QueryWrapper<CustomProductImageEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<CustomProductImageEntity> page = customProductImageDomainService.selectPage(queryWrapper, customProductImagePageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductImageVO.class));
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductImageSnakeVO.class));
}
@Override
public CustomProductImageVO info(Integer id) {
public CustomProductImageSnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductImageEntity customProductImage = customProductImageDomainService.getById(id);
return BeanMapper.mapper().convert(customProductImage, CustomProductImageVO.class);
return BeanMapper.mapper().convert(customProductImage, CustomProductImageSnakeVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductImageVO customProductImageVO) {
CustomAsserts.nonNull(customProductImageVO, "实体对象不能为空");
CustomProductImageEntity customProductImageEntity = BeanMapper.mapper().convert(customProductImageVO, CustomProductImageEntity.class);
public void save(CustomProductImageSnakeVO customProductImageSnakeVO) {
CustomAsserts.nonNull(customProductImageSnakeVO, "实体对象不能为空");
CustomProductImageEntity customProductImageEntity = BeanMapper.mapper().convert(customProductImageSnakeVO, CustomProductImageEntity.class);
try {
customProductImageDomainService.save(customProductImageEntity);
} catch (DuplicateKeyException e) {
......@@ -75,9 +75,9 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductImageVO customProductImageVO) {
CustomAsserts.nonNull(customProductImageVO, "实体对象不能为空");
CustomProductImageEntity customProductImage = BeanMapper.mapper().convert(customProductImageVO, CustomProductImageEntity.class);
public void updateById(CustomProductImageSnakeVO customProductImageSnakeVO) {
CustomAsserts.nonNull(customProductImageSnakeVO, "实体对象不能为空");
CustomProductImageEntity customProductImage = BeanMapper.mapper().convert(customProductImageSnakeVO, CustomProductImageEntity.class);
try {
customProductImageDomainService.updateById(customProductImage);
} catch (DuplicateKeyException e) {
......
......@@ -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.CustomProductInfoPropertyPageVO;
import com.jomalls.custom.app.vo.CustomProductInfoPropertyVO;
import com.jomalls.custom.app.vo.CustomProductInfoPropertySnakeVO;
import com.jomalls.custom.app.service.CustomProductInfoPropertyService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
......@@ -37,34 +37,34 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
}
@Override
public List<CustomProductInfoPropertyVO> list(CustomProductInfoPropertyVO customProductInfoPropertyVO) {
public List<CustomProductInfoPropertySnakeVO> list(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO) {
QueryWrapper<CustomProductInfoPropertyEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<CustomProductInfoPropertyEntity> list = customProductInfoPropertyDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductInfoPropertyVO.class)).collect(Collectors.toList());
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductInfoPropertySnakeVO.class)).collect(Collectors.toList());
}
@Override
public IPage<CustomProductInfoPropertyVO> pageList(CustomProductInfoPropertyPageVO customProductInfoPropertyPageVO) {
public IPage<CustomProductInfoPropertySnakeVO> pageList(CustomProductInfoPropertyPageVO customProductInfoPropertyPageVO) {
CustomAsserts.nonNull(customProductInfoPropertyPageVO, "分页查询参数不能为空");
QueryWrapper<CustomProductInfoPropertyEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<CustomProductInfoPropertyEntity> page = customProductInfoPropertyDomainService.selectPage(queryWrapper, customProductInfoPropertyPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductInfoPropertyVO.class));
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductInfoPropertySnakeVO.class));
}
@Override
public CustomProductInfoPropertyVO info(Integer id) {
public CustomProductInfoPropertySnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductInfoPropertyEntity customProductInfoProperty = customProductInfoPropertyDomainService.getById(id);
return BeanMapper.mapper().convert(customProductInfoProperty, CustomProductInfoPropertyVO.class);
return BeanMapper.mapper().convert(customProductInfoProperty, CustomProductInfoPropertySnakeVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductInfoPropertyVO customProductInfoPropertyVO) {
CustomAsserts.nonNull(customProductInfoPropertyVO, "实体对象不能为空");
CustomProductInfoPropertyEntity customProductInfoPropertyEntity = BeanMapper.mapper().convert(customProductInfoPropertyVO, CustomProductInfoPropertyEntity.class);
public void save(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO) {
CustomAsserts.nonNull(customProductInfoPropertySnakeVO, "实体对象不能为空");
CustomProductInfoPropertyEntity customProductInfoPropertyEntity = BeanMapper.mapper().convert(customProductInfoPropertySnakeVO, CustomProductInfoPropertyEntity.class);
try {
customProductInfoPropertyDomainService.save(customProductInfoPropertyEntity);
} catch (DuplicateKeyException e) {
......@@ -75,9 +75,9 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductInfoPropertyVO customProductInfoPropertyVO) {
CustomAsserts.nonNull(customProductInfoPropertyVO, "实体对象不能为空");
CustomProductInfoPropertyEntity customProductInfoProperty = BeanMapper.mapper().convert(customProductInfoPropertyVO, CustomProductInfoPropertyEntity.class);
public void updateById(CustomProductInfoPropertySnakeVO customProductInfoPropertySnakeVO) {
CustomAsserts.nonNull(customProductInfoPropertySnakeVO, "实体对象不能为空");
CustomProductInfoPropertyEntity customProductInfoProperty = BeanMapper.mapper().convert(customProductInfoPropertySnakeVO, CustomProductInfoPropertyEntity.class);
try {
customProductInfoPropertyDomainService.updateById(customProductInfoProperty);
} catch (DuplicateKeyException e) {
......
......@@ -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.CustomProductItemPageVO;
import com.jomalls.custom.app.vo.CustomProductItemVO;
import com.jomalls.custom.app.vo.CustomProductItemSnakeVO;
import com.jomalls.custom.app.service.CustomProductItemService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
......@@ -37,34 +37,34 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
}
@Override
public List<CustomProductItemVO> list(CustomProductItemVO customProductItemVO) {
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, CustomProductItemVO.class)).collect(Collectors.toList());
return list.stream().map(e -> BeanMapper.mapper().convert(e, CustomProductItemSnakeVO.class)).collect(Collectors.toList());
}
@Override
public IPage<CustomProductItemVO> pageList(CustomProductItemPageVO customProductItemPageVO) {
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, CustomProductItemVO.class));
return page.convert(e -> BeanMapper.mapper().convert(e, CustomProductItemSnakeVO.class));
}
@Override
public CustomProductItemVO info(Integer id) {
public CustomProductItemSnakeVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
CustomProductItemEntity customProductItem = customProductItemDomainService.getById(id);
return BeanMapper.mapper().convert(customProductItem, CustomProductItemVO.class);
return BeanMapper.mapper().convert(customProductItem, CustomProductItemSnakeVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(CustomProductItemVO customProductItemVO) {
CustomAsserts.nonNull(customProductItemVO, "实体对象不能为空");
CustomProductItemEntity customProductItemEntity = BeanMapper.mapper().convert(customProductItemVO, CustomProductItemEntity.class);
public void save(CustomProductItemSnakeVO customProductItemSnakeVO) {
CustomAsserts.nonNull(customProductItemSnakeVO, "实体对象不能为空");
CustomProductItemEntity customProductItemEntity = BeanMapper.mapper().convert(customProductItemSnakeVO, CustomProductItemEntity.class);
try {
customProductItemDomainService.save(customProductItemEntity);
} catch (DuplicateKeyException e) {
......@@ -75,9 +75,9 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(CustomProductItemVO customProductItemVO) {
CustomAsserts.nonNull(customProductItemVO, "实体对象不能为空");
CustomProductItemEntity customProductItem = BeanMapper.mapper().convert(customProductItemVO, CustomProductItemEntity.class);
public void updateById(CustomProductItemSnakeVO customProductItemSnakeVO) {
CustomAsserts.nonNull(customProductItemSnakeVO, "实体对象不能为空");
CustomProductItemEntity customProductItem = BeanMapper.mapper().convert(customProductItemSnakeVO, CustomProductItemEntity.class);
try {
customProductItemDomainService.updateById(customProductItem);
} catch (DuplicateKeyException e) {
......
package com.jomalls.custom.app.service.impl;
import com.jomalls.custom.app.service.DiyUserService;
import com.jomalls.custom.app.vo.*;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
import com.jomalls.custom.domain.service.DbDiyUserDomainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* DIY 用户服务实现
* <p>
* 对齐 TS 项目 {@code diyUserService}。
*
* @author Lizh
* @date 2026-06-08
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class DiyUserServiceImpl implements DiyUserService {
private final DbDiyUserDomainService dbDiyUserDomainService;
/** 折扣基数(100 表示无折扣) */
private static final BigDecimal DISCOUNT_BASE = new BigDecimal("100");
@Override
public DbDiyUserEntity getByNamespace(String namespace) {
return dbDiyUserDomainService.getByNamespace(namespace);
}
@Override
public DbDiyUserEntity getByUserMark(String userMark) {
return dbDiyUserDomainService.getByUserMark(userMark);
}
@Override
public void setProductExternalPrice(DbDiyUserEntity user, CustomProductInfoSnakeVO vo) {
if (user == null || user.getDiscount() == null) {
return;
}
// discount 如 85 → 折扣率 0.85(对齐 TS:317)
BigDecimal discountRate = user.getDiscount().divide(DISCOUNT_BASE, 4, RoundingMode.HALF_UP);
if (discountRate.compareTo(BigDecimal.ONE) == 0) {
return;
}
log.debug("[ setProductExternalPrice ] 用户={}, 折扣率={}", user.getName(), discountRate);
// 主表 sales_price / sales_price_max(对齐 TS:322-327)
if (vo.getSales_price() != null) {
vo.setSales_price(vo.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
if (vo.getSales_price_max() != null) {
vo.setSales_price_max(vo.getSales_price_max().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
// 子项的 sales_price(对齐 TS:328-332)
if (vo.getProductList() != null) {
for (CustomProductItemSnakeVO item : vo.getProductList()) {
if (item.getSales_price() != null) {
item.setSales_price(item.getSales_price().multiply(discountRate).setScale(2, RoundingMode.HALF_UP));
}
}
}
// 工厂价格关联的 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));
}
}
}
}
}
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.exception.ServiceException;
import com.jomalls.custom.app.service.ProductFactoryRelService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.app.vo.ProductFactoryRelPageVO;
import com.jomalls.custom.app.vo.ProductFactoryRelVO;
import com.jomalls.custom.dal.entity.ProductFactoryRelEntity;
import com.jomalls.custom.domain.service.ProductFactoryRelDomainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* 产品-工厂关联 App Service 实现
*
* @author Lizh
* @date 2026-06-06
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductFactoryRelServiceImpl implements ProductFactoryRelService {
private final ProductFactoryRelDomainService productFactoryRelDomainService;
@Override
public List<ProductFactoryRelVO> list(ProductFactoryRelVO vo) {
QueryWrapper<ProductFactoryRelEntity> queryWrapper = new QueryWrapper<>();
List<ProductFactoryRelEntity> list = productFactoryRelDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, ProductFactoryRelVO.class)).collect(Collectors.toList());
}
@Override
public IPage<ProductFactoryRelVO> pageList(ProductFactoryRelPageVO param) {
CustomAsserts.nonNull(param, "分页查询参数不能为空");
QueryWrapper<ProductFactoryRelEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
IPage<ProductFactoryRelEntity> page = productFactoryRelDomainService.selectPage(queryWrapper, param);
return page.convert(e -> BeanMapper.mapper().convert(e, ProductFactoryRelVO.class));
}
@Override
public ProductFactoryRelVO info(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
ProductFactoryRelEntity entity = productFactoryRelDomainService.getById(id);
return BeanMapper.mapper().convert(entity, ProductFactoryRelVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(ProductFactoryRelVO vo) {
CustomAsserts.nonNull(vo, "实体对象不能为空");
ProductFactoryRelEntity entity = BeanMapper.mapper().convert(vo, ProductFactoryRelEntity.class);
try {
productFactoryRelDomainService.save(entity);
} catch (DuplicateKeyException e) {
log.info("[ save ] 实体对象唯一约束重复", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(ProductFactoryRelVO vo) {
CustomAsserts.nonNull(vo, "实体对象不能为空");
ProductFactoryRelEntity entity = BeanMapper.mapper().convert(vo, ProductFactoryRelEntity.class);
try {
productFactoryRelDomainService.updateById(entity);
} catch (DuplicateKeyException e) {
log.info("[ updateById ] 实体对象唯一约束重复", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Integer id) {
CustomAsserts.nonNull(id, "主键id不能为空");
productFactoryRelDomainService.removeById(id);
}
}
......@@ -2,6 +2,7 @@ package com.jomalls.custom.app.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
......@@ -25,10 +26,18 @@ import java.util.List;
public class BeanMapper {
/**
* Jackson ObjectMapper配置
* Jackson ObjectMapper配置(默认驼峰命名)
*/
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* Jackson ObjectMapper配置(蛇形命名 ↔ 驼峰命名双向转换)
* <p>
* 用于 DTO(snake_case 字段名)与 Entity/VO(camelCase 字段名)之间的互转。
* 由于命名策略在序列化和反序列化两端一致生效,驼峰↔驼峰、蛇形↔驼峰的转换都能正确处理。
*/
private static final ObjectMapper SNAKE_CASE_MAPPER = new ObjectMapper();
static {
// 注册Java 8时间模块,支持LocalDate, LocalDateTime等
OBJECT_MAPPER.registerModule(new JavaTimeModule());
......@@ -40,16 +49,44 @@ public class BeanMapper {
OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 允许单值包装数组
OBJECT_MAPPER.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
// 蛇形命名 mapper:复制默认配置,叠加 SNAKE_CASE 命名策略
SNAKE_CASE_MAPPER.registerModule(new JavaTimeModule());
SNAKE_CASE_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
SNAKE_CASE_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SNAKE_CASE_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
SNAKE_CASE_MAPPER.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
// 核心:设置蛇形命名策略,使得 category_id ↔ categoryId 可以互相转换
SNAKE_CASE_MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
}
private BeanMapper() {
this.objectMapper = OBJECT_MAPPER;
}
private BeanMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
private final ObjectMapper objectMapper;
public static BeanMapper mapper() {
return new BeanMapper();
}
/**
* 获取使用蛇形命名策略的 BeanMapper 实例
* <p>
* 适用于 snake_case 字段名的 DTO 与 camelCase 字段名的 Entity/VO 之间的双向转换。
* 例如:CustomProductInfoDTO(category_id)→ CustomProductInfoEntity(categoryId)。
*
* @return 配置了 SNAKE_CASE 命名策略的 BeanMapper
*/
public static BeanMapper snakeCase() {
return new BeanMapper(SNAKE_CASE_MAPPER);
}
/**
* 将源对象转换为目标类型
* 支持嵌套对象、集合等复杂结构
*
......@@ -64,7 +101,7 @@ public class BeanMapper {
return null;
}
try {
return OBJECT_MAPPER.convertValue(source, destinationClass);
return this.objectMapper.convertValue(source, destinationClass);
} catch (Exception e) {
throw new RuntimeException("BeanMapper convert failed: " +
"source=" + source.getClass().getName() +
......@@ -88,7 +125,7 @@ public class BeanMapper {
try {
List<D> result = new ArrayList<>(sourceList.size());
for (S source : sourceList) {
result.add(OBJECT_MAPPER.convertValue(source, destinationClass));
result.add(this.objectMapper.convertValue(source, destinationClass));
}
return result;
} catch (Exception e) {
......@@ -110,7 +147,7 @@ public class BeanMapper {
return null;
}
try {
return (T) OBJECT_MAPPER.convertValue(source, source.getClass());
return (T) this.objectMapper.convertValue(source, source.getClass());
} catch (Exception e) {
throw new RuntimeException("BeanMapper copy failed: " +
"source=" + source.getClass().getName(), e);
......
......@@ -21,7 +21,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "VO")
public class CustomProductImageVO implements Serializable {
public class CustomProductImageSnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -35,13 +35,13 @@ public class CustomProductImageVO implements Serializable {
* 商品ID
*/
@Schema(description = "商品ID")
private Integer productId;
private Integer product_id;
/**
* 图片地址
*/
@Schema(description = "图片地址")
private String imageUrl;
private String image_url;
/**
* 排序
......@@ -59,7 +59,7 @@ public class CustomProductImageVO implements Serializable {
*
*/
@Schema(description = "")
private Date createTime;
private Date create_time;
}
......@@ -20,7 +20,7 @@ import java.io.Serializable;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "VO")
public class CustomProductInfoPropertyVO implements Serializable {
public class CustomProductInfoPropertySnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -34,25 +34,24 @@ public class CustomProductInfoPropertyVO implements Serializable {
* custom_product_info表id
*/
@Schema(description = "custom_product_info表id")
private Integer infoId;
private Integer info_id;
/**
* 属性类ID
*/
@Schema(description = "属性类ID")
private Integer propertyId;
private Integer property_id;
/**
* 属性值ID
*/
@Schema(description = "属性值ID")
private Integer valueId;
private Integer value_id;
/**
* 是否为SKU属性
*/
@Schema(description = "是否为SKU属性")
private Boolean skuProperty;
}
package com.jomalls.custom.app.vo;
import com.jomalls.custom.app.dto.CustomProductPropertiesValueDTO;
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.List;
/**
* @Author: Lizh
* @Date: 2026/6/9 11:06
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "CustomProductInfoSkuPropertiesVO")
public class CustomProductInfoSkuPropertiesVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "")
private Integer id;
/**
* 中文名称
*/
@Schema(description = "中文名称")
private String cnname;
/**
* 英文名称
*/
@Schema(description = "英文名称")
private String enname;
/**
* 排序
*/
@Schema(description = "排序")
private Integer sort;
/**
* 是否为SKU属性
*/
@Schema(description = "是否为SKU属性")
private Boolean skuProperty;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private Boolean multi;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private Boolean enable;
/**
* SKU属性
*/
@Schema(description = "SKU属性")
private String categoryInfoId;
/**
* SKU属性值列表
*/
@Schema(description = "SKU属性值列表")
private List<CustomProductPropertiesValueVO> valueList;
/**
* publicData
*/
@Schema(description = "publicData")
private Boolean publicData;
/**
* publicData
*/
@Schema(description = "propertyValueIds")
private List<String> propertyValueIds;
}
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.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 商品完整详情 VO
* <p>
* 对齐 TS 项目 {@code entity/custom_product_info.ts} 的返回结构。
* 包含主表字段 + 所有子实体列表,由 App Service 通过并行单表查询后在 Java 层组合。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "商品完整详情")
public class CustomProductInfoSnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "主键 ID")
private Integer id;
@Schema(description = "SKU")
private String sku;
@Schema(description = "货号")
private String product_no;
@Schema(description = "title")
private String title;
@Schema(description = "商品名称")
private String name;
@Schema(description = "图片集")
private List<String> colorImageList;
@Schema(description = "图片集")
private String color_images;
@Schema(description = "商品主图")
private String img_url;
@Schema(description = "商品类别ID")
private Integer category_id;
@Schema(description = "重量(kg)")
//private BigDecimal weight;
private String weight;
@Schema(description = "最小采购量")
private Integer purchasing_min;
@Schema(description = "工厂价(¥)")
private BigDecimal factory_price;
@Schema(description = "销售价(¥)")
private BigDecimal sales_price;
@Schema(description = "销售价最高价(¥)")
private BigDecimal sales_price_max;
@Schema(description = "状态:1待上架 10已上架 20已下架 30待下架 40已作废")
private Integer status;
@Schema(description = "商品属性分类ID 1")
private Integer property1_cate_id;
@Schema(description = "商品属性分类ID 2")
private Integer property2_cate_id;
@Schema(description = "商品属性分类ID 3")
private Integer property3_cate_id;
@Schema(description = "商品属性英文名称 1")
private String property1_enname;
@Schema(description = "商品属性英文名称 2")
private String property2_enname;
@Schema(description = "商品属性英文名称 3")
private String property3_enname;
@Schema(description = "材质")
private String material;
@Schema(description = "印花类型:0满印 1局部印")
private Integer print_type;
@Schema(description = "产地编码")
private String origin_code;
@Schema(description = "产地中文名")
private String origin_name_cn;
@Schema(description = "产地英文名")
private String origin_name_en;
@Schema(description = "币种编码")
private String currency_code;
@Schema(description = "币种名称")
private String currency_name;
@Schema(description = "产品类型:platform/customer")
private String product_type;
@Schema(description = "工厂ID")
private Integer factory_id;
@Schema(description = "工厂编码")
private String factory_code;
@Schema(description = "是否九猫处理")
private Boolean processing;
@Schema(description = "创建时间")
private Date create_time;
@Schema(description = "更新时间")
private Date update_time;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "默认模ID")
private Integer diy_id;
@Schema(description = "默认模SKU")
private String diy_sku;
@Schema(description = "普通图片列表(type=0)")
private List<CustomProductImageSnakeVO> imageList;
@Schema(description = "商品描述")
private ProductRemarkVO productRemark;
@Schema(description = "商品中文描述")
private ProductRemarkVO productCnRemark;
@Schema(description = "工厂价格关联列表")
private List<CustomProductFactoryPriceRelVO> factoryPriceList;
@Schema(description = "尺码图片列表(type=1)")
private List<CustomProductImageSnakeVO> sizeList;
@Schema(description = "DIY 用户 ID 列表")
private List<Integer> diyUserIds;
@Schema(description = "工艺 ID 列表")
private List<String> craftIds;
@Schema(description = "SKU 子项列表")
private List<CustomProductItemSnakeVO> productList;
@Schema(description = "普通属性列表")
private List<CustomProductInfoPropertySnakeVO> properties;
@Schema(description = "SKU 属性列表")
private List<CustomProductInfoSkuPropertiesVO> skuProperties;
@Schema(description = "普通属性列表")
private List<CustomProductInfoSkuPropertiesVO> normalProperties;
@Schema(description = "工厂 ID 列表")
private List<Integer> factoryIds;
@Schema(description = "仓库 ID 列表")
private List<Integer> warehouseIds;
@Schema(description = "英文备注内容")
private String remark;
@Schema(description = "中文备注内容")
private String cnRemark;
}
......@@ -22,7 +22,7 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "VO")
public class CustomProductItemVO implements Serializable {
public class CustomProductItemSnakeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
......@@ -36,7 +36,7 @@ public class CustomProductItemVO implements Serializable {
* 商品ID
*/
@Schema(description = "商品ID")
private Integer productId;
private Integer product_id;
/**
* sku
......@@ -48,7 +48,13 @@ public class CustomProductItemVO implements Serializable {
* sku商品名称
*/
@Schema(description = "sku商品名称")
private String skuName;
private String sku_name;
/**
* 货号
*/
@Schema(description = "货号")
private String product_no;
/**
* 封面图
......@@ -60,151 +66,138 @@ public class CustomProductItemVO implements Serializable {
* 图片集
*/
@Schema(description = "图片集")
private String imageAry;
private String image_ary;
/**
* 属性分类ID1
*/
@Schema(description = "属性分类ID1")
private Integer propertyCateId1;
private Integer property_cate_id1;
/**
* 属性分类ID2
*/
@Schema(description = "属性分类ID2")
private Integer propertyCateId2;
private Integer property_cate_id2;
/**
* 属性分类ID3
*/
@Schema(description = "属性分类ID3")
private Integer propertyCateId3;
private Integer property_cate_id3;
/**
*
*/
@Schema(description = "")
private Integer property1Id;
private Integer property1_id;
/**
*
*/
@Schema(description = "")
private Integer property2Id;
private Integer property2_id;
/**
*
*/
@Schema(description = "")
private Integer property3Id;
private Integer property3_id;
/**
* 属性编码1
*/
@Schema(description = "属性编码1")
private String propertyCode1;
private String property_code1;
/**
* 属性编码2
*/
@Schema(description = "属性编码2")
private String propertyCode2;
private String property_code2;
/**
*
*/
@Schema(description = "")
private String propertyCode3;
private String property_code3;
/**
* 属性名称1
*/
@Schema(description = "属性名称1")
private String optionEnname1;
private String option_enname1;
/**
* 属性名称2
*/
@Schema(description = "属性名称2")
private String optionEnname2;
private String option_enname2;
/**
*
*/
@Schema(description = "")
private String optionEnname3;
private String option_enname3;
/**
*
*/
@Schema(description = "")
private String customValue1;
private String custom_value1;
/**
*
*/
@Schema(description = "")
private String customValue2;
private String custom_value2;
/**
*
*/
@Schema(description = "")
private String customValue3;
private String custom_value3;
/**
* 工厂价
*/
@Schema(description = "工厂价")
private BigDecimal factoryPrice;
private BigDecimal factory_price;
/**
* 销售价
*/
@Schema(description = "销售价")
private BigDecimal salesPrice;
private BigDecimal sales_price;
/**
* sku克重
*/
@Schema(description = "sku克重")
private BigDecimal skuWeight;
private BigDecimal sku_weight;
/**
* 印花类型 0满印 1局部印
*/
@Schema(description = "印花类型 0满印 1局部印")
private Integer printType;
/**
* 排序
*/
@Schema(description = "排序")
private Integer sort;
/**
* 货号
*/
@Schema(description = "货号")
private String productNo;
private Integer print_type;
/**
* 1正常码 2大码
*/
@Schema(description = "1正常码 2大码")
private Integer sizeType;
private Integer size_type;
/**
* 创建时间
* 排序
*/
@Schema(description = "创建时间")
private Date createTime;
@Schema(description = "排序")
private Integer sort;
/**
* 更新时间
* 创建时间
*/
@Schema(description = "更新时间")
private Date updateTime;
@Schema(description = "创建时间")
private Date create_time;
}
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;
/**
* @Author: Lizh
* @Date: 2026/6/9 11:10
* @Description:
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "CustomProductPropertiesValueVO")
public class CustomProductPropertiesValueVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@Schema(description = "")
private Integer id;
/**
* 类别编码
*/
@Schema(description = "类别编码")
private String cateCode;
/**
* 类别名称
*/
@Schema(description = "类别名称")
private String cateName;
/**
* 编码
*/
@Schema(description = "编码")
private String code;
/**
* 中文名称
*/
@Schema(description = "中文名称")
private String cnname;
/**
* 英文名称
*/
@Schema(description = "英文名称")
private String enname;
/**
* 前景色
*/
@Schema(description = "前景色")
private String fontColor;
/**
* 背景色
*/
@Schema(description = "背景色")
private String bgColor;
/**
*
*/
@Schema(description = "")
private Boolean battery;
/**
*
*/
@Schema(description = "")
private Boolean liquid;
/**
*
*/
@Schema(description = "")
private Boolean knife;
/**
*
*/
@Schema(description = "")
private Integer selected;
/**
* 排序
*/
@Schema(description = "")
private Integer sort;
/**
*
*/
@Schema(description = "")
private Boolean enable;
/**
*
*/
@Schema(description = "")
private Boolean publicData;
}
package com.jomalls.custom.app.vo;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 产品-工厂关联 分页 VO
*
* @author Lizh
* @date 2026-06-06
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Schema(description = "产品-工厂关联分页VO")
public class ProductFactoryRelPageVO extends PageRequest {
@Serial
private static final long serialVersionUID = 1L;
}
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;
/**
* 产品-工厂关联 VO
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "产品-工厂关联VO")
public class ProductFactoryRelVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "主键")
private Integer id;
@Schema(description = "产品 ID")
private Integer productId;
@Schema(description = "工厂 ID")
private Integer factoryId;
}
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.Serializable;
/**
* @Author: Lizh
* @Date: 2026/6/9 10:50
* @Description: 商品描述
* @Version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "商品描述信息")
public class ProductRemarkVO implements Serializable {
/**
*
*/
@Schema(description = "")
private Integer id;
/**
* 商品ID
*/
@Schema(description = "商品ID")
private Integer product_id;
/**
* 描述
*/
@Schema(description = "图片地址")
private String remark;
}
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;
/**
* DIY 用户实体
* <p>
* 对齐 TS 项目 {@code DbDiyUser} 实体。
* 用于 namespace 用户查询和外部定价折扣计算。
*
* @author Lizh
* @date 2026-06-08
*/
@Data
@TableName("db_diy_user")
public class DbDiyUserEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/** 用户唯一标识 */
@TableField("sku")
private String sku;
/** 用户名称(namespace 即此字段) */
@TableField("name")
private String name;
/** 用户名称-中文 */
@TableField("name_cn")
private String nameCn;
/** 用户类型:1 ERP客户 2 非ERP客户 */
@TableField("user_type")
private Integer userType;
/** 用户标识 */
@TableField("user_mark")
private String userMark;
/** 折扣(百分比,如 85 表示 85%) */
@TableField("discount")
private BigDecimal discount;
/** 余额 */
@TableField("balance")
private BigDecimal balance;
/** 状态 */
@TableField("status")
private Integer status;
}
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;
/**
* DIY 效果图实体
* <p>
* 对齐 TS 项目 {@code DbDiyXiaoguotu} 实体(db_diy_xiaoguotu 表)。
*
* @author Lizh
* @date 2026-06-08
*/
@Data
@TableName("db_diy_xiaoguotu")
public class DbDiyXiaoguotuEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/** 标题 */
@TableField("title")
private String title;
/** 排序 */
@TableField("idx")
private Integer idx;
/** 效果图主图 */
@TableField("img_url")
private String imgUrl;
/** PSD 链接 */
@TableField("psd_url")
private String psdUrl;
/** 颜色 ID */
@TableField("color_id")
private Integer colorId;
/** 宽度 */
@TableField("width")
private Float width;
/** 高度 */
@TableField("height")
private Float height;
/** 分辨率 */
@TableField("dpi")
private Integer dpi;
/** db_diy 表 ID */
@TableField("diy_id")
private Integer diyId;
/** 状态:1 正常 0 禁用 */
@TableField("status")
private Integer status;
/** 层面 IDs */
@TableField("face_ids")
private String faceIds;
/** 是否允许设计 */
@TableField("enable_design")
private Boolean enableDesign;
/** 创建时间 */
@TableField("create_date")
private Date createDate;
}
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;
/**
* 产品-工厂关联表 Entity
* <p>
* 对齐 TS 项目 {@code entity/product_factory_rel.ts},表 {@code product_factory_rel}。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@TableName("product_factory_rel")
public class ProductFactoryRelEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/** custom_product_info 表 ID */
@TableField("product_id")
private Integer productId;
/** 工厂 ID */
@TableField("factory_id")
private Integer factoryId;
}
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 ProductTemplateInfo} 实体(product_template_info 表)。
*
* @author Lizh
* @date 2026-06-08
*/
@Data
@TableName("product_template_info")
public class ProductTemplateInfoEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("sku")
private String sku;
/** custom_product_info 表 ID */
@TableField("product_id")
private Integer productId;
@TableField("product_sku")
private String productSku;
/** 模板 ID(db_diy 表) */
@TableField("diy_id")
private Integer diyId;
@TableField("name")
private String name;
@TableField("title")
private String title;
@TableField("category_id")
private Integer categoryId;
@TableField("style_id")
private Integer styleId;
@TableField("cost_price")
private BigDecimal costPrice;
@TableField("cost_price_max")
private BigDecimal costPriceMax;
@TableField("sales_price")
private BigDecimal salesPrice;
@TableField("sales_price_max")
private BigDecimal salesPriceMax;
@TableField("property1_cate_id")
private Integer property1CateId;
@TableField("property2_cate_id")
private Integer property2CateId;
@TableField("property3_cate_id")
private Integer property3CateId;
@TableField("property1_enname")
private String property1Enname;
@TableField("property2_enname")
private String property2Enname;
@TableField("property3_enname")
private String property3Enname;
@TableField("color_images")
private String colorImages;
@TableField("material")
private String material;
@TableField("print_type")
private Integer printType;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
}
......@@ -3,6 +3,7 @@ package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.CustomProductInfoEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author Lizh
......@@ -12,4 +13,12 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface CustomProductInfoMapper extends BaseMapper<CustomProductInfoEntity> {
/**
* 根据 SKU 查询商品
*
* @param sku 商品 SKU
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity selectBySku(@Param("sku") String sku);
}
......@@ -3,6 +3,9 @@ package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity;
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,9 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface CustomProductWarehouseRelMapper extends BaseMapper<CustomProductWarehouseRelEntity> {
/**
* 根据仓库 ID 列表查询关联关系
*/
List<CustomProductWarehouseRelEntity> selectByWarehouseIds(@Param("warehouseIds") List<Integer> warehouseIds);
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* DbDiyUser Mapper
*
* @author Lizh
* @date 2026-06-08
*/
@Mapper
public interface DbDiyUserMapper extends BaseMapper<DbDiyUserEntity> {
/**
* 根据 namespace(name 字段)查询用户
*
* @param name 用户名称
* @return 用户实体
*/
DbDiyUserEntity selectByName(@Param("name") String name);
/**
* 根据 userMark 查询用户(对齐 TS getByUserMark)
*
* @param userMark 用户标识
* @return 用户实体
*/
DbDiyUserEntity selectByUserMark(@Param("userMark") String userMark);
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.DbDiyXiaoguotuEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* DbDiyXiaoguotu Mapper
*
* @author Lizh
* @date 2026-06-08
*/
@Mapper
public interface DbDiyXiaoguotuMapper extends BaseMapper<DbDiyXiaoguotuEntity> {
/**
* 根据模板 ID 查询效果图列表
*/
List<DbDiyXiaoguotuEntity> selectByDiyId(@Param("diyId") Integer diyId);
/**
* 根据模板 ID 列表批量查询效果图
*/
List<DbDiyXiaoguotuEntity> selectByDiyIds(@Param("diyIds") List<Integer> diyIds);
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.ProductFactoryRelEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 产品-工厂关联 Mapper
*
* @author Lizh
* @date 2026-06-06
*/
@Mapper
public interface ProductFactoryRelMapper extends BaseMapper<ProductFactoryRelEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.ProductTemplateInfoEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* ProductTemplateInfo Mapper
*
* @author Lizh
* @date 2026-06-08
*/
@Mapper
public interface ProductTemplateInfoMapper extends BaseMapper<ProductTemplateInfoEntity> {
/**
* 根据产品 ID 查询模板关联列表
*
* @param productId 产品 ID
* @return 模板信息列表
*/
List<ProductTemplateInfoEntity> selectByProductId(@Param("productId") Integer productId);
/**
* 根据模板 ID 列表查询
*
* @param diyIds 模板 ID 列表
* @return 模板信息列表
*/
List<ProductTemplateInfoEntity> selectByDiyIds(@Param("diyIds") List<Integer> diyIds);
}
......@@ -11,5 +11,12 @@ import com.jomalls.custom.service.IBaseService;
*/
public interface CustomProductInfoDomainService extends IBaseService<CustomProductInfoEntity> {
/**
* 根据 SKU 查询商品
*
* @param sku 商品 SKU
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity getBySku(String sku);
}
......@@ -3,6 +3,8 @@ package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* @author Lizh
* @version 0.01
......@@ -11,5 +13,8 @@ import com.jomalls.custom.service.IBaseService;
*/
public interface CustomProductWarehouseRelDomainService extends IBaseService<CustomProductWarehouseRelEntity> {
/**
* 根据仓库 ID 列表查询关联
*/
List<CustomProductWarehouseRelEntity> selectByWarehouseIds(List<Integer> warehouseIds);
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
import com.jomalls.custom.service.IBaseService;
/**
* DbDiyUser 领域服务接口
*
* @author Lizh
* @date 2026-06-08
*/
public interface DbDiyUserDomainService extends IBaseService<DbDiyUserEntity> {
/**
* 根据 namespace(name 字段)查询用户
* <p>
* 对齐 TS {@code diyUserService.getByNamespace()}
*
* @param namespace 用户名称
* @return 用户实体,未找到返回 null
*/
DbDiyUserEntity getByNamespace(String namespace);
/**
* 根据 userMark 查询用户
* <p>
* 对齐 TS {@code diyUserService.getByUserMark()}
*/
DbDiyUserEntity getByUserMark(String userMark);
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.DbDiyXiaoguotuEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* DbDiyXiaoguotu 领域服务接口
*
* @author Lizh
* @date 2026-06-08
*/
public interface DbDiyXiaoguotuDomainService extends IBaseService<DbDiyXiaoguotuEntity> {
List<DbDiyXiaoguotuEntity> selectByDiyId(Integer diyId);
List<DbDiyXiaoguotuEntity> selectByDiyIds(List<Integer> diyIds);
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.ProductFactoryRelEntity;
import com.jomalls.custom.service.IBaseService;
/**
* 产品-工厂关联 Domain Service 接口
*
* @author Lizh
* @date 2026-06-06
*/
public interface ProductFactoryRelDomainService extends IBaseService<ProductFactoryRelEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.ProductTemplateInfoEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* ProductTemplateInfo 领域服务接口
*
* @author Lizh
* @date 2026-06-08
*/
public interface ProductTemplateInfoDomainService extends IBaseService<ProductTemplateInfoEntity> {
/**
* 根据产品 ID 查询模板关联列表
*/
List<ProductTemplateInfoEntity> selectByProductId(Integer productId);
/**
* 根据模板 ID 列表查询
*/
List<ProductTemplateInfoEntity> selectByDiyIds(List<Integer> diyIds);
}
......@@ -4,6 +4,7 @@ import com.jomalls.custom.dal.mapper.CustomProductInfoMapper;
import com.jomalls.custom.dal.entity.CustomProductInfoEntity;
import com.jomalls.custom.domain.service.CustomProductInfoDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -22,6 +23,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr
public CustomProductInfoDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
@Override
public CustomProductInfoEntity getBySku(String sku) {
return baseMapper.selectBySku(sku);
}
}
\ No newline at end of file
......@@ -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,8 @@ public class CustomProductWarehouseRelDomainServiceImpl extends BaseServiceImpl<
public CustomProductWarehouseRelDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
@Override
public List<CustomProductWarehouseRelEntity> selectByWarehouseIds(List<Integer> warehouseIds) {
return baseMapper.selectByWarehouseIds(warehouseIds);
}
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.entity.DbDiyUserEntity;
import com.jomalls.custom.dal.mapper.DbDiyUserMapper;
import com.jomalls.custom.domain.service.DbDiyUserDomainService;
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;
/**
* DbDiyUser 领域服务实现
*
* @author Lizh
* @date 2026-06-08
*/
@Slf4j
@Service
public class DbDiyUserDomainServiceImpl extends BaseServiceImpl<DbDiyUserMapper, DbDiyUserEntity> implements DbDiyUserDomainService {
@Autowired
public DbDiyUserDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
@Override
public DbDiyUserEntity getByNamespace(String namespace) {
return baseMapper.selectByName(namespace);
}
@Override
public DbDiyUserEntity getByUserMark(String userMark) {
return baseMapper.selectByUserMark(userMark);
}
}
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.entity.DbDiyXiaoguotuEntity;
import com.jomalls.custom.dal.mapper.DbDiyXiaoguotuMapper;
import com.jomalls.custom.domain.service.DbDiyXiaoguotuDomainService;
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.Collections;
import java.util.List;
/**
* DbDiyXiaoguotu 领域服务实现
*
* @author Lizh
* @date 2026-06-08
*/
@Slf4j
@Service
public class DbDiyXiaoguotuDomainServiceImpl
extends BaseServiceImpl<DbDiyXiaoguotuMapper, DbDiyXiaoguotuEntity>
implements DbDiyXiaoguotuDomainService {
@Autowired
public DbDiyXiaoguotuDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
@Override
public List<DbDiyXiaoguotuEntity> selectByDiyId(Integer diyId) {
return baseMapper.selectByDiyId(diyId);
}
@Override
public List<DbDiyXiaoguotuEntity> selectByDiyIds(List<Integer> diyIds) {
if (diyIds == null || diyIds.isEmpty()) {
return Collections.emptyList();
}
return baseMapper.selectByDiyIds(diyIds);
}
}
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.ProductFactoryRelMapper;
import com.jomalls.custom.dal.entity.ProductFactoryRelEntity;
import com.jomalls.custom.domain.service.ProductFactoryRelDomainService;
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-06
*/
@Service
public class ProductFactoryRelDomainServiceImpl
extends BaseServiceImpl<ProductFactoryRelMapper, ProductFactoryRelEntity>
implements ProductFactoryRelDomainService {
@Autowired
public ProductFactoryRelDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
}
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.entity.ProductTemplateInfoEntity;
import com.jomalls.custom.dal.mapper.ProductTemplateInfoMapper;
import com.jomalls.custom.domain.service.ProductTemplateInfoDomainService;
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;
/**
* ProductTemplateInfo 领域服务实现
*
* @author Lizh
* @date 2026-06-08
*/
@Slf4j
@Service
public class ProductTemplateInfoDomainServiceImpl
extends BaseServiceImpl<ProductTemplateInfoMapper, ProductTemplateInfoEntity>
implements ProductTemplateInfoDomainService {
@Autowired
public ProductTemplateInfoDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
@Override
public List<ProductTemplateInfoEntity> selectByProductId(Integer productId) {
return baseMapper.selectByProductId(productId);
}
@Override
public List<ProductTemplateInfoEntity> selectByDiyIds(List<Integer> diyIds) {
if (diyIds == null || diyIds.isEmpty()) {
return List.of();
}
return baseMapper.selectByDiyIds(diyIds);
}
}
......@@ -15,4 +15,12 @@
product_id,
diy_user_id
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_blacklist (product_id, diy_user_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.diyUserId})
</foreach>
</insert>
</mapper>
......@@ -17,4 +17,12 @@
remark,
create_time
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_cn_remark (product_id, remark, create_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.remark}, #{item.createTime})
</foreach>
</insert>
</mapper>
......@@ -15,4 +15,12 @@
product_id,
craft_id
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_craft_rel (product_id, craft_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.craftId})
</foreach>
</insert>
</mapper>
......@@ -15,4 +15,12 @@
product_id,
diy_user_id
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_diy_user_rel (product_id, diy_user_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.diyUserId})
</foreach>
</insert>
</mapper>
......@@ -19,4 +19,12 @@
price_max,
price_min
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_factory_price_interval_rel (product_id, currency_code, price_max, price_min) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.currencyCode}, #{item.priceMax}, #{item.priceMin})
</foreach>
</insert>
</mapper>
......@@ -31,4 +31,12 @@
create_time,
update_time
</sql>
<!-- 批量插入 -->
<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
<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})
</foreach>
</insert>
</mapper>
......@@ -21,4 +21,12 @@
type,
create_time
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_image (product_id, image_url, sort, type, create_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.imageUrl}, #{item.sort}, #{item.type}, #{item.createTime})
</foreach>
</insert>
</mapper>
......@@ -81,4 +81,20 @@
diy_id,
diy_sku
</sql>
<!-- 根据 SKU 查询商品 -->
<select id="selectBySku" resultMap="customProductInfoMap">
SELECT <include refid="tableColumns"/>
FROM custom_product_info
WHERE sku = #{sku}
LIMIT 1
</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
<foreach collection="list" item="item" separator=",">
(#{item.sku}, #{item.title}, #{item.name}, #{item.imgUrl}, #{item.categoryId}, #{item.weight}, #{item.purchasingMin}, #{item.factoryPrice}, #{item.salesPrice}, #{item.salesPriceMax}, #{item.status}, #{item.property1CateId}, #{item.property2CateId}, #{item.property3CateId}, #{item.property1Enname}, #{item.property2Enname}, #{item.property3Enname}, #{item.colorImages}, #{item.material}, #{item.printType}, #{item.productNo}, #{item.originCode}, #{item.originNameCn}, #{item.originNameEn}, #{item.currencyCode}, #{item.currencyName}, #{item.productType}, #{item.factoryId}, #{item.factoryCode}, #{item.processing}, #{item.createTime}, #{item.updateTime}, #{item.sort}, #{item.diyId}, #{item.diySku})
</foreach>
</insert>
</mapper>
......@@ -19,4 +19,12 @@
value_id,
sku_property
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_info_property (info_id, property_id, value_id, sku_property) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.infoId}, #{item.propertyId}, #{item.valueId}, #{item.skuProperty})
</foreach>
</insert>
</mapper>
......@@ -69,4 +69,12 @@
create_time,
update_time
</sql>
<!-- 批量插入 -->
<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
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.sku}, #{item.skuName}, #{item.image}, #{item.imageAry}, #{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.factoryPrice}, #{item.salesPrice}, #{item.skuWeight}, #{item.printType}, #{item.sort}, #{item.productNo}, #{item.sizeType}, #{item.createTime}, #{item.updateTime})
</foreach>
</insert>
</mapper>
......@@ -17,4 +17,12 @@
remark,
create_time
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_remark (product_id, remark, create_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.remark}, #{item.createTime})
</foreach>
</insert>
</mapper>
......@@ -15,4 +15,22 @@
product_id,
warehouse_id
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_product_warehouse_rel (product_id, warehouse_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.warehouseId})
</foreach>
</insert>
<!-- 根据仓库 ID 列表查询关联 -->
<select id="selectByWarehouseIds" resultMap="customProductWarehouseRelMap">
SELECT <include refid="tableColumns"/>
FROM custom_product_warehouse_rel
WHERE warehouse_id IN
<foreach collection="warehouseIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper>
......@@ -79,4 +79,12 @@
settlement_currency,
company_name_cn
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO custom_warehouse_info (warehouse_name, warehouse_code, overall_logistics, super_factory, system_logistics, overall_logistics_scope, contact_name, contact_phone, contact_email, country_code, country_name, province, province_code, province_abb, city, city_code, district, street, postcode, company_name, social_credit_code, remarks, update_time, create_time, status, contact_name_cn, country_name_cn, province_cn, city_cn, district_cn, street_cn, formal, settlement_currency, company_name_cn) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.warehouseName}, #{item.warehouseCode}, #{item.overallLogistics}, #{item.superFactory}, #{item.systemLogistics}, #{item.overallLogisticsScope}, #{item.contactName}, #{item.contactPhone}, #{item.contactEmail}, #{item.countryCode}, #{item.countryName}, #{item.province}, #{item.provinceCode}, #{item.provinceAbb}, #{item.city}, #{item.cityCode}, #{item.district}, #{item.street}, #{item.postcode}, #{item.companyName}, #{item.socialCreditCode}, #{item.remarks}, #{item.updateTime}, #{item.createTime}, #{item.status}, #{item.contactNameCn}, #{item.countryNameCn}, #{item.provinceCn}, #{item.cityCn}, #{item.districtCn}, #{item.streetCn}, #{item.formal}, #{item.settlementCurrency}, #{item.companyNameCn})
</foreach>
</insert>
</mapper>
......@@ -107,4 +107,12 @@
new_standard,
diy_remark
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO db_diy (sku, title, en_name, idx, img_url, img_arr, bianma, content, leixing, sc_img_type, chima_now_render, render, parent_id, user_ids, ban_user_ids, type_id, status, create_date, default_diy_id, factory_id, print_type, material, craft_id, min_price, max_price, picture_status, remark, namespace, audit_id, audit_name, audit_date, shelf_date, template_id, category_id, allocation_id, allocation_name, expedited, bind_diy_ids, is_bind, usa_made, manufacturer, style_num, type, production_client, erp_sku_properties, push_user, new_standard, diy_remark) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.sku}, #{item.title}, #{item.enName}, #{item.idx}, #{item.imgUrl}, #{item.imgArr}, #{item.bianma}, #{item.content}, #{item.leixing}, #{item.scImgType}, #{item.chimaNowRender}, #{item.render}, #{item.parentId}, #{item.userIds}, #{item.banUserIds}, #{item.typeId}, #{item.status}, #{item.createDate}, #{item.defaultDiyId}, #{item.factoryId}, #{item.printType}, #{item.material}, #{item.craftId}, #{item.minPrice}, #{item.maxPrice}, #{item.pictureStatus}, #{item.remark}, #{item.namespace}, #{item.auditId}, #{item.auditName}, #{item.auditDate}, #{item.shelfDate}, #{item.templateId}, #{item.categoryId}, #{item.allocationId}, #{item.allocationName}, #{item.expedited}, #{item.bindDiyIds}, #{item.isBind}, #{item.usaMade}, #{item.manufacturer}, #{item.styleNum}, #{item.type}, #{item.productionClient}, #{item.erpSkuProperties, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler}, #{item.pushUser}, #{item.newStandard}, #{item.diyRemark})
</foreach>
</insert>
</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.DbDiyUserMapper">
<resultMap type="com.jomalls.custom.dal.entity.DbDiyUserEntity" id="dbDiyUserMap">
<result property="id" column="id"/>
<result property="sku" column="sku"/>
<result property="name" column="name"/>
<result property="nameCn" column="name_cn"/>
<result property="userType" column="user_type"/>
<result property="userMark" column="user_mark"/>
<result property="discount" column="discount"/>
<result property="balance" column="balance"/>
<result property="status" column="status"/>
</resultMap>
<sql id="tableColumns">
id,
sku,
name,
name_cn,
user_type,
user_mark,
discount,
balance,
status
</sql>
<!-- 根据 namespace 查询用户(对齐 TS getByNamespace) -->
<select id="selectByName" resultMap="dbDiyUserMap">
SELECT <include refid="tableColumns"/>
FROM db_diy_user
WHERE name = #{name}
LIMIT 1
</select>
<!-- 根据 userMark 查询用户(对齐 TS getByUserMark) -->
<select id="selectByUserMark" resultMap="dbDiyUserMap">
SELECT <include refid="tableColumns"/>
FROM db_diy_user
WHERE user_mark = #{userMark}
LIMIT 1
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO db_diy_user (sku, name, name_cn, user_type, user_mark, discount, balance, status) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.sku}, #{item.name}, #{item.nameCn}, #{item.userType}, #{item.userMark}, #{item.discount}, #{item.balance}, #{item.status})
</foreach>
</insert>
</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.DbDiyXiaoguotuMapper">
<resultMap type="com.jomalls.custom.dal.entity.DbDiyXiaoguotuEntity" id="dbDiyXiaoguotuMap">
<result property="id" column="id"/>
<result property="title" column="title"/>
<result property="idx" column="idx"/>
<result property="imgUrl" column="img_url"/>
<result property="psdUrl" column="psd_url"/>
<result property="colorId" column="color_id"/>
<result property="width" column="width"/>
<result property="height" column="height"/>
<result property="dpi" column="dpi"/>
<result property="diyId" column="diy_id"/>
<result property="status" column="status"/>
<result property="faceIds" column="face_ids"/>
<result property="enableDesign" column="enable_design"/>
<result property="createDate" column="create_date"/>
</resultMap>
<sql id="tableColumns">
id, title, idx, img_url, psd_url, color_id, width, height, dpi, diy_id,
status, face_ids, enable_design, create_date
</sql>
<select id="selectByDiyId" resultMap="dbDiyXiaoguotuMap">
SELECT <include refid="tableColumns"/>
FROM db_diy_xiaoguotu
WHERE diy_id = #{diyId}
ORDER BY idx ASC
</select>
<select id="selectByDiyIds" resultMap="dbDiyXiaoguotuMap">
SELECT <include refid="tableColumns"/>
FROM db_diy_xiaoguotu
WHERE diy_id IN
<foreach collection="diyIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
ORDER BY idx ASC
</select>
<insert id="insertBatchSomeColumn">
INSERT INTO db_diy_xiaoguotu (title, idx, img_url, psd_url, color_id, width, height,
dpi, diy_id, status, face_ids, enable_design, create_date) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.title}, #{item.idx}, #{item.imgUrl}, #{item.psdUrl}, #{item.colorId},
#{item.width}, #{item.height}, #{item.dpi}, #{item.diyId}, #{item.status},
#{item.faceIds}, #{item.enableDesign}, #{item.createDate})
</foreach>
</insert>
</mapper>
......@@ -21,4 +21,12 @@
description,
create_time
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO log_custom_product (product_id, employee_id, employee_account, description, create_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.employeeId}, #{item.employeeAccount}, #{item.description}, #{item.createTime})
</foreach>
</insert>
</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.ProductFactoryRelMapper">
<resultMap type="com.jomalls.custom.dal.entity.ProductFactoryRelEntity" id="productFactoryRelMap">
<result property="id" column="id"/>
<result property="productId" column="product_id"/>
<result property="factoryId" column="factory_id"/>
</resultMap>
<sql id="tableColumns">
id,
product_id,
factory_id
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO product_factory_rel (product_id, factory_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.productId}, #{item.factoryId})
</foreach>
</insert>
</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.ProductTemplateInfoMapper">
<resultMap type="com.jomalls.custom.dal.entity.ProductTemplateInfoEntity" id="productTemplateInfoMap">
<result property="id" column="id"/>
<result property="sku" column="sku"/>
<result property="productId" column="product_id"/>
<result property="productSku" column="product_sku"/>
<result property="diyId" column="diy_id"/>
<result property="name" column="name"/>
<result property="title" column="title"/>
<result property="categoryId" column="category_id"/>
<result property="styleId" column="style_id"/>
<result property="costPrice" column="cost_price"/>
<result property="costPriceMax" column="cost_price_max"/>
<result property="salesPrice" column="sales_price"/>
<result property="salesPriceMax" column="sales_price_max"/>
<result property="property1CateId" column="property1_cate_id"/>
<result property="property2CateId" column="property2_cate_id"/>
<result property="property3CateId" column="property3_cate_id"/>
<result property="property1Enname" column="property1_enname"/>
<result property="property2Enname" column="property2_enname"/>
<result property="property3Enname" column="property3_enname"/>
<result property="colorImages" column="color_images"/>
<result property="material" column="material"/>
<result property="printType" column="print_type"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="tableColumns">
id, sku, product_id, product_sku, diy_id, name, title, category_id, style_id,
cost_price, cost_price_max, sales_price, sales_price_max,
property1_cate_id, property2_cate_id, property3_cate_id,
property1_enname, property2_enname, property3_enname,
color_images, material, print_type, create_time, update_time
</sql>
<!-- 根据产品 ID 查询模板关联 -->
<select id="selectByProductId" resultMap="productTemplateInfoMap">
SELECT <include refid="tableColumns"/>
FROM product_template_info
WHERE product_id = #{productId}
</select>
<!-- 根据模板 ID 列表查询 -->
<select id="selectByDiyIds" resultMap="productTemplateInfoMap">
SELECT <include refid="tableColumns"/>
FROM product_template_info
WHERE diy_id IN
<foreach collection="diyIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO product_template_info (sku, product_id, product_sku, diy_id, name, title, category_id, style_id,
cost_price, cost_price_max, sales_price, sales_price_max,
property1_cate_id, property2_cate_id, property3_cate_id,
property1_enname, property2_enname, property3_enname,
color_images, material, print_type, create_time, update_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.sku}, #{item.productId}, #{item.productSku}, #{item.diyId}, #{item.name}, #{item.title},
#{item.categoryId}, #{item.styleId}, #{item.costPrice}, #{item.costPriceMax}, #{item.salesPrice},
#{item.salesPriceMax}, #{item.property1CateId}, #{item.property2CateId}, #{item.property3CateId},
#{item.property1Enname}, #{item.property2Enname}, #{item.property3Enname},
#{item.colorImages}, #{item.material}, #{item.printType}, #{item.createTime}, #{item.updateTime})
</foreach>
</insert>
</mapper>
......@@ -38,4 +38,12 @@
FOR UPDATE
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_bill_rule (name, code, short_name, date_type, example, space_mark, start_number, current_number, enable_flag, last_no) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.name}, #{item.code}, #{item.shortName}, #{item.dateType}, #{item.example}, #{item.spaceMark}, #{item.startNumber}, #{item.currentNumber}, #{item.enableFlag}, #{item.lastNo})
</foreach>
</insert>
</mapper>
......@@ -62,4 +62,12 @@
AND m.perms IS NOT NULL
AND m.perms != ''
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.menuName}, #{item.parentId}, #{item.orderNum}, #{item.path}, #{item.component}, #{item.query}, #{item.routeName}, #{item.isFrame}, #{item.isCache}, #{item.menuType}, #{item.visible}, #{item.status}, #{item.perms}, #{item.icon}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark})
</foreach>
</insert>
</mapper>
......@@ -13,4 +13,12 @@
role_id,
dept_id,
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_role_dept (role_id, dept_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.roleId}, #{item.deptId})
</foreach>
</insert>
</mapper>
......@@ -45,4 +45,12 @@
LEFT JOIN sys_role r ON ur.role_id = r.role_id
WHERE ur.user_id = #{userId} AND r.del_flag = '0' AND r.status = '0'
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_role (role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, update_by, update_time, remark) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.roleName}, #{item.roleKey}, #{item.roleSort}, #{item.dataScope}, #{item.menuCheckStrictly}, #{item.deptCheckStrictly}, #{item.status}, #{item.delFlag}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark})
</foreach>
</insert>
</mapper>
......@@ -13,4 +13,12 @@
role_id,
menu_id,
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_role_menu (role_id, menu_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.roleId}, #{item.menuId})
</foreach>
</insert>
</mapper>
......@@ -48,4 +48,13 @@
ORDER BY created_at DESC
</select>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_user (username, password, email, phone, status, created_at, updated_at) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.username}, #{item.password}, #{item.email}, #{item.phone}, #{item.status}, #{item.createdAt}, #{item.updatedAt})
</foreach>
</insert>
</mapper>
\ No newline at end of file
......@@ -23,4 +23,12 @@
remark,
create_time,
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_user_old (account, img_url, password, status, remark, create_time) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.account}, #{item.imgUrl}, #{item.password}, #{item.status}, #{item.remark}, #{item.createTime})
</foreach>
</insert>
</mapper>
......@@ -13,4 +13,12 @@
user_id,
role_id,
</sql>
<!-- 批量插入 -->
<insert id="insertBatchSomeColumn">
INSERT INTO sys_user_role (user_id, role_id) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.userId}, #{item.roleId})
</foreach>
</insert>
</mapper>
......@@ -6,6 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
......@@ -19,8 +20,9 @@ import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "商品分类")
public class BaseCategoryInfoVO implements Serializable {
public class BaseCategoryInfoModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Integer id;
......
package com.jomalls.custom.integrate.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 基础属性 VO(admin API 返回)
* <p>
* 对齐 TS 项目 {@code basePropertyService.getByIds()} 的返回结构。
*
* @author Lizh
* @date 2026-06-08
*/
@Data
public class BasePropertyModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 属性 ID */
private Integer id;
/** 中文名称 */
private String cnname;
/** 英文名称 */
private String enname;
/** 排序 */
private Integer sort;
/** 是否是 SKU 属性 */
private Boolean skuProperty;
/** 是否多选 */
private Boolean multi;
/** 是否启用 */
private Boolean enable;
/** 分类信息 ID */
private String categoryInfoId;
/** 属性值列表 */
@JsonProperty("valueList")
private List<BasePropertyValueModel> valueList;
/** 是否公共数据 */
private Boolean publicData;
/** 属性值 ID 列表 */
private String propertyValueIds;
}
package com.jomalls.custom.integrate.model;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 属性值 VO
*
* @author Lizh
* @date 2026-06-08
*/
@Data
public class BasePropertyValueModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 属性值 ID */
private Integer id;
/** 分类编码 */
private String cateCode;
/** 分类名称 */
private String cateName;
/** 编码 */
private String code;
/** 属性值名称(中文) */
private String cnname;
/** 属性值名称(英文) */
private String enname;
/** 前景色 */
private String fontColor;
/** 背景色 */
private String bgColor;
/** 是否为电池属性 */
private Boolean battery;
/** 是否为液体属性 */
private Boolean liquid;
/** 是否为刀片属性 */
private Boolean knife;
/** 是否为选中属性 */
private Integer selected;
/** 排序 */
private Integer sort;
/** 是否启用 */
private Boolean enable;
/** 是否为公共数据 */
private Boolean publicData;
}
package com.jomalls.custom.integrate.model;
import lombok.Data;
/**
* @Author: Lizh
* @Date: 2026/6/9 14:39
* @Description: SaasAdmin返回数据
* @Version: 1.0
*/
@Data
public class SaasAdminApiResponseModel<T> {
private Integer code;
private T data;
private String requestId;
private String message;
}
package com.jomalls.custom.integrate.service;
import com.jomalls.custom.integrate.model.BaseCategoryInfoVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class BaseCategoryInfoService {
private static final String GET_TREE_URL = "/api/manage/rest/baseCategoryInfo/tree_list";
private static final String GET_BY_IDS_URL = "/api/manage/rest/baseCategoryInfo/getDataByIds";
private static final String GET_BY_ID_URL = "/api/manage/rest/baseCategoryInfo/get";
private static final String GET_TREE_LIST_URL = "/api/manage/rest/baseCategoryInfo/getDataByIds";
private static final String GET_ALL_LIST_URL = "/api/manage/rest/baseCategoryInfo/all_list";
/**
* 获取类别树
*/
public void getTree() {
}
public void getByIds(String ids) {
}
/**
* 获取带有风格属性的树形结构
*/
public void getTreeList() {
}
/**
* 根据id获取
* @param id
*/
public void getById(Integer id) {
}
/**
*查询所有类别
*/
public List<BaseCategoryInfoVO> getAllList() {
return null;
}
}
package com.jomalls.custom.integrate.service;
import com.jomalls.custom.enums.CodeEnum;
import com.jomalls.custom.integrate.client.RemoteApiClient;
import com.jomalls.custom.integrate.model.BaseCategoryInfoModel;
import com.jomalls.custom.integrate.model.BasePropertyModel;
import com.jomalls.custom.integrate.model.SaasAdminApiResponseModel;
import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 商品分类服务
* <p>
* 调用 admin API 获取商品分类数据。
* 对齐 TS 项目 {@code baseCategoryInfoService}。
*
* @author zhengcunwen
* @author Lizh (Java 迁移)
* @since 2019-09-02
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SaasAdminService {
private static final String GET_TREE_URL = "/api/manage/rest/baseCategoryInfo/tree_list";
private static final String GET_BY_IDS_URL = "/api/manage/rest/baseCategoryInfo/getDataByIds";
private static final String GET_BY_ID_URL = "/api/manage/rest/baseCategoryInfo/get";
private static final String GET_ALL_LIST_URL = "/api/manage/rest/baseCategoryInfo/all_list";
private static final String GET_PROPERTY_BY_IDS_URL = "/api/manage/rest/baseProperty/getByIds";
private static final int DEFAULT_MAP_SIZE = 2;
private final RemoteApiClient remoteApiClient;
@Value("${server.admin.base-url:https://admin.jomalls.com}")
private String adminBaseUrl;
private Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>(DEFAULT_MAP_SIZE);
headers.put("Content-Type", "application/json");
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return headers;
}
headers.put("jwt-token", loginUser.getToken());
return headers;
}
/**
* 根据属性 ID 列表批量查询属性(含属性值列表)
* <p>
* 对齐 TS {@code getByIds(ids)} 方法。
*
* @param ids 属性 ID,逗号分隔(如 "1,2,3")
* @return 属性列表,包含 valueList 和 skuProperty 等字段
*/
public List<BasePropertyModel> getPropertyByIds(String ids) {
if (!StringUtils.hasText(ids)) {
return Collections.emptyList();
}
try {
String url = adminBaseUrl + GET_PROPERTY_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<SaasAdminApiResponseModel<List<BasePropertyModel>>> response = remoteApiClient.get(
url,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
log.debug("[ BasePropertyService ] getByIds 成功, ids={}, 返回 {} 条", ids, response.toString());
SaasAdminApiResponseModel<List<BasePropertyModel>> responseBody = response.getBody();
if (responseBody.getCode() == CodeEnum.SUCCESS.getCode()) {
return responseBody.getData();
}
}
log.warn("[ BasePropertyService ] getByIds 返回空, ids={}", ids);
return Collections.emptyList();
} catch (Exception e) {
log.error("[ BasePropertyService ] getByIds 调用失败, ids={}", ids, e);
return Collections.emptyList();
}
}
/**
* 获取分类树
* <p>
* 对齐 TS {@code getTree()}
*/
public List<BaseCategoryInfoModel> getTree() {
try {
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getTree 调用失败", e);
}
return Collections.emptyList();
}
/**
* 根据 ID 列表批量查询
* <p>
* 对齐 TS {@code getByIds(ids)}
*/
public List<BaseCategoryInfoModel> getByIds(String ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
try {
String url = adminBaseUrl + GET_BY_IDS_URL + "?ids=" + ids;
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get(
url,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getByIds 调用失败, ids={}", ids, e);
}
return Collections.emptyList();
}
/**
* 获取带有风格属性的树形结构
* <p>
* 对齐 TS {@code treeList()}
*/
public List<BaseCategoryInfoModel> treeList() {
try {
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_TREE_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ BaseCategoryInfoService ] treeList 调用失败", e);
}
return Collections.emptyList();
}
/**
* 根据 ID 查询单个分类
* <p>
* 对齐 TS {@code getById(id)}
*/
public BaseCategoryInfoModel getById(Integer id) {
if (id == null) {
return null;
}
try {
String url = adminBaseUrl + GET_BY_ID_URL + "?id=" + id;
ResponseEntity<BaseCategoryInfoModel> response = remoteApiClient.get(
url, BaseCategoryInfoModel.class, null);
if (response != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getById 调用失败, id={}", id, e);
}
return null;
}
/**
* 查询所有分类
* <p>
* 对齐 TS {@code allList()}
*/
public List<BaseCategoryInfoModel> getAllList() {
try {
ResponseEntity<List<BaseCategoryInfoModel>> response = remoteApiClient.get(
adminBaseUrl + GET_ALL_LIST_URL,
new ParameterizedTypeReference<>() {},
getHeader());
if (response != null && response.getBody() != null) {
return response.getBody();
}
} catch (Exception e) {
log.error("[ BaseCategoryInfoService ] getAllList 调用失败", e);
}
return Collections.emptyList();
}
}
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