Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
custom-server
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhonghong
custom-server
Commits
7b931415
Commit
7b931415
authored
Jun 09, 2026
by
Lizh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
按照ts代码逻辑迁移商品保存与根据商品id或sku查询商品详情接口
parent
627d26f8
Hide whitespace changes
Inline
Side-by-side
Showing
101 changed files
with
5023 additions
and
788 deletions
+5023
-788
custom-server-app/src/main/java/com/jomalls/custom/app/dto/AddBlackListDTO.java
+33
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/BindDiyUserDTO.java
+32
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductImageSnakeDTO.java
+3
-11
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoDTO.java
+0
-270
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoPropertyDTO.java
+47
-11
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoSaveDTO1.java
+160
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoSnakeDTO.java
+315
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoUpdateDTO.java
+75
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductItemSnakeDTO.java
+67
-86
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductPropertiesValueDTO.java
+105
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/FactoryPriceIntervalRelDTO.java
+37
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/FactoryPriceRelDTO.java
+51
-0
custom-server-app/src/main/java/com/jomalls/custom/app/dto/ProductChangeDTO.java
+4
-4
custom-server-app/src/main/java/com/jomalls/custom/app/enums/CustomProductInfoStatusEnum.java
+74
-0
custom-server-app/src/main/java/com/jomalls/custom/app/enums/TemplateStatus.java
+52
-0
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductImageService.java
+9
-9
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductInfoPropertyService.java
+9
-9
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductInfoService.java
+77
-24
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductItemService.java
+9
-9
custom-server-app/src/main/java/com/jomalls/custom/app/service/DiyUserService.java
+43
-0
custom-server-app/src/main/java/com/jomalls/custom/app/service/ProductFactoryRelService.java
+28
-0
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductImageServiceImpl.java
+13
-13
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductInfoPropertyServiceImpl.java
+13
-13
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductInfoServiceImpl.java
+1243
-66
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductItemServiceImpl.java
+13
-13
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/DiyUserServiceImpl.java
+80
-0
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/ProductFactoryRelServiceImpl.java
+90
-0
custom-server-app/src/main/java/com/jomalls/custom/app/utils/BeanMapper.java
+41
-4
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductImageSnakeVO.java
+4
-4
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoPropertySnakeVO.java
+4
-5
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoSkuPropertiesVO.java
+95
-0
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoSnakeVO.java
+194
-0
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductItemSnakeVO.java
+36
-43
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductPropertiesValueVO.java
+116
-0
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductFactoryRelPageVO.java
+23
-0
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductFactoryRelVO.java
+36
-0
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductRemarkVO.java
+40
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/DbDiyUserEntity.java
+63
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/DbDiyXiaoguotuEntity.java
+82
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/ProductFactoryRelEntity.java
+37
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/ProductTemplateInfoEntity.java
+102
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/CustomProductInfoMapper.java
+9
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/CustomProductWarehouseRelMapper.java
+8
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/DbDiyUserMapper.java
+32
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/DbDiyXiaoguotuMapper.java
+28
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/ProductFactoryRelMapper.java
+15
-0
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/ProductTemplateInfoMapper.java
+34
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/CustomProductInfoDomainService.java
+7
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/CustomProductWarehouseRelDomainService.java
+6
-1
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/DbDiyUserDomainService.java
+30
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/DbDiyXiaoguotuDomainService.java
+19
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/ProductFactoryRelDomainService.java
+13
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/ProductTemplateInfoDomainService.java
+25
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/CustomProductInfoDomainServiceImpl.java
+6
-1
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/CustomProductWarehouseRelDomainServiceImpl.java
+7
-2
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/DbDiyUserDomainServiceImpl.java
+36
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/DbDiyXiaoguotuDomainServiceImpl.java
+44
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/ProductFactoryRelDomainServiceImpl.java
+26
-0
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/ProductTemplateInfoDomainServiceImpl.java
+43
-0
custom-server-domain/src/main/resources/mapper/CustomProductBlacklistMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductCnRemarkMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductCraftRelMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductDiyUserRelMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductFactoryPriceIntervalRelMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductFactoryPriceRelMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductImageMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductInfoMapper.xml
+16
-0
custom-server-domain/src/main/resources/mapper/CustomProductInfoPropertyMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductItemMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductRemarkMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/CustomProductWarehouseRelMapper.xml
+18
-0
custom-server-domain/src/main/resources/mapper/CustomWarehouseInfoMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/DbDiyMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/DbDiyUserMapper.xml
+52
-0
custom-server-domain/src/main/resources/mapper/DbDiyXiaoguotuMapper.xml
+53
-0
custom-server-domain/src/main/resources/mapper/LogCustomProductMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/ProductFactoryRelMapper.xml
+23
-0
custom-server-domain/src/main/resources/mapper/ProductTemplateInfoMapper.xml
+72
-0
custom-server-domain/src/main/resources/mapper/SysBillRuleMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysMenuMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysRoleDeptMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysRoleMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysRoleMenuMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysUserMapper.xml
+10
-0
custom-server-domain/src/main/resources/mapper/SysUserOldMapper.xml
+8
-0
custom-server-domain/src/main/resources/mapper/SysUserRoleMapper.xml
+8
-0
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BaseCategoryInfoModel.java
+3
-1
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BasePropertyModel.java
+57
-0
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BasePropertyValueModel.java
+64
-0
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/SaasAdminApiResponseModel.java
+17
-0
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/service/BaseCategoryInfoService.java
+0
-53
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/service/SaasAdminService.java
+199
-0
custom-server-starter/src/main/java/com/jomalls/custom/config/RedisConfig.java
+84
-7
custom-server-starter/src/main/resources/application-redis.properties
+28
-7
custom-server-starter/src/main/resources/application.properties
+5
-2
custom-server-starter/src/main/resources/logback-spring.xml
+24
-22
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductImageController.java
+12
-12
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductInfoController.java
+92
-62
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductInfoPropertyController.java
+12
-12
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductItemController.java
+12
-12
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/ProductFactoryRelController.java
+67
-0
No files found.
custom-server-app/src/main/java/com/jomalls/custom/app/dto/AddBlackListDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/BindDiyUserDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductImageDTO.java
→
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductImage
Snake
DTO.java
View file @
7b931415
...
@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
...
@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
import
java.io.Serial
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
/**
*
*
...
@@ -20,7 +19,7 @@ import java.util.Date;
...
@@ -20,7 +19,7 @@ import java.util.Date;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"图片Dto"
)
@Schema
(
description
=
"图片Dto"
)
public
class
CustomProductImageDTO
implements
Serializable
{
public
class
CustomProductImage
Snake
DTO
implements
Serializable
{
@Serial
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
...
@@ -34,13 +33,13 @@ public class CustomProductImageDTO implements Serializable {
...
@@ -34,13 +33,13 @@ public class CustomProductImageDTO implements Serializable {
* 商品ID
* 商品ID
*/
*/
@Schema
(
description
=
"商品ID"
)
@Schema
(
description
=
"商品ID"
)
private
Integer
product
I
d
;
private
Integer
product
_i
d
;
/**
/**
* 图片地址
* 图片地址
*/
*/
@Schema
(
description
=
"图片地址"
)
@Schema
(
description
=
"图片地址"
)
private
String
image
U
rl
;
private
String
image
_u
rl
;
/**
/**
* 排序
* 排序
...
@@ -54,11 +53,4 @@ public class CustomProductImageDTO implements Serializable {
...
@@ -54,11 +53,4 @@ public class CustomProductImageDTO implements Serializable {
@Schema
(
description
=
"类型 0普通图片 1尺码图"
)
@Schema
(
description
=
"类型 0普通图片 1尺码图"
)
private
Integer
type
;
private
Integer
type
;
/**
*
*/
@Schema
(
description
=
""
)
private
Date
createTime
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoDTO.java
deleted
100644 → 0
View file @
627d26f8
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoPropertyDTO.java
View file @
7b931415
...
@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
...
@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import
java.io.Serial
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.List
;
/**
/**
* @author huanying
* @author huanying
...
@@ -23,28 +24,29 @@ public class CustomProductInfoPropertyDTO implements Serializable {
...
@@ -23,28 +24,29 @@ public class CustomProductInfoPropertyDTO implements Serializable {
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
/**
/**
*
*
ID
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
id
;
private
Integer
id
;
/**
/**
*
custom_product_info表id
*
中文名称
*/
*/
@Schema
(
description
=
"
custom_product_info表id
"
)
@Schema
(
description
=
"
中文名称
"
)
private
Integer
infoId
;
private
String
cnname
;
/**
/**
*
属性类ID
*
英文名称
*/
*/
@Schema
(
description
=
"
属性类ID
"
)
@Schema
(
description
=
"
英文名称
"
)
private
Integer
propertyId
;
private
String
enname
;
/**
/**
*
属性值ID
*
排序
*/
*/
@Schema
(
description
=
"属性值ID"
)
@Schema
(
description
=
"排序"
)
private
Integer
valueId
;
private
Integer
sort
;
/**
/**
* 是否为SKU属性
* 是否为SKU属性
...
@@ -52,5 +54,39 @@ public class CustomProductInfoPropertyDTO implements Serializable {
...
@@ -52,5 +54,39 @@ public class CustomProductInfoPropertyDTO implements Serializable {
@Schema
(
description
=
"是否为SKU属性"
)
@Schema
(
description
=
"是否为SKU属性"
)
private
Boolean
skuProperty
;
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
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoSaveDTO1.java
0 → 100644
View file @
7b931415
package
com
.
jomalls
.
custom
.
app
.
dto
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
jakarta.validation.constraints.NotNull
;
import
jakarta.validation.constraints.Size
;
import
lombok.Data
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.util.List
;
/**
* 组合创建商品 DTO
* <p>
* 对齐 TS 项目 {@code dto/custom.product.dto.ts} 中的 {@code CreateCustomProductInfoDTO}。
* 包含商品基本信息 + 所有子实体列表,由 App Service 编排写入多张表。
*
* @author Lizh
* @date 2026-06-06
*/
@Data
@Schema
(
description
=
"组合创建商品请求"
)
public
class
CustomProductInfoSaveDTO1
implements
Serializable
{
@Serial
private
static
final
long
serialVersionUID
=
1L
;
@Schema
(
description
=
"商品名称"
)
@NotNull
(
message
=
"商品名称不能为空"
)
@Size
(
max
=
255
,
message
=
"商品名称长度不能超过255个字符"
)
private
String
name
;
@Schema
(
description
=
"title"
)
@Size
(
max
=
255
,
message
=
"title长度不能超过255个字符"
)
private
String
title
;
@Schema
(
description
=
"商品主图"
)
private
String
imgUrl
;
@Schema
(
description
=
"商品类别ID"
)
private
Integer
categoryId
;
@Schema
(
description
=
"重量(kg)"
)
private
BigDecimal
weight
;
@Schema
(
description
=
"最小采购量"
)
private
Integer
purchasingMin
;
@Schema
(
description
=
"工厂价(¥)"
)
private
BigDecimal
factoryPrice
;
@Schema
(
description
=
"销售价(¥)"
)
private
BigDecimal
salesPrice
;
@Schema
(
description
=
"销售价最高价(¥)"
)
private
BigDecimal
salesPriceMax
;
@Schema
(
description
=
"状态:1待上架 10已上架 20已下架 30待下架 40已作废"
)
private
Integer
status
;
@Schema
(
description
=
"商品属性分类ID 1"
)
private
Integer
property1CateId
;
@Schema
(
description
=
"商品属性分类ID 2"
)
private
Integer
property2CateId
;
@Schema
(
description
=
"商品属性分类ID 3"
)
private
Integer
property3CateId
;
@Schema
(
description
=
"商品属性英文名称 1"
)
private
String
property1Enname
;
@Schema
(
description
=
"商品属性英文名称 2"
)
private
String
property2Enname
;
@Schema
(
description
=
"商品属性英文名称 3"
)
private
String
property3Enname
;
@Schema
(
description
=
"颜色图(JSON字符串)"
)
private
String
colorImages
;
@Schema
(
description
=
"材质"
)
private
String
material
;
@Schema
(
description
=
"印花类型:0满印 1局部印"
)
private
Integer
printType
;
@Schema
(
description
=
"货号"
)
@Size
(
max
=
20
,
message
=
"货号长度不能超过20个字符"
)
private
String
productNo
;
@Schema
(
description
=
"产地编码"
)
private
String
originCode
;
@Schema
(
description
=
"产地中文名"
)
private
String
originNameCn
;
@Schema
(
description
=
"产地英文名"
)
private
String
originNameEn
;
@Schema
(
description
=
"币种编码"
)
private
String
currencyCode
;
@Schema
(
description
=
"币种名称"
)
private
String
currencyName
;
@Schema
(
description
=
"产品类型:platform/customer"
)
private
String
productType
;
@Schema
(
description
=
"工厂ID"
)
private
Integer
factoryId
;
@Schema
(
description
=
"是否九猫处理"
)
private
Integer
processing
;
@Schema
(
description
=
"排序"
)
private
Integer
sort
;
// ==================== 子实体列表 ====================
@Schema
(
description
=
"SKU 子项列表"
)
private
List
<
CustomProductItemSnakeDTO
>
productList
;
@Schema
(
description
=
"普通图片列表"
)
private
List
<
CustomProductImageSnakeDTO
>
imageList
;
@Schema
(
description
=
"尺码图片列表(type=1)"
)
private
List
<
CustomProductImageSnakeDTO
>
sizeList
;
@Schema
(
description
=
"SKU 属性集合"
)
private
List
<
CustomProductInfoPropertyDTO
>
skuProperties
;
@Schema
(
description
=
"普通属性集合"
)
private
List
<
CustomProductInfoPropertyDTO
>
normalProperties
;
@Schema
(
description
=
"工厂价格关联列表"
)
private
List
<
FactoryPriceRelDTO
>
factoryPriceList
;
@Schema
(
description
=
"工厂 ID 列表"
)
private
List
<
Integer
>
factoryIds
;
@Schema
(
description
=
"仓库 ID 列表"
)
private
List
<
Integer
>
warehouseIds
;
@Schema
(
description
=
"DIY 用户 ID 列表"
)
private
List
<
Integer
>
diyUserIds
;
@Schema
(
description
=
"工艺 ID 列表"
)
private
List
<
Integer
>
craftIds
;
@Schema
(
description
=
"工厂价格区间关联列表"
)
private
List
<
FactoryPriceIntervalRelDTO
>
factoryPriceIntervalList
;
@Schema
(
description
=
"英文备注"
)
private
String
remark
;
@Schema
(
description
=
"中文备注"
)
private
String
cnRemark
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoSnakeDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductInfoUpdateDTO.java
0 → 100644
View file @
7b931415
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
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductItemDTO.java
→
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductItem
Snake
DTO.java
View file @
7b931415
...
@@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
...
@@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
import
java.io.Serial
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.util.
Date
;
import
java.util.
List
;
/**
/**
* Model
* Model
...
@@ -22,7 +22,7 @@ import java.util.Date;
...
@@ -22,7 +22,7 @@ import java.util.Date;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"skuItem Dto"
)
@Schema
(
description
=
"skuItem Dto"
)
public
class
CustomProductItemDTO
implements
Serializable
{
public
class
CustomProductItem
Snake
DTO
implements
Serializable
{
@Serial
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
...
@@ -33,10 +33,10 @@ public class CustomProductItemDTO implements Serializable {
...
@@ -33,10 +33,10 @@ public class CustomProductItemDTO implements Serializable {
private
Integer
id
;
private
Integer
id
;
/**
/**
*
商品ID
*
排序
*/
*/
@Schema
(
description
=
"
商品ID
"
)
@Schema
(
description
=
"
排序
"
)
private
Integer
productId
;
private
Integer
sort
;
/**
/**
* sku
* sku
...
@@ -48,163 +48,144 @@ public class CustomProductItemDTO implements Serializable {
...
@@ -48,163 +48,144 @@ public class CustomProductItemDTO implements Serializable {
* sku商品名称
* sku商品名称
*/
*/
@Schema
(
description
=
"sku商品名称"
)
@Schema
(
description
=
"sku商品名称"
)
private
String
sku
N
ame
;
private
String
sku
_n
ame
;
/**
/**
*
封面图
*
sku克重
*/
*/
@Schema
(
description
=
"
封面图
"
)
@Schema
(
description
=
"
sku克重
"
)
private
String
image
;
private
BigDecimal
sku_weight
;
/**
/**
*
图片集
*
*/
*/
@Schema
(
description
=
"
图片集
"
)
@Schema
(
description
=
""
)
private
String
imageAry
;
private
Integer
property1_id
;
/**
/**
* 属性
分类ID
1
* 属性
名称
1
*/
*/
@Schema
(
description
=
"属性
分类ID
1"
)
@Schema
(
description
=
"属性
名称
1"
)
private
Integer
propertyCateId
1
;
private
String
option_enname
1
;
/**
/**
*
属性分类ID2
*
*/
*/
@Schema
(
description
=
"
属性分类ID2
"
)
@Schema
(
description
=
""
)
private
Integer
propertyCateId2
;
private
String
custom_value1
;
/**
/**
* 属性分类ID
3
* 属性分类ID
1
*/
*/
@Schema
(
description
=
"属性分类ID
3
"
)
@Schema
(
description
=
"属性分类ID
1
"
)
private
Integer
propertyCateId3
;
private
String
property_code1
;
/**
/**
*
*
属性分类ID1
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
"
属性分类ID1
"
)
private
Integer
property
1Id
;
private
Integer
property
_cate_id1
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
property2
I
d
;
private
Integer
property2
_i
d
;
/**
/**
*
* 属性名称2
*/
@Schema
(
description
=
"属性名称2"
)
private
String
option_enname2
;
/**
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
property3Id
;
private
String
custom_value2
;
/**
/**
* 属性
编码1
* 属性
分类ID2
*/
*/
@Schema
(
description
=
"属性
编码1
"
)
@Schema
(
description
=
"属性
分类ID2
"
)
private
String
property
Code1
;
private
String
property
_code2
;
/**
/**
* 属性
编码
2
* 属性
分类ID
2
*/
*/
@Schema
(
description
=
"属性
编码
2"
)
@Schema
(
description
=
"属性
分类ID
2"
)
private
String
propertyCode
2
;
private
Integer
property_cate_id
2
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
propertyCode3
;
private
Integer
property3_id
;
/**
/**
* 属性名称
1
* 属性名称
3
*/
*/
@Schema
(
description
=
"属性名称
1
"
)
@Schema
(
description
=
"属性名称
3
"
)
private
String
option
Enname1
;
private
String
option
_enname3
;
/**
/**
*
属性名称2
*
*/
*/
@Schema
(
description
=
"
属性名称2
"
)
@Schema
(
description
=
""
)
private
String
optionEnname2
;
private
String
custom_value3
;
/**
/**
*
*
属性分类ID3
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
"
属性分类ID3
"
)
private
String
optionEnnam
e3
;
private
String
property_cod
e3
;
/**
/**
*
*
属性分类ID3
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
"
属性分类ID3
"
)
private
String
customValue1
;
private
Integer
property_cate_id3
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
customValue2
;
private
String
relation_ids
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
customValue3
;
private
List
<
String
>
relation
;
/**
/**
* 工厂价
* 工厂价
*/
*/
@Schema
(
description
=
"工厂价"
)
@Schema
(
description
=
"工厂价"
)
private
BigDecimal
factory
P
rice
;
private
BigDecimal
factory
_p
rice
;
/**
/**
* 销售价
* 销售价
*/
*/
@Schema
(
description
=
"销售价"
)
@Schema
(
description
=
"销售价"
)
private
BigDecimal
sales
P
rice
;
private
BigDecimal
sales
_p
rice
;
/**
/**
* sku克重
* 封面图
*/
@Schema
(
description
=
"sku克重"
)
private
BigDecimal
skuWeight
;
/**
* 印花类型 0满印 1局部印
*/
@Schema
(
description
=
"印花类型 0满印 1局部印"
)
private
Integer
printType
;
/**
* 排序
*/
*/
@Schema
(
description
=
"
排序
"
)
@Schema
(
description
=
"
封面图
"
)
private
Integer
sort
;
private
String
image
;
/**
/**
*
货号
*
图片集Json串
*/
*/
@Schema
(
description
=
"
货号
"
)
@Schema
(
description
=
"
图片集Json串
"
)
private
String
productNo
;
private
String
image_ary
;
/**
/**
* 1正常码 2大码
* 1正常码 2大码
*/
*/
@Schema
(
description
=
"1正常码 2大码"
)
@Schema
(
description
=
"1正常码 2大码"
)
private
Integer
sizeType
;
private
Integer
size_type
;
/**
* 创建时间
*/
@Schema
(
description
=
"创建时间"
)
private
Date
createTime
;
/**
* 更新时间
*/
@Schema
(
description
=
"更新时间"
)
private
Date
updateTime
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/CustomProductPropertiesValueDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/FactoryPriceIntervalRelDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/FactoryPriceRelDTO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/dto/ProductChangeDTO.java
View file @
7b931415
...
@@ -15,11 +15,11 @@ import java.util.List;
...
@@ -15,11 +15,11 @@ import java.util.List;
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"商品变更Dto"
)
@Schema
(
description
=
"商品变更Dto"
)
public
class
ProductChangeDTO
implements
Serializable
{
public
class
ProductChangeDTO
implements
Serializable
{
@Schema
(
description
=
"添加集合"
,
implementation
=
CustomProductItemDTO
.
class
)
@Schema
(
description
=
"添加集合"
,
implementation
=
CustomProductItem
Snake
DTO
.
class
)
private
List
<
CustomProductItemDTO
>
addList
;
private
List
<
CustomProductItem
Snake
DTO
>
addList
;
@Schema
(
description
=
"修改集合"
,
implementation
=
CustomProductItemDTO
.
class
)
@Schema
(
description
=
"修改集合"
,
implementation
=
CustomProductItem
Snake
DTO
.
class
)
private
List
<
CustomProductItemDTO
>
updateList
;
private
List
<
CustomProductItem
Snake
DTO
>
updateList
;
@Schema
(
description
=
"删除集合"
,
implementation
=
Integer
.
class
)
@Schema
(
description
=
"删除集合"
,
implementation
=
Integer
.
class
)
private
List
<
Integer
>
removeList
;
private
List
<
Integer
>
removeList
;
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/enums/CustomProductInfoStatusEnum.java
0 → 100644
View file @
7b931415
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
());
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/enums/TemplateStatus.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductImageService.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImageVO
;
import
com.jomalls.custom.app.vo.CustomProductImage
Snake
VO
;
import
java.util.List
;
import
java.util.List
;
...
@@ -17,10 +17,10 @@ public interface CustomProductImageService {
...
@@ -17,10 +17,10 @@ public interface CustomProductImageService {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductImageVO 条件model
* @param customProductImage
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
List
<
CustomProductImage
VO
>
list
(
CustomProductImageVO
customProductImag
eVO
);
List
<
CustomProductImage
SnakeVO
>
list
(
CustomProductImageSnakeVO
customProductImageSnak
eVO
);
/**
/**
* 根据条件查询分页列表接口
* 根据条件查询分页列表接口
...
@@ -28,7 +28,7 @@ public interface CustomProductImageService {
...
@@ -28,7 +28,7 @@ public interface CustomProductImageService {
* @param customProductImagePageVO 分页入参model
* @param customProductImagePageVO 分页入参model
* @return 分页对象
* @return 分页对象
*/
*/
IPage
<
CustomProductImageVO
>
pageList
(
CustomProductImagePageVO
customProductImagePageVO
);
IPage
<
CustomProductImage
Snake
VO
>
pageList
(
CustomProductImagePageVO
customProductImagePageVO
);
/**
/**
* 根据id查询详情
* 根据id查询详情
...
@@ -36,21 +36,21 @@ public interface CustomProductImageService {
...
@@ -36,21 +36,21 @@ public interface CustomProductImageService {
* @param id 主键
* @param id 主键
* @return 实体model
* @return 实体model
*/
*/
CustomProductImageVO
info
(
Integer
id
);
CustomProductImage
Snake
VO
info
(
Integer
id
);
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductImageVO 保存对象
* @param customProductImage
Snake
VO 保存对象
*/
*/
void
save
(
CustomProductImage
VO
customProductImag
eVO
);
void
save
(
CustomProductImage
SnakeVO
customProductImageSnak
eVO
);
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductImageVO 修改对象
* @param customProductImage
Snake
VO 修改对象
*/
*/
void
updateById
(
CustomProductImage
VO
customProductImag
eVO
);
void
updateById
(
CustomProductImage
SnakeVO
customProductImageSnak
eVO
);
/**
/**
* 根据主键ID进行删除
* 根据主键ID进行删除
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductInfoPropertyService.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoProperty
Snake
VO
;
import
java.util.List
;
import
java.util.List
;
...
@@ -17,10 +17,10 @@ public interface CustomProductInfoPropertyService {
...
@@ -17,10 +17,10 @@ public interface CustomProductInfoPropertyService {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductInfoPropertyVO 条件model
* @param customProductInfoProperty
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
List
<
CustomProductInfoProperty
VO
>
list
(
CustomProductInfoPropertyVO
customProductInfoProperty
VO
);
List
<
CustomProductInfoProperty
SnakeVO
>
list
(
CustomProductInfoPropertySnakeVO
customProductInfoPropertySnake
VO
);
/**
/**
* 根据条件查询分页列表接口
* 根据条件查询分页列表接口
...
@@ -28,7 +28,7 @@ public interface CustomProductInfoPropertyService {
...
@@ -28,7 +28,7 @@ public interface CustomProductInfoPropertyService {
* @param customProductInfoPropertyPageVO 分页入参model
* @param customProductInfoPropertyPageVO 分页入参model
* @return 分页对象
* @return 分页对象
*/
*/
IPage
<
CustomProductInfoPropertyVO
>
pageList
(
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
);
IPage
<
CustomProductInfoProperty
Snake
VO
>
pageList
(
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
);
/**
/**
* 根据id查询详情
* 根据id查询详情
...
@@ -36,21 +36,21 @@ public interface CustomProductInfoPropertyService {
...
@@ -36,21 +36,21 @@ public interface CustomProductInfoPropertyService {
* @param id 主键
* @param id 主键
* @return 实体model
* @return 实体model
*/
*/
CustomProductInfoPropertyVO
info
(
Integer
id
);
CustomProductInfoProperty
Snake
VO
info
(
Integer
id
);
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductInfoPropertyVO 保存对象
* @param customProductInfoProperty
Snake
VO 保存对象
*/
*/
void
save
(
CustomProductInfoProperty
VO
customProductInfoProperty
VO
);
void
save
(
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
);
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductInfoPropertyVO 修改对象
* @param customProductInfoProperty
Snake
VO 修改对象
*/
*/
void
updateById
(
CustomProductInfoProperty
VO
customProductInfoProperty
VO
);
void
updateById
(
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
);
/**
/**
* 根据主键ID进行删除
* 根据主键ID进行删除
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductInfoService.java
View file @
7b931415
package
com
.
jomalls
.
custom
.
app
.
service
;
package
com
.
jomalls
.
custom
.
app
.
service
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.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.CustomProductInfoVO
;
import
com.jomalls.custom.app.vo.DbDiyVO
;
import
java.util.List
;
import
java.util.List
;
/**
/**
* @author Lizh
* @author Lizh
* @version 0.01
* @version 0.01
* @description:
接口
* @description:
定制商品服务
接口
* @date 2026-05-29 10:43:29
* @date 2026-05-29 10:43:29
*/
*/
public
interface
CustomProductInfoService
{
public
interface
CustomProductInfoService
{
IPage
<
CustomProductInfoVO
>
pageList
(
CustomProductInfoSnakeDTO
param
);
/**
/**
*
列表查询接口
*
组合创建商品(SKU 生成 + 事务内写入主表及所有子表)
*
*
* @param customProductInfoVO 条件model
* @param dto 组合创建 DTO
* @return list集合
*/
*/
List
<
CustomProductInfoVO
>
list
(
CustomProductInfoVO
customProductInfoVO
);
void
saveFull
(
CustomProductInfoSnakeDTO
dto
);
/**
/**
*
根据条件查询分页列表接口
*
组合更新商品(事务内处理主表及子表的增/删/改差异)
*
*
* @param param 分页入参model
* @param dto 组合更新 DTO
* @return 分页对象
*/
*/
IPage
<
CustomProductInfoVO
>
pageList
(
CustomProductInfoDTO
param
);
void
updateFull
(
CustomProductInfoUpdateDTO
dto
);
/**
/**
* 根据
id查询详情
* 根据
ID 或 SKU 加载商品完整数据(并行单表查询后在 Java 层组合)
*
*
* @param id 主键
* @param id 商品 ID(可为 null)
* @return 实体model
* @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
);
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/CustomProductItemService.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.app.service;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemVO
;
import
com.jomalls.custom.app.vo.CustomProductItem
Snake
VO
;
import
java.util.List
;
import
java.util.List
;
...
@@ -17,10 +17,10 @@ public interface CustomProductItemService {
...
@@ -17,10 +17,10 @@ public interface CustomProductItemService {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductItemVO 条件model
* @param customProductItem
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
List
<
CustomProductItem
VO
>
list
(
CustomProductItemVO
customProductItem
VO
);
List
<
CustomProductItem
SnakeVO
>
list
(
CustomProductItemSnakeVO
customProductItemSnake
VO
);
/**
/**
* 根据条件查询分页列表接口
* 根据条件查询分页列表接口
...
@@ -28,7 +28,7 @@ public interface CustomProductItemService {
...
@@ -28,7 +28,7 @@ public interface CustomProductItemService {
* @param customProductItemPageVO 分页入参model
* @param customProductItemPageVO 分页入参model
* @return 分页对象
* @return 分页对象
*/
*/
IPage
<
CustomProductItemVO
>
pageList
(
CustomProductItemPageVO
customProductItemPageVO
);
IPage
<
CustomProductItem
Snake
VO
>
pageList
(
CustomProductItemPageVO
customProductItemPageVO
);
/**
/**
* 根据id查询详情
* 根据id查询详情
...
@@ -36,21 +36,21 @@ public interface CustomProductItemService {
...
@@ -36,21 +36,21 @@ public interface CustomProductItemService {
* @param id 主键
* @param id 主键
* @return 实体model
* @return 实体model
*/
*/
CustomProductItemVO
info
(
Integer
id
);
CustomProductItem
Snake
VO
info
(
Integer
id
);
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductItemVO 保存对象
* @param customProductItem
Snake
VO 保存对象
*/
*/
void
save
(
CustomProductItem
VO
customProductItem
VO
);
void
save
(
CustomProductItem
SnakeVO
customProductItemSnake
VO
);
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductItemVO 修改对象
* @param customProductItem
Snake
VO 修改对象
*/
*/
void
updateById
(
CustomProductItem
VO
customProductItem
VO
);
void
updateById
(
CustomProductItem
SnakeVO
customProductItemSnake
VO
);
/**
/**
* 根据主键ID进行删除
* 根据主键ID进行删除
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/DiyUserService.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/ProductFactoryRelService.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductImageServiceImpl.java
View file @
7b931415
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImageVO
;
import
com.jomalls.custom.app.vo.CustomProductImage
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductImageService
;
import
com.jomalls.custom.app.service.CustomProductImageService
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
...
@@ -37,34 +37,34 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
...
@@ -37,34 +37,34 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
}
}
@Override
@Override
public
List
<
CustomProductImage
VO
>
list
(
CustomProductImageVO
customProductImag
eVO
)
{
public
List
<
CustomProductImage
SnakeVO
>
list
(
CustomProductImageSnakeVO
customProductImageSnak
eVO
)
{
QueryWrapper
<
CustomProductImageEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductImageEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
List
<
CustomProductImageEntity
>
list
=
customProductImageDomainService
.
list
(
queryWrapper
);
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
,
CustomProductImage
Snake
VO
.
class
)).
collect
(
Collectors
.
toList
());
}
}
@Override
@Override
public
IPage
<
CustomProductImageVO
>
pageList
(
CustomProductImagePageVO
customProductImagePageVO
)
{
public
IPage
<
CustomProductImage
Snake
VO
>
pageList
(
CustomProductImagePageVO
customProductImagePageVO
)
{
CustomAsserts
.
nonNull
(
customProductImagePageVO
,
"分页查询参数不能为空"
);
CustomAsserts
.
nonNull
(
customProductImagePageVO
,
"分页查询参数不能为空"
);
QueryWrapper
<
CustomProductImageEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductImageEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
IPage
<
CustomProductImageEntity
>
page
=
customProductImageDomainService
.
selectPage
(
queryWrapper
,
customProductImagePageVO
);
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
,
CustomProductImage
Snake
VO
.
class
));
}
}
@Override
@Override
public
CustomProductImageVO
info
(
Integer
id
)
{
public
CustomProductImage
Snake
VO
info
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomProductImageEntity
customProductImage
=
customProductImageDomainService
.
getById
(
id
);
CustomProductImageEntity
customProductImage
=
customProductImageDomainService
.
getById
(
id
);
return
BeanMapper
.
mapper
().
convert
(
customProductImage
,
CustomProductImageVO
.
class
);
return
BeanMapper
.
mapper
().
convert
(
customProductImage
,
CustomProductImage
Snake
VO
.
class
);
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
save
(
CustomProductImage
VO
customProductImag
eVO
)
{
public
void
save
(
CustomProductImage
SnakeVO
customProductImageSnak
eVO
)
{
CustomAsserts
.
nonNull
(
customProductImageVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductImage
Snake
VO
,
"实体对象不能为空"
);
CustomProductImageEntity
customProductImageEntity
=
BeanMapper
.
mapper
().
convert
(
customProductImageVO
,
CustomProductImageEntity
.
class
);
CustomProductImageEntity
customProductImageEntity
=
BeanMapper
.
mapper
().
convert
(
customProductImage
Snake
VO
,
CustomProductImageEntity
.
class
);
try
{
try
{
customProductImageDomainService
.
save
(
customProductImageEntity
);
customProductImageDomainService
.
save
(
customProductImageEntity
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
@@ -75,9 +75,9 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
...
@@ -75,9 +75,9 @@ public class CustomProductImageServiceImpl implements CustomProductImageService
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
updateById
(
CustomProductImage
VO
customProductImag
eVO
)
{
public
void
updateById
(
CustomProductImage
SnakeVO
customProductImageSnak
eVO
)
{
CustomAsserts
.
nonNull
(
customProductImageVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductImage
Snake
VO
,
"实体对象不能为空"
);
CustomProductImageEntity
customProductImage
=
BeanMapper
.
mapper
().
convert
(
customProductImageVO
,
CustomProductImageEntity
.
class
);
CustomProductImageEntity
customProductImage
=
BeanMapper
.
mapper
().
convert
(
customProductImage
Snake
VO
,
CustomProductImageEntity
.
class
);
try
{
try
{
customProductImageDomainService
.
updateById
(
customProductImage
);
customProductImageDomainService
.
updateById
(
customProductImage
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductInfoPropertyServiceImpl.java
View file @
7b931415
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoProperty
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductInfoPropertyService
;
import
com.jomalls.custom.app.service.CustomProductInfoPropertyService
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
...
@@ -37,34 +37,34 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
...
@@ -37,34 +37,34 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
}
}
@Override
@Override
public
List
<
CustomProductInfoProperty
VO
>
list
(
CustomProductInfoPropertyVO
customProductInfoProperty
VO
)
{
public
List
<
CustomProductInfoProperty
SnakeVO
>
list
(
CustomProductInfoPropertySnakeVO
customProductInfoPropertySnake
VO
)
{
QueryWrapper
<
CustomProductInfoPropertyEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductInfoPropertyEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
List
<
CustomProductInfoPropertyEntity
>
list
=
customProductInfoPropertyDomainService
.
list
(
queryWrapper
);
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
,
CustomProductInfoProperty
Snake
VO
.
class
)).
collect
(
Collectors
.
toList
());
}
}
@Override
@Override
public
IPage
<
CustomProductInfoPropertyVO
>
pageList
(
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
)
{
public
IPage
<
CustomProductInfoProperty
Snake
VO
>
pageList
(
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
)
{
CustomAsserts
.
nonNull
(
customProductInfoPropertyPageVO
,
"分页查询参数不能为空"
);
CustomAsserts
.
nonNull
(
customProductInfoPropertyPageVO
,
"分页查询参数不能为空"
);
QueryWrapper
<
CustomProductInfoPropertyEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductInfoPropertyEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
IPage
<
CustomProductInfoPropertyEntity
>
page
=
customProductInfoPropertyDomainService
.
selectPage
(
queryWrapper
,
customProductInfoPropertyPageVO
);
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
,
CustomProductInfoProperty
Snake
VO
.
class
));
}
}
@Override
@Override
public
CustomProductInfoPropertyVO
info
(
Integer
id
)
{
public
CustomProductInfoProperty
Snake
VO
info
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomProductInfoPropertyEntity
customProductInfoProperty
=
customProductInfoPropertyDomainService
.
getById
(
id
);
CustomProductInfoPropertyEntity
customProductInfoProperty
=
customProductInfoPropertyDomainService
.
getById
(
id
);
return
BeanMapper
.
mapper
().
convert
(
customProductInfoProperty
,
CustomProductInfoPropertyVO
.
class
);
return
BeanMapper
.
mapper
().
convert
(
customProductInfoProperty
,
CustomProductInfoProperty
Snake
VO
.
class
);
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
save
(
CustomProductInfoProperty
VO
customProductInfoProperty
VO
)
{
public
void
save
(
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
)
{
CustomAsserts
.
nonNull
(
customProductInfoPropertyVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductInfoProperty
Snake
VO
,
"实体对象不能为空"
);
CustomProductInfoPropertyEntity
customProductInfoPropertyEntity
=
BeanMapper
.
mapper
().
convert
(
customProductInfoPropertyVO
,
CustomProductInfoPropertyEntity
.
class
);
CustomProductInfoPropertyEntity
customProductInfoPropertyEntity
=
BeanMapper
.
mapper
().
convert
(
customProductInfoProperty
Snake
VO
,
CustomProductInfoPropertyEntity
.
class
);
try
{
try
{
customProductInfoPropertyDomainService
.
save
(
customProductInfoPropertyEntity
);
customProductInfoPropertyDomainService
.
save
(
customProductInfoPropertyEntity
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
@@ -75,9 +75,9 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
...
@@ -75,9 +75,9 @@ public class CustomProductInfoPropertyServiceImpl implements CustomProductInfoPr
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
updateById
(
CustomProductInfoProperty
VO
customProductInfoProperty
VO
)
{
public
void
updateById
(
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
)
{
CustomAsserts
.
nonNull
(
customProductInfoPropertyVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductInfoProperty
Snake
VO
,
"实体对象不能为空"
);
CustomProductInfoPropertyEntity
customProductInfoProperty
=
BeanMapper
.
mapper
().
convert
(
customProductInfoPropertyVO
,
CustomProductInfoPropertyEntity
.
class
);
CustomProductInfoPropertyEntity
customProductInfoProperty
=
BeanMapper
.
mapper
().
convert
(
customProductInfoProperty
Snake
VO
,
CustomProductInfoPropertyEntity
.
class
);
try
{
try
{
customProductInfoPropertyDomainService
.
updateById
(
customProductInfoProperty
);
customProductInfoPropertyDomainService
.
updateById
(
customProductInfoProperty
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductInfoServiceImpl.java
View file @
7b931415
package
com
.
jomalls
.
custom
.
app
.
service
.
impl
;
package
com
.
jomalls
.
custom
.
app
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.dto.CustomProductInfoDTO
;
import
com.jomalls.custom.app.dto.*
;
import
com.jomalls.custom.app.enums.SkuGenerateEnums
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.integrate.service.BaseCategoryInfoService
;
import
com.jomalls.custom.app.enums.TemplateStatus
;
import
com.jomalls.custom.integrate.model.BaseCategoryInfoVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoVO
;
import
com.jomalls.custom.app.service.CustomProductInfoService
;
import
com.jomalls.custom.app.service.CustomProductInfoService
;
import
com.jomalls.custom.app.service.DiyUserService
;
import
com.jomalls.custom.app.service.SysBillRuleService
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
import
com.jomalls.custom.dal.entity.CustomProductInfoEntity
;
import
com.jomalls.custom.app.vo.*
;
import
com.jomalls.custom.domain.service.CustomProductInfoDomainService
;
import
com.jomalls.custom.dal.entity.*
;
import
com.jomalls.custom.domain.service.*
;
import
com.jomalls.custom.integrate.model.BaseCategoryInfoModel
;
import
com.jomalls.custom.integrate.model.BasePropertyModel
;
import
com.jomalls.custom.integrate.model.BasePropertyValueModel
;
import
com.jomalls.custom.integrate.service.SaasAdminService
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.dao.DuplicateKeyException
;
import
org.springframework.dao.DuplicateKeyException
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.
annotation.Transactional
;
import
org.springframework.transaction.
support.TransactionTemplate
;
import
java.util.List
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.util.*
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.concurrent.CompletionException
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
/**
/**
* @author Lizh
* @author Lizh
* @version 0.0
1
* @version 0.0
2
* @description:
接口实现
* @description:
定制商品服务实现(含组合编排逻辑)
* @date 2026-05-29 10:43:29
* @date 2026-05-29 10:43:29
*/
*/
@Slf4j
@Slf4j
...
@@ -33,42 +50,62 @@ import java.util.stream.Collectors;
...
@@ -33,42 +50,62 @@ import java.util.stream.Collectors;
public
class
CustomProductInfoServiceImpl
implements
CustomProductInfoService
{
public
class
CustomProductInfoServiceImpl
implements
CustomProductInfoService
{
private
final
CustomProductInfoDomainService
customProductInfoDomainService
;
private
final
CustomProductInfoDomainService
customProductInfoDomainService
;
private
final
BaseCategoryInfoService
baseCategoryInfoService
;
private
final
SaasAdminService
saasAdminService
;
private
final
SysBillRuleService
sysBillRuleService
;
private
final
TransactionTemplate
transactionTemplate
;
private
final
CustomProductItemDomainService
customProductItemDomainService
;
private
final
CustomProductImageDomainService
customProductImageDomainService
;
private
final
CustomProductRemarkDomainService
customProductRemarkDomainService
;
private
final
CustomProductCnRemarkDomainService
customProductCnRemarkDomainService
;
private
final
CustomProductInfoPropertyDomainService
customProductInfoPropertyDomainService
;
private
final
CustomProductFactoryPriceRelDomainService
customProductFactoryPriceRelDomainService
;
private
final
CustomProductFactoryPriceIntervalRelDomainService
customProductFactoryPriceIntervalRelDomainService
;
private
final
CustomProductDiyUserRelDomainService
customProductDiyUserRelDomainService
;
private
final
CustomProductCraftRelDomainService
customProductCraftRelDomainService
;
private
final
CustomProductWarehouseRelDomainService
customProductWarehouseRelDomainService
;
private
final
CustomWarehouseInfoDomainService
customWarehouseInfoDomainService
;
private
final
CustomProductBlacklistDomainService
customProductBlacklistDomainService
;
private
final
LogCustomProductDomainService
logCustomProductDomainService
;
private
final
DbDiyDomainService
dbDiyDomainService
;
private
final
ProductFactoryRelDomainService
productFactoryRelDomainService
;
private
final
ProductTemplateInfoDomainService
productTemplateInfoDomainService
;
private
final
DbDiyXiaoguotuDomainService
dbDiyXiaoguotuDomainService
;
private
final
DiyUserService
diyUserService
;
private
final
ThreadPoolExecutor
threadPoolExecutor
;
/** 图片类型:普通图片 */
private
static
final
int
IMAGE_TYPE_NORMAL
=
0
;
/** 图片类型:尺码图 */
private
static
final
int
IMAGE_TYPE_SIZE
=
1
;
/** 并行查询超时时间(秒) */
private
static
final
long
QUERY_TIMEOUT_SECONDS
=
30
;
@Override
public
List
<
CustomProductInfoVO
>
list
(
CustomProductInfoVO
customProductInfoVO
)
{
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
List
<
CustomProductInfoEntity
>
list
=
customProductInfoDomainService
.
list
(
queryWrapper
);
return
list
.
stream
().
map
(
e
->
BeanMapper
.
mapper
().
convert
(
e
,
CustomProductInfoVO
.
class
)).
collect
(
Collectors
.
toList
());
}
@Override
@Override
public
IPage
<
CustomProductInfoVO
>
pageList
(
CustomProductInfoDTO
param
)
{
public
IPage
<
CustomProductInfoVO
>
pageList
(
CustomProductInfo
Snake
DTO
param
)
{
CustomAsserts
.
nonNull
(
param
,
"分页查询参数不能为空"
);
CustomAsserts
.
nonNull
(
param
,
"分页查询参数不能为空"
);
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
=
new
QueryWrapper
<>();
toQueryWrapper
(
param
,
queryWrapper
);
// 构造查询条件
// TODO 根据业务条件组装入参
toQueryWrapper
(
param
,
queryWrapper
);
IPage
<
CustomProductInfoEntity
>
page
=
customProductInfoDomainService
.
selectPage
(
queryWrapper
,
param
);
IPage
<
CustomProductInfoEntity
>
page
=
customProductInfoDomainService
.
selectPage
(
queryWrapper
,
param
);
return
page
.
convert
(
e
->
BeanMapper
.
mapper
().
convert
(
e
,
CustomProductInfoVO
.
class
));
return
page
.
convert
(
e
->
BeanMapper
.
mapper
().
convert
(
e
,
CustomProductInfoVO
.
class
));
}
}
private
void
toQueryWrapper
(
CustomProductInfoDTO
param
,
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
)
{
private
void
toQueryWrapper
(
CustomProductInfoSnakeDTO
param
,
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
)
{
if
(
param
.
getCategory_id
()
!=
null
){
// 分类层级过滤
// 获取所有分类列表
if
(
param
.
getCategory_id
()
!=
null
)
{
List
<
BaseCategoryInfoVO
>
cateList
=
baseCategoryInfoService
.
getAllList
();
List
<
BaseCategoryInfoModel
>
cateList
=
saasAdminService
.
getAllList
();
// 查找匹配的分类
if
(
cateList
==
null
)
{
BaseCategoryInfoVO
cate
=
cateList
.
stream
()
cateList
=
Collections
.
emptyList
();
}
BaseCategoryInfoModel
cate
=
cateList
.
stream
()
.
filter
(
c
->
c
.
getId
().
equals
(
param
.
getCategory_id
()))
.
filter
(
c
->
c
.
getId
().
equals
(
param
.
getCategory_id
()))
.
findFirst
()
.
findFirst
()
.
orElseThrow
(()
->
new
ServiceException
(
"不存在该类别"
));
.
orElseThrow
(()
->
new
ServiceException
(
"不存在该类别, category_id="
+
param
.
getCategory_id
()));
// 构建 pids
String
pids
=
String
.
valueOf
(
cate
.
getId
());
String
pids
=
String
.
valueOf
(
cate
.
getId
());
if
(
cate
.
getPids
()
!=
null
&&
!
cate
.
getPids
().
isEmpty
())
{
if
(
cate
.
getPids
()
!=
null
&&
!
cate
.
getPids
().
isEmpty
())
{
pids
=
cate
.
getPids
()
+
","
+
pids
;
pids
=
cate
.
getPids
()
+
","
+
pids
;
}
}
// 筛选子分类
String
finalPids
=
pids
;
String
finalPids
=
pids
;
List
<
Integer
>
cateIds
=
cateList
.
stream
()
List
<
Integer
>
cateIds
=
cateList
.
stream
()
.
filter
(
item
->
{
.
filter
(
item
->
{
...
@@ -76,63 +113,1203 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
...
@@ -76,63 +113,1203 @@ public class CustomProductInfoServiceImpl implements CustomProductInfoService {
return
finalPids
.
equals
(
itemPids
)
||
return
finalPids
.
equals
(
itemPids
)
||
(
itemPids
!=
null
&&
itemPids
.
startsWith
(
finalPids
+
","
));
(
itemPids
!=
null
&&
itemPids
.
startsWith
(
finalPids
+
","
));
})
})
.
map
(
BaseCategoryInfo
VO
:
:
getId
)
.
map
(
BaseCategoryInfo
Model
:
:
getId
)
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
// 添加当前分类ID
cateIds
.
add
(
cate
.
getId
());
cateIds
.
add
(
cate
.
getId
());
// 设置参数
queryWrapper
.
in
(
"category_id"
,
cateIds
);
queryWrapper
.
in
(
"category_id"
,
cateIds
);
}
// 是否九猫处理过滤
if
(
param
.
getProcessing
())
{
queryWrapper
.
eq
(
"processing"
,
1
);
}
else
{
queryWrapper
.
eq
(
"processing"
,
0
);
}
// 直接列等值过滤
if
(
param
.
getId
()
!=
null
)
{
queryWrapper
.
eq
(
"id"
,
param
.
getId
());
}
if
(
param
.
getSku
()
!=
null
&&
!
param
.
getSku
().
isEmpty
())
{
queryWrapper
.
eq
(
"sku"
,
param
.
getSku
());
}
if
(
param
.
getStatus
()
!=
null
)
{
queryWrapper
.
eq
(
"status"
,
param
.
getStatus
());
}
if
(
param
.
getProduct_type
()
!=
null
&&
!
param
.
getProduct_type
().
isEmpty
())
{
queryWrapper
.
eq
(
"product_type"
,
param
.
getProduct_type
());
}
if
(
param
.
getProduct_no
()
!=
null
&&
!
param
.
getProduct_no
().
isEmpty
())
{
queryWrapper
.
eq
(
"product_no"
,
param
.
getProduct_no
());
}
if
(
param
.
getPrint_type
()
!=
null
)
{
queryWrapper
.
eq
(
"print_type"
,
param
.
getPrint_type
());
}
if
(
param
.
getName
()
!=
null
&&
!
param
.
getName
().
isEmpty
())
{
queryWrapper
.
like
(
"name"
,
param
.
getName
());
}
if
(
param
.
getTitle
()
!=
null
&&
!
param
.
getTitle
().
isEmpty
())
{
queryWrapper
.
like
(
"title"
,
param
.
getTitle
());
}
// 工厂过滤(factory_id 是 custom_product_info 的直接列)
if
(
param
.
getFactoryIds
()
!=
null
)
{
queryWrapper
.
in
(
"factory_id"
,
param
.
getFactoryIds
());
}
// DIY 用户过滤 与 黑名单过滤:需要查询关联表取 productId 列表,两者取交集
List
<
Integer
>
idListFromDiyUser
=
null
;
List
<
Integer
>
idListFromBlacklist
=
null
;
if
(
param
.
getDiyUserId
()
!=
null
)
{
if
(
param
.
getDiyUserId
()
==
-
1
)
{
// 查询未绑定任何 DIY 用户的产品:先找出已绑定的 productId,再 NOT IN
List
<
Integer
>
boundIds
=
customProductDiyUserRelDomainService
.
list
().
stream
()
.
map
(
CustomProductDiyUserRelEntity:
:
getProductId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
if
(!
boundIds
.
isEmpty
())
{
queryWrapper
.
notIn
(
"id"
,
boundIds
);
}
}
else
{
idListFromDiyUser
=
customProductDiyUserRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductDiyUserRelEntity
>()
.
eq
(
CustomProductDiyUserRelEntity:
:
getDiyUserId
,
param
.
getDiyUserId
()))
.
stream
()
.
map
(
CustomProductDiyUserRelEntity:
:
getProductId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
if
(
idListFromDiyUser
.
isEmpty
())
{
// 该 DIY 用户未绑定任何商品,直接返回空结果
queryWrapper
.
eq
(
"id"
,
-
1
);
}
}
}
if
(
param
.
getBlackUserId
()
!=
null
)
{
idListFromBlacklist
=
customProductBlacklistDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductBlacklistEntity
>()
.
eq
(
CustomProductBlacklistEntity:
:
getDiyUserId
,
param
.
getBlackUserId
()))
.
stream
()
.
map
(
CustomProductBlacklistEntity:
:
getProductId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
}
}
if
(
param
.
getProcessing
()
!=
null
||
param
.
getProcessing
()
==
0
)
{
if
(
param
.
getProcessing
()
==
1
)
{
// diyUserId 和 blackUserId 同时存在时取交集
queryWrapper
.
eq
(
"processing"
,
1
);
if
(
idListFromDiyUser
!=
null
&&
idListFromBlacklist
!=
null
)
{
}
else
if
(
param
.
getProcessing
()
==
0
)
{
List
<
Integer
>
intersection
=
idListFromDiyUser
.
stream
()
queryWrapper
.
eq
(
"processing"
,
0
);
.
filter
(
idListFromBlacklist:
:
contains
)
}
else
if
(
param
.
getProcessing
()
==
2
)
{
.
collect
(
Collectors
.
toList
());
queryWrapper
.
isNull
(
"processing"
);
if
(
intersection
.
isEmpty
())
{
queryWrapper
.
eq
(
"id"
,
-
1
);
// 交集为空,返回空结果
}
else
{
queryWrapper
.
in
(
"id"
,
intersection
);
}
}
}
else
if
(
idListFromDiyUser
!=
null
)
{
queryWrapper
.
in
(
"id"
,
idListFromDiyUser
);
}
else
if
(
idListFromBlacklist
!=
null
)
{
queryWrapper
.
in
(
"id"
,
idListFromBlacklist
);
}
}
queryWrapper
.
orderByDesc
(
"id"
);
queryWrapper
.
orderByDesc
(
"id"
);
}
}
@Override
@Override
public
CustomProductInfoVO
info
(
Integer
id
)
{
public
void
saveFull
(
CustomProductInfoSnakeDTO
dto
)
{
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomAsserts
.
nonNull
(
dto
,
"创建参数不能为空"
);
CustomProductInfoEntity
customProductInfo
=
customProductInfoDomainService
.
getById
(
id
);
return
BeanMapper
.
mapper
().
convert
(
customProductInfo
,
CustomProductInfoVO
.
class
);
// 1. 生成 SKU 调用SysBillRuleService
String
sku
=
sysBillRuleService
.
getProductSku
(
SkuGenerateEnums
.
TEMPLATE_PRODUCT
.
getCode
());
log
.
debug
(
"[ saveFull ] 生成 SKU: {}"
,
sku
);
if
(
StringUtils
.
isBlank
(
sku
))
{
throw
new
ServiceException
(
"生成 SKU 失败"
);
}
// 2. 事务外预先计算主表的工厂价/销售价(从子项取 min/max)
computeProductPricesFromItems
(
dto
);
// 3. 编程式事务写入所有表
transactionTemplate
.
executeWithoutResult
(
status
->
{
// 3a. 保存主表
CustomProductInfoEntity
entity
=
buildEntityFromSaveDTO
(
dto
,
sku
);
customProductInfoDomainService
.
save
(
entity
);
Integer
productId
=
entity
.
getId
();
log
.
debug
(
"[ saveFull ] 主表保存成功, productId: {}"
,
productId
);
// 3b. 保存子项(逐条保存以获取自增 ID,返回 originalSku → savedEntity 映射)
Map
<
String
,
CustomProductItemEntity
>
itemMap
=
saveProductItemsIndividually
(
dto
.
getProductList
(),
sku
,
productId
,
entity
);
// 3c. 保存工厂价格关联(利用 itemMap 替换 item_sku 为生成的 SKU 并填充 item_id)
saveFactoryPriceRels
(
dto
.
getFactoryPriceList
(),
productId
,
itemMap
);
// 3d. 保存产品-工厂关联(product_factory_rel 表)
saveFactoryRels
(
dto
.
getFactoryIds
(),
productId
);
// 3e. 保存 DIY 用户关联
//saveDiyUserRels(dto.getDiyUserIds(), productId);
// 3f. 保存工艺关联
saveCraftRels
(
dto
.
getCraftIds
(),
productId
);
// 3g. 保存价格区间关联
saveFactoryPriceIntervalRels
(
dto
.
getFactoryPriceIntervalList
(),
productId
);
// 3h. 保存图片(普通图 + 尺码图)
saveImages
(
dto
.
getImageList
(),
dto
.
getSizeList
(),
productId
);
// 3i. 保存备注(英文 + 中文)
saveRemarks
(
dto
.
getRemark
(),
dto
.
getCnRemark
(),
productId
);
// 3j. 保存属性(SKU 属性 + 普通属性)
saveProperties
(
dto
.
getSkuProperties
(),
dto
.
getNormalProperties
(),
productId
);
// 3k. 保存仓库关联
saveWarehouseRels
(
dto
.
getWarehouseIds
(),
productId
);
// 3l. 事务内记录日志(对齐 TS:日志与数据写入同一事务)
saveLogTransaction
(
productId
,
"创建商品"
);
});
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
save
(
CustomProductInfoVO
customProductInfoVO
)
{
public
void
updateFull
(
CustomProductInfoUpdateDTO
dto
)
{
CustomAsserts
.
nonNull
(
customProductInfoVO
,
"实体对象不能为空"
);
/*CustomAsserts.nonNull(dto, "更新参数不能为空");
CustomProductInfoEntity
customProductInfoEntity
=
BeanMapper
.
mapper
().
convert
(
customProductInfoVO
,
CustomProductInfoEntity
.
class
);
CustomAsserts.nonNull(dto.getId(), "商品 ID 不能为空");
transactionTemplate.executeWithoutResult(status -> {
Integer productId = dto.getId();
// 1. 更新主表
CustomProductInfoEntity entity = buildEntityFromSaveDTO(dto, null);
entity.setId(productId);
customProductInfoDomainService.updateById(entity);
// 2. 处理子项的增/删/改
if (dto.getProductChange() != null) {
handleItemChanges(dto.getProductChange(), productId);
}
// 3. 处理工厂价格变更
if (dto.getProductFactoryPriceChange() != null) {
handleFactoryPriceChanges(dto.getProductFactoryPriceChange(), productId);
}
// 4. 销毁并重建属性
rebuildProperties(dto.getSkuProperties(), dto.getNormalProperties(), productId);
// 5. 处理图片变更
if (dto.getProductImageChange() != null) {
handleImageChanges(dto.getProductImageChange(), productId, IMAGE_TYPE_NORMAL);
}
if (dto.getProductSizeChange() != null) {
handleImageChanges(dto.getProductSizeChange(), productId, IMAGE_TYPE_SIZE);
}
// 6. 更新备注(先删后插)
updateRemarks(dto.getRemark(), dto.getCnRemark(), productId);
// 7. 重建工厂/仓库/工艺/DIY用户/价格区间关联(先删后插)
rebuildRels(dto.getFactoryIds(), dto.getWarehouseIds(), dto.getCraftIds(),
dto.getDiyUserIds(), dto.getFactoryPriceIntervalList(), productId);
// 8. 事务内记日志
saveLogTransaction(productId, "修改商品信息");
});*/
}
@Override
public
CustomProductInfoSnakeVO
getByIdOrSku
(
Integer
id
,
String
sku
,
String
namespace
)
{
// 1. 查询主表
CustomProductInfoEntity
entity
;
if
(
id
!=
null
)
{
entity
=
customProductInfoDomainService
.
getById
(
id
);
}
else
if
(
StringUtils
.
isNotBlank
(
sku
))
{
entity
=
customProductInfoDomainService
.
getBySku
(
sku
);
}
else
{
throw
new
ServiceException
(
"id 和 sku 至少需要提供一个"
);
}
if
(
entity
==
null
)
{
throw
new
ServiceException
(
"商品信息不存在, id="
+
id
+
", sku="
+
sku
);
}
final
Integer
productId
=
entity
.
getId
();
// 1a. 根据 namespace 查询 DIY 用户(对齐 TS:197-203)
DbDiyUserEntity
user
=
null
;
if
(
StringUtils
.
isNotBlank
(
namespace
))
{
user
=
diyUserService
.
getByNamespace
(
namespace
);
if
(
user
==
null
)
{
throw
new
ServiceException
(
"用户不存在, namespace="
+
namespace
);
}
}
// 2. 并行查询所有子表(单表查询,Java 层组合,使用自定义线程池 + 超时保护)
CompletableFuture
<
List
<
CustomProductItemEntity
>>
itemsFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductItemDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductItemEntity
>()
.
eq
(
CustomProductItemEntity:
:
getProductId
,
productId
)
.
orderByAsc
(
CustomProductItemEntity:
:
getSort
)),
threadPoolExecutor
);
CompletableFuture
<
List
<
CustomProductImageEntity
>>
imagesFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductImageDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductImageEntity
>()
.
eq
(
CustomProductImageEntity:
:
getProductId
,
productId
)),
threadPoolExecutor
);
CompletableFuture
<
List
<
CustomProductInfoPropertyEntity
>>
propertiesFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductInfoPropertyDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductInfoPropertyEntity
>()
.
eq
(
CustomProductInfoPropertyEntity:
:
getInfoId
,
productId
)),
threadPoolExecutor
);
CompletableFuture
<
List
<
CustomProductFactoryPriceRelEntity
>>
factoryPriceFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductFactoryPriceRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductFactoryPriceRelEntity
>()
.
eq
(
CustomProductFactoryPriceRelEntity:
:
getProductId
,
productId
)),
threadPoolExecutor
);
CompletableFuture
<
List
<
Integer
>>
diyUserIdsFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductDiyUserRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductDiyUserRelEntity
>()
.
eq
(
CustomProductDiyUserRelEntity:
:
getProductId
,
productId
))
.
stream
().
map
(
CustomProductDiyUserRelEntity:
:
getDiyUserId
)
.
collect
(
Collectors
.
toList
()),
threadPoolExecutor
);
CompletableFuture
<
List
<
Long
>>
craftIdsFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductCraftRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductCraftRelEntity
>()
.
eq
(
CustomProductCraftRelEntity:
:
getProductId
,
productId
))
.
stream
().
map
(
CustomProductCraftRelEntity:
:
getCraftId
)
.
collect
(
Collectors
.
toList
()),
threadPoolExecutor
);
CompletableFuture
<
List
<
Integer
>>
warehouseIdsFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductWarehouseRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductWarehouseRelEntity
>()
.
eq
(
CustomProductWarehouseRelEntity:
:
getProductId
,
productId
))
.
stream
().
map
(
r
->
r
.
getWarehouseId
().
intValue
())
.
collect
(
Collectors
.
toList
()),
threadPoolExecutor
);
CompletableFuture
<
CustomProductRemarkEntity
>
remarkFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductRemarkDomainService
.
getOne
(
new
LambdaQueryWrapper
<
CustomProductRemarkEntity
>()
.
eq
(
CustomProductRemarkEntity:
:
getProductId
,
productId
)),
threadPoolExecutor
);
CompletableFuture
<
CustomProductCnRemarkEntity
>
cnRemarkFuture
=
CompletableFuture
.
supplyAsync
(()
->
customProductCnRemarkDomainService
.
getOne
(
new
LambdaQueryWrapper
<
CustomProductCnRemarkEntity
>()
.
eq
(
CustomProductCnRemarkEntity:
:
getProductId
,
productId
)),
threadPoolExecutor
);
// 工厂关联 ID 列表(product_factory_rel 表)
CompletableFuture
<
List
<
Integer
>>
factoryIdsFuture
=
CompletableFuture
.
supplyAsync
(()
->
productFactoryRelDomainService
.
list
(
new
LambdaQueryWrapper
<
ProductFactoryRelEntity
>()
.
eq
(
ProductFactoryRelEntity:
:
getProductId
,
productId
))
.
stream
().
map
(
ProductFactoryRelEntity:
:
getFactoryId
)
.
collect
(
Collectors
.
toList
()),
threadPoolExecutor
);
// 3. 等待所有查询完成(带超时保护,防止某个查询永久阻塞)
try
{
CompletableFuture
.
allOf
(
itemsFuture
,
imagesFuture
,
propertiesFuture
,
factoryPriceFuture
,
diyUserIdsFuture
,
craftIdsFuture
,
warehouseIdsFuture
,
remarkFuture
,
cnRemarkFuture
,
factoryIdsFuture
)
.
orTimeout
(
QUERY_TIMEOUT_SECONDS
,
TimeUnit
.
SECONDS
)
.
join
();
}
catch
(
CompletionException
e
)
{
// 超时或异常时取消所有未完成的任务
cancelAll
(
itemsFuture
,
imagesFuture
,
propertiesFuture
,
factoryPriceFuture
,
diyUserIdsFuture
,
craftIdsFuture
,
warehouseIdsFuture
,
remarkFuture
,
cnRemarkFuture
,
factoryIdsFuture
);
throw
new
ServiceException
(
"查询商品详情超时, productId="
+
productId
)
.
setDetailMessage
(
e
.
toString
());
}
// 4. Java 层组合结果
CustomProductInfoSnakeVO
fullVO
;
List
<
CustomProductInfoPropertyEntity
>
properties
;
try
{
try
{
customProductInfoDomainService
.
save
(
customProductInfoEntity
);
properties
=
propertiesFuture
.
get
();
}
catch
(
DuplicateKeyException
e
)
{
fullVO
=
buildProductFullVO
(
entity
,
log
.
info
(
"[ CustomProductInfoServiceImpl save ] 实体对象唯一约束重复,请调整后再试!"
,
e
);
itemsFuture
.
get
(),
throw
new
ServiceException
(
"实体对象唯一约束重复,请调整后再试!"
);
imagesFuture
.
get
(),
factoryPriceFuture
.
get
(),
diyUserIdsFuture
.
get
(),
craftIdsFuture
.
get
(),
warehouseIdsFuture
.
get
(),
remarkFuture
.
get
(),
cnRemarkFuture
.
get
(),
factoryIdsFuture
.
get
());
}
catch
(
Exception
e
)
{
throw
new
ServiceException
(
"组装商品详情失败, productId="
+
productId
+
": "
+
e
.
getMessage
())
.
setDetailMessage
(
e
.
toString
());
}
// 5. 通过 AdminPropertyService 解析属性名称(对齐 TS:217-236)
resolvePropertyNames
(
properties
,
fullVO
);
// 6. 如果查询了用户,应用外部定价折扣(对齐 TS:241-243)
if
(
user
!=
null
)
{
diyUserService
.
setProductExternalPrice
(
user
,
fullVO
);
}
}
return
fullVO
;
}
/**
* 通过 AdminPropertyService 解析属性名称,填充到 FullVO 的 skuProperties / normalProperties 中
* <p>
* 对齐 TS:217-236 — 将数据库中存储的 property_id/value_id 转换为带名称的属性列表。
*
* @param properties 数据库原始属性记录
* @param fullVO 待填充的商品完整详情
*/
private
void
resolvePropertyNames
(
List
<
CustomProductInfoPropertyEntity
>
properties
,
CustomProductInfoSnakeVO
fullVO
)
{
if
(
properties
==
null
||
properties
.
isEmpty
())
{
return
;
}
fullVO
.
setProperties
(
properties
.
stream
().
map
(
e
->
BeanMapper
.
snakeCase
()
.
convert
(
e
,
CustomProductInfoPropertySnakeVO
.
class
)).
collect
(
Collectors
.
toList
()));
// 收集所有 property_id
String
propIds
=
properties
.
stream
().
map
(
p
->
String
.
valueOf
(
p
.
getPropertyId
()))
.
distinct
().
collect
(
Collectors
.
joining
(
","
));
if
(
propIds
.
isEmpty
())
{
return
;
}
// 调用 saas admin API 获取属性定义(含 valueList)
List
<
BasePropertyModel
>
publicProperties
=
saasAdminService
.
getPropertyByIds
(
propIds
);
if
(
publicProperties
==
null
||
publicProperties
.
isEmpty
())
{
return
;
}
// 收集当前商品使用的 value_id
Set
<
Integer
>
valueIds
=
properties
.
stream
().
map
(
CustomProductInfoPropertyEntity:
:
getValueId
)
.
filter
(
Objects:
:
nonNull
).
collect
(
Collectors
.
toSet
());
// 按 skuProperty 拆分为 SKU 属性和普通属性(对齐 TS:234-235)
// 转换为 CustomProductInfoPropertyVO 列表
List
<
CustomProductInfoSkuPropertiesVO
>
skuProps
=
new
ArrayList
<>();
List
<
CustomProductInfoSkuPropertiesVO
>
normalProps
=
new
ArrayList
<>();
for
(
BasePropertyModel
prop
:
publicProperties
)
{
CustomProductInfoSkuPropertiesVO
propVO
=
BeanMapper
.
snakeCase
().
convert
(
prop
,
CustomProductInfoSkuPropertiesVO
.
class
);
if
(
CollectionUtils
.
isNotEmpty
(
prop
.
getValueList
()))
{
// 过滤每个属性的 valueList,只保留当前商品使用的值(对齐 TS:222-233)
List
<
BasePropertyValueModel
>
filtered
=
prop
.
getValueList
().
stream
()
.
filter
(
v
->
valueIds
.
contains
(
v
.
getId
())).
toList
();
// 转换为 CustomProductPropertiesValueVO 列表,并赋值给valueList
propVO
.
setValueList
(
filtered
.
stream
().
map
(
v
->
BeanMapper
.
mapper
().
convert
(
v
,
CustomProductPropertiesValueVO
.
class
)).
toList
());
}
// 检查是否是SKU属性,如果是则添加到skuProps,否则添加到normalProps
(
prop
.
getSkuProperty
()
?
skuProps
:
normalProps
).
add
(
propVO
);
}
// 填充到 FullVO 中
fullVO
.
setSkuProperties
(
skuProps
);
fullVO
.
setNormalProperties
(
normalProps
);
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
updateById
(
CustomProductInfoVO
customProductInfoVO
)
{
public
void
bindsDiyUser
(
BindDiyUserDTO
dto
)
{
CustomAsserts
.
nonNull
(
customProductInfoVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
dto
,
"绑定参数不能为空"
);
CustomProductInfoEntity
customProductInfo
=
BeanMapper
.
mapper
().
convert
(
customProductInfoVO
,
CustomProductInfoEntity
.
class
);
CustomAsserts
.
nonNull
(
dto
.
getProductIds
(),
"商品 ID 列表不能为空"
);
try
{
customProductInfoDomainService
.
updateById
(
customProductInfo
);
transactionTemplate
.
executeWithoutResult
(
status
->
{
}
catch
(
DuplicateKeyException
e
)
{
for
(
Integer
productId
:
dto
.
getProductIds
())
{
log
.
info
(
"[ CustomProductInfoServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!"
,
e
);
// 先删除该商品的所有现有绑定
throw
new
ServiceException
(
"实体对象唯一约束重复,请调整后再试!"
);
customProductDiyUserRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductDiyUserRelEntity
>()
.
eq
(
CustomProductDiyUserRelEntity:
:
getProductId
,
productId
));
// 再插入新的绑定
if
(
dto
.
getDiyUserIds
()
!=
null
&&
!
dto
.
getDiyUserIds
().
isEmpty
())
{
List
<
CustomProductDiyUserRelEntity
>
rels
=
dto
.
getDiyUserIds
().
stream
()
.
map
(
diyUserId
->
{
CustomProductDiyUserRelEntity
rel
=
new
CustomProductDiyUserRelEntity
();
rel
.
setProductId
(
productId
);
rel
.
setDiyUserId
(
diyUserId
);
return
rel
;
})
.
collect
(
Collectors
.
toList
());
customProductDiyUserRelDomainService
.
saveBatch
(
rels
);
}
}
saveLogBatch
(
"绑定客户"
,
dto
.
getProductIds
());
});
}
@Override
public
void
addBlackList
(
AddBlackListDTO
dto
)
{
CustomAsserts
.
nonNull
(
dto
,
"黑名单参数不能为空"
);
CustomAsserts
.
nonNull
(
dto
.
getProductIds
(),
"商品 ID 列表不能为空"
);
transactionTemplate
.
executeWithoutResult
(
status
->
{
for
(
Integer
productId
:
dto
.
getProductIds
())
{
// 先删除该商品的所有现有黑名单
customProductBlacklistDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductBlacklistEntity
>()
.
eq
(
CustomProductBlacklistEntity:
:
getProductId
,
productId
));
// 再插入新的黑名单
if
(
dto
.
getDiyUserIds
()
!=
null
&&
!
dto
.
getDiyUserIds
().
isEmpty
())
{
List
<
CustomProductBlacklistEntity
>
blacklists
=
dto
.
getDiyUserIds
().
stream
()
.
map
(
diyUserId
->
{
CustomProductBlacklistEntity
bl
=
new
CustomProductBlacklistEntity
();
bl
.
setProductId
(
productId
);
bl
.
setDiyUserId
(
diyUserId
);
return
bl
;
})
.
collect
(
Collectors
.
toList
());
customProductBlacklistDomainService
.
saveBatch
(
blacklists
);
}
}
saveLogBatch
(
"加入黑名单"
,
dto
.
getProductIds
());
});
}
@Override
public
void
bindDefaultDiy
(
Integer
id
,
Integer
diyId
,
String
diySku
)
{
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
// 使用 LambdaUpdateWrapper 仅更新指定字段,避免 updateById 清空其他字段
customProductInfoDomainService
.
update
(
new
LambdaUpdateWrapper
<
CustomProductInfoEntity
>()
.
eq
(
CustomProductInfoEntity:
:
getId
,
id
)
.
set
(
CustomProductInfoEntity:
:
getDiyId
,
diyId
)
.
set
(
CustomProductInfoEntity:
:
getDiySku
,
diySku
));
}
@Override
public
List
<
DbDiyVO
>
getBindsDiyById
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
// 注:当前 custom-server 中没有 product_template_info 表,
// TS 版本通过该表关联 DIY。此处暂时通过默认 DIY ID 返回。
CustomProductInfoEntity
entity
=
customProductInfoDomainService
.
getById
(
id
);
if
(
entity
==
null
||
entity
.
getDiyId
()
==
null
)
{
return
Collections
.
emptyList
();
}
}
DbDiyEntity
diy
=
dbDiyDomainService
.
getById
(
entity
.
getDiyId
());
if
(
diy
==
null
)
{
return
Collections
.
emptyList
();
}
return
Collections
.
singletonList
(
BeanMapper
.
mapper
().
convert
(
diy
,
DbDiyVO
.
class
));
}
@Override
public
List
<
Integer
>
getBindsDiyUserById
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
return
customProductDiyUserRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductDiyUserRelEntity
>()
.
eq
(
CustomProductDiyUserRelEntity:
:
getProductId
,
id
))
.
stream
()
.
map
(
CustomProductDiyUserRelEntity:
:
getDiyUserId
)
.
collect
(
Collectors
.
toList
());
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
deleteById
(
Integer
id
)
{
public
List
<
Integer
>
getBlackListById
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
customProductInfoDomainService
.
removeById
(
id
);
return
customProductBlacklistDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductBlacklistEntity
>()
.
eq
(
CustomProductBlacklistEntity:
:
getProductId
,
id
))
.
stream
()
.
map
(
CustomProductBlacklistEntity:
:
getDiyUserId
)
.
collect
(
Collectors
.
toList
());
}
}
@Override
public
List
<
Long
>
getCraftById
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
return
customProductCraftRelDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomProductCraftRelEntity
>()
.
eq
(
CustomProductCraftRelEntity:
:
getProductId
,
id
))
.
stream
()
.
map
(
CustomProductCraftRelEntity:
:
getCraftId
)
.
collect
(
Collectors
.
toList
());
}
// ==================== ERP 专用接口 ====================
@Override
public
List
<
DbDiyVO
>
getErpBindsDiyById
(
Integer
id
,
String
userMark
,
String
namespace
)
{
CustomAsserts
.
nonNull
(
id
,
"商品 ID 不能为空"
);
// 1. 根据 userMark 或 namespace 查询用户(对齐 TS:751-759)
DbDiyUserEntity
user
;
if
(
StringUtils
.
isNotBlank
(
userMark
))
{
user
=
diyUserService
.
getByUserMark
(
userMark
);
}
else
{
user
=
diyUserService
.
getByNamespace
(
namespace
);
}
if
(
user
==
null
)
{
throw
new
ServiceException
(
"客户不存在"
);
}
// 2. 查询 product_template_info 获取 diy_id 列表(对齐 TS:760-762)
List
<
ProductTemplateInfoEntity
>
templates
=
productTemplateInfoDomainService
.
selectByProductId
(
id
);
if
(
templates
.
isEmpty
())
{
return
Collections
.
emptyList
();
}
List
<
Integer
>
diyIds
=
templates
.
stream
()
.
map
(
ProductTemplateInfoEntity:
:
getDiyId
)
.
filter
(
d
->
d
!=
null
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
// 3. 查询 db_diy,根据用户类型过滤状态(对齐 TS:766-783)
List
<
Integer
>
statusList
;
String
userName
=
user
.
getName
();
if
(
"demo"
.
equals
(
userName
))
{
statusList
=
Arrays
.
asList
(
TemplateStatus
.
SHELF_CODE
,
TemplateStatus
.
WAIT_SHELF
.
getCode
());
// demo 用户可见待上架
}
else
{
statusList
=
Collections
.
singletonList
(
TemplateStatus
.
SHELF_CODE
);
}
List
<
DbDiyEntity
>
diys
=
dbDiyDomainService
.
list
(
new
LambdaQueryWrapper
<
DbDiyEntity
>()
.
in
(
DbDiyEntity:
:
getId
,
diyIds
)
.
in
(
DbDiyEntity:
:
getStatus
,
statusList
));
if
(
diys
.
isEmpty
())
{
return
Collections
.
emptyList
();
}
// 4. 转换为 VO 并附带效果图(对齐 TS:783 include DbDiyXiaoguotu)
return
diys
.
stream
().
map
(
diy
->
{
DbDiyVO
vo
=
BeanMapper
.
mapper
().
convert
(
diy
,
DbDiyVO
.
class
);
List
<
DbDiyXiaoguotuEntity
>
xiaoguotus
=
dbDiyXiaoguotuDomainService
.
selectByDiyId
(
diy
.
getId
());
// 将效果图数据附加到 VO(通过扩展方式,当前 DbDiyVO 无 xiaoguotu 字段,
// 如有需要可扩展 DbDiyVO)
return
vo
;
}).
collect
(
Collectors
.
toList
());
}
@Override
public
IPage
<
CustomProductInfoVO
>
erpPage
(
CustomProductInfoSnakeDTO
param
)
{
CustomAsserts
.
nonNull
(
param
,
"分页查询参数不能为空"
);
// 1. 查询用户(对齐 TS:683-684)
DbDiyUserEntity
user
=
null
;
if
(
StringUtils
.
isNotBlank
(
param
.
getUserMark
()))
{
user
=
diyUserService
.
getByUserMark
(
param
.
getUserMark
());
if
(
user
==
null
)
{
// 用户不存在,返回空结果
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
}
// 2. 构建查询条件(复用 + ERP 特有逻辑)
QueryWrapper
<
CustomProductInfoEntity
>
queryWrapper
=
new
QueryWrapper
<>();
toQueryWrapper
(
param
,
queryWrapper
);
// 3. DIY 模板过滤(对齐 TS:630-657)
if
(
StringUtils
.
isNotBlank
(
param
.
getDiySku
())
||
StringUtils
.
isNotBlank
(
param
.
getSource
())
||
param
.
getDiyId
()
!=
null
)
{
LambdaQueryWrapper
<
DbDiyEntity
>
diyWrapper
=
new
LambdaQueryWrapper
<>();
if
(
StringUtils
.
isNotBlank
(
param
.
getDiySku
()))
{
diyWrapper
.
eq
(
DbDiyEntity:
:
getSku
,
param
.
getDiySku
());
}
if
(
param
.
getDiyId
()
!=
null
)
{
diyWrapper
.
eq
(
DbDiyEntity:
:
getId
,
param
.
getDiyId
());
}
if
(
StringUtils
.
isNotBlank
(
param
.
getSource
()))
{
diyWrapper
.
eq
(
DbDiyEntity:
:
getNamespace
,
param
.
getSource
());
}
List
<
DbDiyEntity
>
diys
=
dbDiyDomainService
.
list
(
diyWrapper
);
if
(
diys
.
isEmpty
())
{
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
List
<
Integer
>
diyIds
=
diys
.
stream
().
map
(
DbDiyEntity:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
ProductTemplateInfoEntity
>
temps
=
productTemplateInfoDomainService
.
selectByDiyIds
(
diyIds
);
if
(
temps
.
isEmpty
())
{
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
List
<
Integer
>
productIds
=
temps
.
stream
()
.
map
(
ProductTemplateInfoEntity:
:
getProductId
)
.
filter
(
pid
->
pid
!=
null
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
if
(
productIds
.
isEmpty
())
{
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
queryWrapper
.
in
(
"id"
,
productIds
);
}
// 4. 仓库国家过滤(对齐 TS:673-681)
if
(
StringUtils
.
isNotBlank
(
param
.
getWarehouseCountry
()))
{
List
<
CustomWarehouseInfoEntity
>
warehouses
=
customWarehouseInfoDomainService
.
list
(
new
LambdaQueryWrapper
<
CustomWarehouseInfoEntity
>()
.
eq
(
CustomWarehouseInfoEntity:
:
getCountryCode
,
param
.
getWarehouseCountry
()));
if
(
warehouses
.
isEmpty
())
{
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
List
<
Integer
>
wIds
=
warehouses
.
stream
()
.
map
(
w
->
w
.
getId
().
intValue
())
.
collect
(
Collectors
.
toList
());
List
<
CustomProductWarehouseRelEntity
>
rels
=
customProductWarehouseRelDomainService
.
selectByWarehouseIds
(
wIds
);
if
(
rels
.
isEmpty
())
{
return
new
com
.
baomidou
.
mybatisplus
.
extension
.
plugins
.
pagination
.
Page
<>(
param
.
getCurrent
(),
param
.
getSize
());
}
List
<
Integer
>
productIds
=
rels
.
stream
()
.
map
(
CustomProductWarehouseRelEntity:
:
getProductId
).
distinct
().
collect
(
Collectors
.
toList
());
queryWrapper
.
in
(
"id"
,
productIds
);
}
// 5. 执行分页查询
queryWrapper
.
orderByDesc
(
"id"
);
IPage
<
CustomProductInfoEntity
>
page
=
customProductInfoDomainService
.
selectPage
(
queryWrapper
,
param
);
// 6. 转换并应用外部定价(对齐 TS:731-738)
// 预计算折扣率(放入 final 变量,供 lambda 使用)
final
BigDecimal
discountRate
;
if
(
user
!=
null
&&
user
.
getDiscount
()
!=
null
)
{
discountRate
=
user
.
getDiscount
().
divide
(
new
BigDecimal
(
"100"
),
4
,
RoundingMode
.
HALF_UP
);
}
else
{
discountRate
=
null
;
}
return
page
.
convert
(
e
->
{
CustomProductInfoVO
vo
=
BeanMapper
.
mapper
().
convert
(
e
,
CustomProductInfoVO
.
class
);
if
(
discountRate
!=
null
)
{
if
(
vo
.
getSalesPrice
()
!=
null
)
{
vo
.
setSalesPrice
(
vo
.
getSalesPrice
().
multiply
(
discountRate
).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
}
if
(
vo
.
getSalesPriceMax
()
!=
null
)
{
vo
.
setSalesPriceMax
(
vo
.
getSalesPriceMax
().
multiply
(
discountRate
).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
}
}
return
vo
;
});
}
/**
* 从事务外的子项列表中计算主表的 factory_price / sales_price / sales_price_max
* <p>
* factory_price 取子项中的最小值,sales_price 取子项中的最大值,sales_price_max 取子项中的最大值。
*/
private
void
computeProductPricesFromItems
(
CustomProductInfoSnakeDTO
dto
)
{
if
(
dto
.
getProductList
()
==
null
||
dto
.
getProductList
().
isEmpty
())
{
return
;
}
BigDecimal
factoryPrice
=
null
;
BigDecimal
salesPrice
=
null
;
BigDecimal
salesPriceMax
=
null
;
for
(
CustomProductItemSnakeDTO
item
:
dto
.
getProductList
())
{
if
(
item
.
getFactory_price
()
!=
null
)
{
// 当前值 < 子项值时替换 取最大值
if
(
factoryPrice
==
null
||
factoryPrice
.
compareTo
(
item
.
getFactory_price
())
<
0
)
{
factoryPrice
=
item
.
getFactory_price
();
}
}
if
(
item
.
getSales_price
()
!=
null
)
{
// 当前值 < 子项值时替换 取最大值
if
(
salesPrice
==
null
||
salesPrice
.
compareTo
(
item
.
getSales_price
())
<
0
)
{
salesPrice
=
item
.
getSales_price
();
}
// 当前值 > 子项值时替换 取最小值
if
(
salesPriceMax
==
null
||
salesPriceMax
.
compareTo
(
item
.
getSales_price
())
>
0
)
{
salesPriceMax
=
item
.
getSales_price
();
}
}
}
if
(
factoryPrice
!=
null
)
{
dto
.
setFactory_price
(
factoryPrice
);
}
if
(
salesPrice
!=
null
)
{
dto
.
setSales_price
(
salesPrice
);
}
if
(
salesPriceMax
!=
null
)
{
dto
.
setSales_price_max
(
salesPriceMax
);
}
}
/**
* 从 SaveDTO 构建 Entity
* <p>
* SaveDTO 使用驼峰命名,与 Entity 字段名一致,直接用默认 mapper 转换。
* 对于蛇形命名的 {@link CustomProductInfoSnakeDTO},调用方需先用 {@code BeanMapper.snakeCase()} 转为 SaveDTO。
*
* @param dto 保存 DTO(驼峰命名)
* @param sku 生成的 SKU(创建时传入,更新时传 null)
* @return 商品实体
*/
private
CustomProductInfoEntity
buildEntityFromSaveDTO
(
CustomProductInfoSnakeDTO
dto
,
String
sku
)
{
CustomProductInfoEntity
entity
=
BeanMapper
.
snakeCase
().
convert
(
dto
,
CustomProductInfoEntity
.
class
);
if
(
sku
!=
null
)
{
entity
.
setSku
(
sku
);
}
return
entity
;
}
/**
* 逐条保存子项并返回原始 SKU → 已保存实体的映射
* <p>
* 逐条保存是为了获取每条记录的自增 ID,供后续工厂价格关联的 item_id 填充使用。
* 对齐 TS {@code save} 方法 100-117 行。
*
* @return Map<原始DTO中的SKU, 已保存的实体(含自增ID和替换后的SKU)>
*/
private
Map
<
String
,
CustomProductItemEntity
>
saveProductItemsIndividually
(
List
<
CustomProductItemSnakeDTO
>
itemDTOs
,
String
generatedSku
,
Integer
productId
,
CustomProductInfoEntity
mainProduct
)
{
Map
<
String
,
CustomProductItemEntity
>
itemMap
=
new
HashMap
<>();
if
(
itemDTOs
==
null
||
itemDTOs
.
isEmpty
())
{
return
itemMap
;
}
for
(
CustomProductItemSnakeDTO
dto
:
itemDTOs
)
{
String
originalSku
=
dto
.
getSku
();
// 保存原始 SKU 作为 map key
CustomProductItemEntity
item
=
BeanMapper
.
snakeCase
().
convert
(
dto
,
CustomProductItemEntity
.
class
);
item
.
setProductId
(
productId
);
// 替换 SKU 占位符
if
(
item
.
getSku
()
!=
null
)
{
item
.
setSku
(
item
.
getSku
().
replace
(
"SKU"
,
generatedSku
));
}
// 同步主表的 print_type 和 product_no 到子项(对齐 TS:102,105)
item
.
setPrintType
(
mainProduct
.
getPrintType
());
item
.
setProductNo
(
mainProduct
.
getProductNo
());
// 逐条保存以获取自增 ID
customProductItemDomainService
.
save
(
item
);
itemMap
.
put
(
originalSku
,
item
);
}
log
.
info
(
"[ saveProductItems ] 逐条保存 {} 个子项, productId: {}"
,
itemMap
.
size
(),
productId
);
return
itemMap
;
}
/**
* 保存工厂价格关联(利用 itemMap 替换 item_sku 为生成的 SKU 并填充 item_id)
* <p>
* 对齐 TS {@code save} 方法 132-139 行。
*/
private
void
saveFactoryPriceRels
(
List
<
FactoryPriceRelDTO
>
factoryPriceList
,
Integer
productId
,
Map
<
String
,
CustomProductItemEntity
>
itemMap
)
{
if
(
factoryPriceList
==
null
||
factoryPriceList
.
isEmpty
())
{
return
;
}
List
<
CustomProductFactoryPriceRelEntity
>
rels
=
new
ArrayList
<>();
for
(
FactoryPriceRelDTO
dto
:
factoryPriceList
)
{
CustomProductFactoryPriceRelEntity
rel
=
BeanMapper
.
snakeCase
().
convert
(
dto
,
CustomProductFactoryPriceRelEntity
.
class
);
rel
.
setProductId
(
productId
);
// 从 itemMap 中查找对应的子项,替换 item_sku 为生成的 SKU 并填充 item_id(对齐 TS:134-137)
CustomProductItemEntity
item
=
itemMap
.
get
(
dto
.
getItemSku
());
if
(
item
!=
null
)
{
rel
.
setItemSku
(
item
.
getSku
());
// 替换为替换后的 SKU
rel
.
setItemId
(
item
.
getId
());
// 填充自增 ID
}
rels
.
add
(
rel
);
}
customProductFactoryPriceRelDomainService
.
saveBatch
(
rels
);
}
/**
* 保存产品-工厂关联(product_factory_rel 表)
* <p>
* 对齐 TS {@code save} 方法 162-163 行。
*/
private
void
saveFactoryRels
(
List
<
Integer
>
factoryIds
,
Integer
productId
)
{
if
(
factoryIds
==
null
||
factoryIds
.
isEmpty
())
{
return
;
}
List
<
ProductFactoryRelEntity
>
rels
=
factoryIds
.
stream
().
map
(
factoryId
->
{
ProductFactoryRelEntity
rel
=
new
ProductFactoryRelEntity
();
rel
.
setProductId
(
productId
);
rel
.
setFactoryId
(
factoryId
);
return
rel
;
}).
collect
(
Collectors
.
toList
());
productFactoryRelDomainService
.
saveBatch
(
rels
);
}
/**
* 保存 DIY 用户关联
*/
private
void
saveDiyUserRels
(
List
<
Integer
>
diyUserIds
,
Integer
productId
)
{
if
(
diyUserIds
==
null
||
diyUserIds
.
isEmpty
())
{
return
;
}
List
<
CustomProductDiyUserRelEntity
>
rels
=
diyUserIds
.
stream
().
map
(
diyUserId
->
{
CustomProductDiyUserRelEntity
rel
=
new
CustomProductDiyUserRelEntity
();
rel
.
setProductId
(
productId
);
rel
.
setDiyUserId
(
diyUserId
);
return
rel
;
}).
collect
(
Collectors
.
toList
());
customProductDiyUserRelDomainService
.
saveBatch
(
rels
);
}
/**
* 保存工艺关联
*/
private
void
saveCraftRels
(
List
<
Integer
>
craftIds
,
Integer
productId
)
{
if
(
craftIds
==
null
||
craftIds
.
isEmpty
())
{
return
;
}
List
<
CustomProductCraftRelEntity
>
rels
=
craftIds
.
stream
().
map
(
craftId
->
{
CustomProductCraftRelEntity
rel
=
new
CustomProductCraftRelEntity
();
rel
.
setProductId
(
productId
);
rel
.
setCraftId
(
craftId
.
longValue
());
return
rel
;
}).
collect
(
Collectors
.
toList
());
customProductCraftRelDomainService
.
saveBatch
(
rels
);
}
/**
* 保存价格区间关联
*/
private
void
saveFactoryPriceIntervalRels
(
List
<
FactoryPriceIntervalRelDTO
>
intervals
,
Integer
productId
)
{
if
(
intervals
==
null
||
intervals
.
isEmpty
())
{
return
;
}
List
<
CustomProductFactoryPriceIntervalRelEntity
>
rels
=
intervals
.
stream
().
map
(
dto
->
{
CustomProductFactoryPriceIntervalRelEntity
rel
=
BeanMapper
.
mapper
().
convert
(
dto
,
CustomProductFactoryPriceIntervalRelEntity
.
class
);
rel
.
setProductId
(
productId
);
return
rel
;
}).
collect
(
Collectors
.
toList
());
customProductFactoryPriceIntervalRelDomainService
.
saveBatch
(
rels
);
}
/**
* 构建图片实体列表
*/
private
List
<
CustomProductImageEntity
>
buildImageEntities
(
List
<
CustomProductImageSnakeDTO
>
imageList
,
Integer
productId
,
Integer
type
)
{
return
Optional
.
ofNullable
(
imageList
).
orElse
(
Collections
.
emptyList
()).
stream
().
map
(
dto
->
{
CustomProductImageEntity
entity
=
BeanMapper
.
snakeCase
().
convert
(
dto
,
CustomProductImageEntity
.
class
);
entity
.
setProductId
(
productId
);
entity
.
setType
(
type
);
entity
.
setCreateTime
(
new
Date
());
return
entity
;
}).
collect
(
Collectors
.
toList
());
}
/**
* 保存图片(普通图 type=0 + 尺码图 type=1)
*/
private
void
saveImages
(
List
<
CustomProductImageSnakeDTO
>
imageList
,
List
<
CustomProductImageSnakeDTO
>
sizeList
,
Integer
productId
)
{
List
<
CustomProductImageEntity
>
allImages
=
Stream
.
of
(
buildImageEntities
(
imageList
,
productId
,
IMAGE_TYPE_NORMAL
),
buildImageEntities
(
sizeList
,
productId
,
IMAGE_TYPE_SIZE
)
).
flatMap
(
List:
:
stream
).
collect
(
Collectors
.
toList
());
if
(
CollectionUtils
.
isNotEmpty
(
allImages
))
{
customProductImageDomainService
.
saveBatch
(
allImages
);
}
}
/**
* 保存备注(英文 + 中文)
*/
private
void
saveRemarks
(
String
remark
,
String
cnRemark
,
Integer
productId
)
{
if
(
StringUtils
.
isNotBlank
(
remark
))
{
CustomProductRemarkEntity
r
=
new
CustomProductRemarkEntity
();
r
.
setProductId
(
productId
);
r
.
setRemark
(
remark
);
customProductRemarkDomainService
.
save
(
r
);
}
if
(
StringUtils
.
isNotBlank
(
remark
))
{
CustomProductCnRemarkEntity
cr
=
new
CustomProductCnRemarkEntity
();
cr
.
setProductId
(
productId
);
cr
.
setRemark
(
cnRemark
);
customProductCnRemarkDomainService
.
save
(
cr
);
}
}
/**
* 保存属性(SKU 属性 + 普通属性)
*/
private
void
saveProperties
(
List
<
CustomProductInfoPropertyDTO
>
skuProperties
,
List
<
CustomProductInfoPropertyDTO
>
normalProperties
,
Integer
productId
)
{
List
<
CustomProductInfoPropertyEntity
>
allProps
=
Stream
.
of
(
buildPropertyEntities
(
skuProperties
,
productId
,
true
),
buildPropertyEntities
(
normalProperties
,
productId
,
false
)
)
.
flatMap
(
List:
:
stream
)
.
collect
(
Collectors
.
toList
());
if
(!
allProps
.
isEmpty
())
{
customProductInfoPropertyDomainService
.
saveBatch
(
allProps
);
}
}
/**
* 创建属性实体
*
* @param properties 属性值DTO
* @param productId 商品ID
* @param isSkuProperty 是否为SKU属性
* @return 属性实体
*/
private
List
<
CustomProductInfoPropertyEntity
>
buildPropertyEntities
(
List
<
CustomProductInfoPropertyDTO
>
properties
,
Integer
productId
,
boolean
isSkuProperty
)
{
if
(
CollectionUtils
.
isEmpty
(
properties
))
{
return
Collections
.
emptyList
();
}
return
properties
.
stream
().
filter
(
dto
->
CollectionUtils
.
isNotEmpty
(
dto
.
getValueList
()))
.
flatMap
(
dto
->
dto
.
getValueList
().
stream
().
map
(
valueDTO
->
createPropertyEntity
(
dto
,
valueDTO
,
productId
,
isSkuProperty
)))
.
collect
(
Collectors
.
toList
());
}
/**
* 创建属性实体
*
* @param dto 属性DTO
* @param valueDTO 属性值DTO
* @param productId 商品ID
* @param isSkuProperty 是否为SKU属性
* @return 属性实体
*/
private
CustomProductInfoPropertyEntity
createPropertyEntity
(
CustomProductInfoPropertyDTO
dto
,
CustomProductPropertiesValueDTO
valueDTO
,
Integer
productId
,
boolean
isSkuProperty
)
{
CustomProductInfoPropertyEntity
prop
=
new
CustomProductInfoPropertyEntity
();
prop
.
setInfoId
(
productId
);
prop
.
setPropertyId
(
dto
.
getId
());
prop
.
setValueId
(
valueDTO
.
getId
());
prop
.
setSkuProperty
(
isSkuProperty
);
return
prop
;
}
/**
* 保存仓库关联
*/
private
void
saveWarehouseRels
(
List
<
Integer
>
warehouseIds
,
Integer
productId
)
{
if
(
warehouseIds
==
null
||
warehouseIds
.
isEmpty
())
{
return
;
}
List
<
CustomProductWarehouseRelEntity
>
rels
=
warehouseIds
.
stream
().
map
(
wid
->
{
CustomProductWarehouseRelEntity
rel
=
new
CustomProductWarehouseRelEntity
();
rel
.
setProductId
(
productId
);
rel
.
setWarehouseId
(
wid
.
longValue
());
return
rel
;
}).
collect
(
Collectors
.
toList
());
customProductWarehouseRelDomainService
.
saveBatch
(
rels
);
}
// -------- updateFull 辅助方法 --------
/**
* 处理子项变更(增/删/改)
*/
private
void
handleItemChanges
(
com
.
jomalls
.
custom
.
app
.
dto
.
ProductChangeDTO
change
,
Integer
productId
)
{
if
(
change
==
null
)
{
return
;
}
// 删除
if
(
change
.
getRemoveList
()
!=
null
&&
!
change
.
getRemoveList
().
isEmpty
())
{
customProductItemDomainService
.
removeByIds
(
change
.
getRemoveList
());
}
// 修改
if
(
change
.
getUpdateList
()
!=
null
)
{
for
(
var
itemDTO
:
change
.
getUpdateList
())
{
CustomProductItemEntity
item
=
BeanMapper
.
mapper
().
convert
(
itemDTO
,
CustomProductItemEntity
.
class
);
item
.
setProductId
(
productId
);
customProductItemDomainService
.
updateById
(
item
);
}
}
// 新增
if
(
change
.
getAddList
()
!=
null
)
{
for
(
var
itemDTO
:
change
.
getAddList
())
{
CustomProductItemEntity
item
=
BeanMapper
.
mapper
().
convert
(
itemDTO
,
CustomProductItemEntity
.
class
);
item
.
setProductId
(
productId
);
customProductItemDomainService
.
save
(
item
);
}
}
}
/**
* 处理工厂价格变更(增/删/改)
*/
private
void
handleFactoryPriceChanges
(
CustomProductInfoUpdateDTO
.
ProductFactoryPriceChangeDTO
change
,
Integer
productId
)
{
if
(
change
.
getRemoveList
()
!=
null
&&
!
change
.
getRemoveList
().
isEmpty
())
{
customProductFactoryPriceRelDomainService
.
removeByIds
(
change
.
getRemoveList
());
}
if
(
change
.
getUpdateList
()
!=
null
)
{
for
(
var
dto
:
change
.
getUpdateList
())
{
CustomProductFactoryPriceRelEntity
rel
=
BeanMapper
.
mapper
().
convert
(
dto
,
CustomProductFactoryPriceRelEntity
.
class
);
rel
.
setProductId
(
productId
);
customProductFactoryPriceRelDomainService
.
updateById
(
rel
);
}
}
if
(
change
.
getAddList
()
!=
null
)
{
for
(
var
dto
:
change
.
getAddList
())
{
CustomProductFactoryPriceRelEntity
rel
=
BeanMapper
.
mapper
().
convert
(
dto
,
CustomProductFactoryPriceRelEntity
.
class
);
rel
.
setProductId
(
productId
);
customProductFactoryPriceRelDomainService
.
save
(
rel
);
}
}
}
/**
* 销毁并重建属性
*/
private
void
rebuildProperties
(
List
<
CustomProductInfoPropertyDTO
>
skuProperties
,
List
<
CustomProductInfoPropertyDTO
>
normalProperties
,
Integer
productId
)
{
// 删除旧属性
customProductInfoPropertyDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductInfoPropertyEntity
>()
.
eq
(
CustomProductInfoPropertyEntity:
:
getInfoId
,
productId
));
// 重建新属性
saveProperties
(
skuProperties
,
normalProperties
,
productId
);
}
/**
* 处理图片变更
*/
private
void
handleImageChanges
(
CustomProductInfoUpdateDTO
.
ProductImageChangeDTO
change
,
Integer
productId
,
Integer
type
)
{
if
(
change
.
getRemoveList
()
!=
null
&&
!
change
.
getRemoveList
().
isEmpty
())
{
customProductImageDomainService
.
removeByIds
(
change
.
getRemoveList
());
}
if
(
change
.
getAddList
()
!=
null
)
{
for
(
var
dto
:
change
.
getAddList
())
{
CustomProductImageEntity
img
=
BeanMapper
.
mapper
().
convert
(
dto
,
CustomProductImageEntity
.
class
);
img
.
setProductId
(
productId
);
img
.
setType
(
type
);
customProductImageDomainService
.
save
(
img
);
}
}
}
/**
* 更新备注(先删后插)
*/
private
void
updateRemarks
(
String
remark
,
String
cnRemark
,
Integer
productId
)
{
// 英文备注
customProductRemarkDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductRemarkEntity
>()
.
eq
(
CustomProductRemarkEntity:
:
getProductId
,
productId
));
if
(
remark
!=
null
&&
!
remark
.
isEmpty
())
{
CustomProductRemarkEntity
r
=
new
CustomProductRemarkEntity
();
r
.
setProductId
(
productId
);
r
.
setRemark
(
remark
);
customProductRemarkDomainService
.
save
(
r
);
}
// 中文备注
customProductCnRemarkDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductCnRemarkEntity
>()
.
eq
(
CustomProductCnRemarkEntity:
:
getProductId
,
productId
));
if
(
cnRemark
!=
null
&&
!
cnRemark
.
isEmpty
())
{
CustomProductCnRemarkEntity
cr
=
new
CustomProductCnRemarkEntity
();
cr
.
setProductId
(
productId
);
cr
.
setRemark
(
cnRemark
);
customProductCnRemarkDomainService
.
save
(
cr
);
}
}
/**
* 重建关联关系(先删后插)
*/
private
void
rebuildRels
(
List
<
Integer
>
factoryIds
,
List
<
Integer
>
warehouseIds
,
List
<
Integer
>
craftIds
,
List
<
Integer
>
diyUserIds
,
List
<
FactoryPriceIntervalRelDTO
>
intervals
,
Integer
productId
)
{
// 产品-工厂关联
productFactoryRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
ProductFactoryRelEntity
>()
.
eq
(
ProductFactoryRelEntity:
:
getProductId
,
productId
));
saveFactoryRels
(
factoryIds
,
productId
);
// 仓库关联
customProductWarehouseRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductWarehouseRelEntity
>()
.
eq
(
CustomProductWarehouseRelEntity:
:
getProductId
,
productId
));
saveWarehouseRels
(
warehouseIds
,
productId
);
// 工艺关联
customProductCraftRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductCraftRelEntity
>()
.
eq
(
CustomProductCraftRelEntity:
:
getProductId
,
productId
));
saveCraftRels
(
craftIds
,
productId
);
// DIY 用户关联
customProductDiyUserRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductDiyUserRelEntity
>()
.
eq
(
CustomProductDiyUserRelEntity:
:
getProductId
,
productId
));
saveDiyUserRels
(
diyUserIds
,
productId
);
// 价格区间关联
customProductFactoryPriceIntervalRelDomainService
.
remove
(
new
LambdaQueryWrapper
<
CustomProductFactoryPriceIntervalRelEntity
>()
.
eq
(
CustomProductFactoryPriceIntervalRelEntity:
:
getProductId
,
productId
));
saveFactoryPriceIntervalRels
(
intervals
,
productId
);
}
// -------- 日志辅助方法 --------
/**
* 事务内记录日志
*/
private
void
saveLogTransaction
(
Integer
productId
,
String
description
)
{
LogCustomProductEntity
logEntry
=
new
LogCustomProductEntity
();
logEntry
.
setProductId
(
productId
);
logEntry
.
setDescription
(
description
);
logEntry
.
setEmployeeId
(-
1
);
logEntry
.
setEmployeeAccount
(
"系统"
);
logCustomProductDomainService
.
save
(
logEntry
);
}
/**
* 批量记录产品日志
*/
private
void
saveLogBatch
(
String
action
,
List
<
Integer
>
productIds
)
{
List
<
LogCustomProductEntity
>
logs
=
new
ArrayList
<>();
for
(
Integer
productId
:
productIds
)
{
LogCustomProductEntity
logEntry
=
new
LogCustomProductEntity
();
logEntry
.
setProductId
(
productId
);
logEntry
.
setDescription
(
action
);
logEntry
.
setEmployeeId
(-
1
);
logEntry
.
setEmployeeAccount
(
"系统"
);
logs
.
add
(
logEntry
);
}
logCustomProductDomainService
.
saveBatch
(
logs
);
}
/**
* 取消所有 CompletableFuture(超时或异常时调用)
*/
private
void
cancelAll
(
CompletableFuture
<?>...
futures
)
{
for
(
CompletableFuture
<?>
f
:
futures
)
{
if
(
f
!=
null
&&
!
f
.
isDone
())
{
f
.
cancel
(
true
);
}
}
}
// -------- getByIdOrSku 辅助方法 --------
/**
* 将并行查询结果组装为 FullVO
*/
private
CustomProductInfoSnakeVO
buildProductFullVO
(
CustomProductInfoEntity
entity
,
List
<
CustomProductItemEntity
>
items
,
List
<
CustomProductImageEntity
>
images
,
List
<
CustomProductFactoryPriceRelEntity
>
factoryPrices
,
List
<
Integer
>
diyUserIds
,
List
<
Long
>
craftIds
,
List
<
Integer
>
warehouseIds
,
CustomProductRemarkEntity
remark
,
CustomProductCnRemarkEntity
cnRemark
,
List
<
Integer
>
factoryIds
)
{
CustomProductInfoSnakeVO
fullVO
=
BeanMapper
.
snakeCase
().
convert
(
entity
,
CustomProductInfoSnakeVO
.
class
);
// 子项(对齐 TS:209-214 — 同步主表的 print_type 到每个子项)
fullVO
.
setProductList
(
items
.
stream
()
.
map
(
e
->
{
CustomProductItemSnakeVO
vo
=
BeanMapper
.
snakeCase
().
convert
(
e
,
CustomProductItemSnakeVO
.
class
);
// 同步主表 printType 到子项(对齐 TS:212)
vo
.
setPrint_type
(
entity
.
getPrintType
());
return
vo
;
})
.
collect
(
Collectors
.
toList
()));
// 图片拆分:按类型分为普通图和尺码图(对齐 TS:205-206)
fullVO
.
setColorImageList
(
Arrays
.
asList
(
entity
.
getColorImages
().
split
(
","
)));
fullVO
.
setImageList
(
images
.
stream
()
.
filter
(
img
->
img
.
getType
()
==
null
||
img
.
getType
()
==
IMAGE_TYPE_NORMAL
)
.
map
(
img
->
BeanMapper
.
snakeCase
().
convert
(
img
,
CustomProductImageSnakeVO
.
class
))
.
collect
(
Collectors
.
toList
()));
fullVO
.
setSizeList
(
images
.
stream
()
.
filter
(
img
->
img
.
getType
()
!=
null
&&
img
.
getType
()
==
IMAGE_TYPE_SIZE
)
.
map
(
img
->
BeanMapper
.
snakeCase
().
convert
(
img
,
CustomProductImageSnakeVO
.
class
))
.
collect
(
Collectors
.
toList
()));
// 工厂价格
fullVO
.
setFactoryPriceList
(
factoryPrices
.
stream
()
.
map
(
e
->
BeanMapper
.
mapper
().
convert
(
e
,
CustomProductFactoryPriceRelVO
.
class
))
.
collect
(
Collectors
.
toList
()));
// 关联 ID 列表
fullVO
.
setDiyUserIds
(
diyUserIds
);
fullVO
.
setCraftIds
(
craftIds
.
stream
().
map
(
String:
:
valueOf
).
collect
(
Collectors
.
toList
()));
fullVO
.
setWarehouseIds
(
warehouseIds
);
// 工厂关联 ID 列表(对齐 TS:238)
fullVO
.
setFactoryIds
(
factoryIds
);
// 备注
fullVO
.
setProductCnRemark
(
BeanMapper
.
snakeCase
().
convert
(
cnRemark
,
ProductRemarkVO
.
class
));
fullVO
.
setProductRemark
(
BeanMapper
.
snakeCase
().
convert
(
remark
,
ProductRemarkVO
.
class
));
fullVO
.
setRemark
(
remark
.
getRemark
());
fullVO
.
setCnRemark
(
cnRemark
.
getRemark
());
return
fullVO
;
}
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/CustomProductItemServiceImpl.java
View file @
7b931415
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.exception.ServiceException
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemVO
;
import
com.jomalls.custom.app.vo.CustomProductItem
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductItemService
;
import
com.jomalls.custom.app.service.CustomProductItemService
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.BeanMapper
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
import
com.jomalls.custom.app.utils.CustomAsserts
;
...
@@ -37,34 +37,34 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
...
@@ -37,34 +37,34 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
}
}
@Override
@Override
public
List
<
CustomProductItem
VO
>
list
(
CustomProductItemVO
customProductItem
VO
)
{
public
List
<
CustomProductItem
SnakeVO
>
list
(
CustomProductItemSnakeVO
customProductItemSnake
VO
)
{
QueryWrapper
<
CustomProductItemEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductItemEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
List
<
CustomProductItemEntity
>
list
=
customProductItemDomainService
.
list
(
queryWrapper
);
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
,
CustomProductItem
Snake
VO
.
class
)).
collect
(
Collectors
.
toList
());
}
}
@Override
@Override
public
IPage
<
CustomProductItemVO
>
pageList
(
CustomProductItemPageVO
customProductItemPageVO
)
{
public
IPage
<
CustomProductItem
Snake
VO
>
pageList
(
CustomProductItemPageVO
customProductItemPageVO
)
{
CustomAsserts
.
nonNull
(
customProductItemPageVO
,
"分页查询参数不能为空"
);
CustomAsserts
.
nonNull
(
customProductItemPageVO
,
"分页查询参数不能为空"
);
QueryWrapper
<
CustomProductItemEntity
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
CustomProductItemEntity
>
queryWrapper
=
new
QueryWrapper
<>();
// TODO 根据业务条件组装入参
// TODO 根据业务条件组装入参
IPage
<
CustomProductItemEntity
>
page
=
customProductItemDomainService
.
selectPage
(
queryWrapper
,
customProductItemPageVO
);
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
,
CustomProductItem
Snake
VO
.
class
));
}
}
@Override
@Override
public
CustomProductItemVO
info
(
Integer
id
)
{
public
CustomProductItem
Snake
VO
info
(
Integer
id
)
{
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomAsserts
.
nonNull
(
id
,
"主键id不能为空"
);
CustomProductItemEntity
customProductItem
=
customProductItemDomainService
.
getById
(
id
);
CustomProductItemEntity
customProductItem
=
customProductItemDomainService
.
getById
(
id
);
return
BeanMapper
.
mapper
().
convert
(
customProductItem
,
CustomProductItemVO
.
class
);
return
BeanMapper
.
mapper
().
convert
(
customProductItem
,
CustomProductItem
Snake
VO
.
class
);
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
save
(
CustomProductItem
VO
customProductItem
VO
)
{
public
void
save
(
CustomProductItem
SnakeVO
customProductItemSnake
VO
)
{
CustomAsserts
.
nonNull
(
customProductItemVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductItem
Snake
VO
,
"实体对象不能为空"
);
CustomProductItemEntity
customProductItemEntity
=
BeanMapper
.
mapper
().
convert
(
customProductItemVO
,
CustomProductItemEntity
.
class
);
CustomProductItemEntity
customProductItemEntity
=
BeanMapper
.
mapper
().
convert
(
customProductItem
Snake
VO
,
CustomProductItemEntity
.
class
);
try
{
try
{
customProductItemDomainService
.
save
(
customProductItemEntity
);
customProductItemDomainService
.
save
(
customProductItemEntity
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
@@ -75,9 +75,9 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
...
@@ -75,9 +75,9 @@ public class CustomProductItemServiceImpl implements CustomProductItemService {
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
@Override
public
void
updateById
(
CustomProductItem
VO
customProductItem
VO
)
{
public
void
updateById
(
CustomProductItem
SnakeVO
customProductItemSnake
VO
)
{
CustomAsserts
.
nonNull
(
customProductItemVO
,
"实体对象不能为空"
);
CustomAsserts
.
nonNull
(
customProductItem
Snake
VO
,
"实体对象不能为空"
);
CustomProductItemEntity
customProductItem
=
BeanMapper
.
mapper
().
convert
(
customProductItemVO
,
CustomProductItemEntity
.
class
);
CustomProductItemEntity
customProductItem
=
BeanMapper
.
mapper
().
convert
(
customProductItem
Snake
VO
,
CustomProductItemEntity
.
class
);
try
{
try
{
customProductItemDomainService
.
updateById
(
customProductItem
);
customProductItemDomainService
.
updateById
(
customProductItem
);
}
catch
(
DuplicateKeyException
e
)
{
}
catch
(
DuplicateKeyException
e
)
{
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/DiyUserServiceImpl.java
0 → 100644
View file @
7b931415
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
));
}
}
}
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/ProductFactoryRelServiceImpl.java
0 → 100644
View file @
7b931415
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
);
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/utils/BeanMapper.java
View file @
7b931415
...
@@ -2,6 +2,7 @@ package com.jomalls.custom.app.utils;
...
@@ -2,6 +2,7 @@ package com.jomalls.custom.app.utils;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.PropertyNamingStrategies
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
;
import
com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
;
...
@@ -25,10 +26,18 @@ import java.util.List;
...
@@ -25,10 +26,18 @@ import java.util.List;
public
class
BeanMapper
{
public
class
BeanMapper
{
/**
/**
* Jackson ObjectMapper配置
* Jackson ObjectMapper配置
(默认驼峰命名)
*/
*/
private
static
final
ObjectMapper
OBJECT_MAPPER
=
new
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
{
static
{
// 注册Java 8时间模块,支持LocalDate, LocalDateTime等
// 注册Java 8时间模块,支持LocalDate, LocalDateTime等
OBJECT_MAPPER
.
registerModule
(
new
JavaTimeModule
());
OBJECT_MAPPER
.
registerModule
(
new
JavaTimeModule
());
...
@@ -40,16 +49,44 @@ public class BeanMapper {
...
@@ -40,16 +49,44 @@ public class BeanMapper {
OBJECT_MAPPER
.
disable
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
);
OBJECT_MAPPER
.
disable
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
);
// 允许单值包装数组
// 允许单值包装数组
OBJECT_MAPPER
.
enable
(
DeserializationFeature
.
ACCEPT_SINGLE_VALUE_AS_ARRAY
);
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
()
{
private
BeanMapper
()
{
this
.
objectMapper
=
OBJECT_MAPPER
;
}
private
BeanMapper
(
ObjectMapper
objectMapper
)
{
this
.
objectMapper
=
objectMapper
;
}
}
private
final
ObjectMapper
objectMapper
;
public
static
BeanMapper
mapper
()
{
public
static
BeanMapper
mapper
()
{
return
new
BeanMapper
();
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 {
...
@@ -64,7 +101,7 @@ public class BeanMapper {
return
null
;
return
null
;
}
}
try
{
try
{
return
OBJECT_MAPPER
.
convertValue
(
source
,
destinationClass
);
return
this
.
objectMapper
.
convertValue
(
source
,
destinationClass
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"BeanMapper convert failed: "
+
throw
new
RuntimeException
(
"BeanMapper convert failed: "
+
"source="
+
source
.
getClass
().
getName
()
+
"source="
+
source
.
getClass
().
getName
()
+
...
@@ -88,7 +125,7 @@ public class BeanMapper {
...
@@ -88,7 +125,7 @@ public class BeanMapper {
try
{
try
{
List
<
D
>
result
=
new
ArrayList
<>(
sourceList
.
size
());
List
<
D
>
result
=
new
ArrayList
<>(
sourceList
.
size
());
for
(
S
source
:
sourceList
)
{
for
(
S
source
:
sourceList
)
{
result
.
add
(
OBJECT_MAPPER
.
convertValue
(
source
,
destinationClass
));
result
.
add
(
this
.
objectMapper
.
convertValue
(
source
,
destinationClass
));
}
}
return
result
;
return
result
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -110,7 +147,7 @@ public class BeanMapper {
...
@@ -110,7 +147,7 @@ public class BeanMapper {
return
null
;
return
null
;
}
}
try
{
try
{
return
(
T
)
OBJECT_MAPPER
.
convertValue
(
source
,
source
.
getClass
());
return
(
T
)
this
.
objectMapper
.
convertValue
(
source
,
source
.
getClass
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"BeanMapper copy failed: "
+
throw
new
RuntimeException
(
"BeanMapper copy failed: "
+
"source="
+
source
.
getClass
().
getName
(),
e
);
"source="
+
source
.
getClass
().
getName
(),
e
);
...
...
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductImageVO.java
→
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductImage
Snake
VO.java
View file @
7b931415
...
@@ -21,7 +21,7 @@ import java.util.Date;
...
@@ -21,7 +21,7 @@ import java.util.Date;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"VO"
)
@Schema
(
description
=
"VO"
)
public
class
CustomProductImageVO
implements
Serializable
{
public
class
CustomProductImage
Snake
VO
implements
Serializable
{
@Serial
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
...
@@ -35,13 +35,13 @@ public class CustomProductImageVO implements Serializable {
...
@@ -35,13 +35,13 @@ public class CustomProductImageVO implements Serializable {
* 商品ID
* 商品ID
*/
*/
@Schema
(
description
=
"商品ID"
)
@Schema
(
description
=
"商品ID"
)
private
Integer
product
I
d
;
private
Integer
product
_i
d
;
/**
/**
* 图片地址
* 图片地址
*/
*/
@Schema
(
description
=
"图片地址"
)
@Schema
(
description
=
"图片地址"
)
private
String
image
U
rl
;
private
String
image
_u
rl
;
/**
/**
* 排序
* 排序
...
@@ -59,7 +59,7 @@ public class CustomProductImageVO implements Serializable {
...
@@ -59,7 +59,7 @@ public class CustomProductImageVO implements Serializable {
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Date
create
T
ime
;
private
Date
create
_t
ime
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoPropertyVO.java
→
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoProperty
Snake
VO.java
View file @
7b931415
...
@@ -20,7 +20,7 @@ import java.io.Serializable;
...
@@ -20,7 +20,7 @@ import java.io.Serializable;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"VO"
)
@Schema
(
description
=
"VO"
)
public
class
CustomProductInfoPropertyVO
implements
Serializable
{
public
class
CustomProductInfoProperty
Snake
VO
implements
Serializable
{
@Serial
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
...
@@ -34,25 +34,24 @@ public class CustomProductInfoPropertyVO implements Serializable {
...
@@ -34,25 +34,24 @@ public class CustomProductInfoPropertyVO implements Serializable {
* custom_product_info表id
* custom_product_info表id
*/
*/
@Schema
(
description
=
"custom_product_info表id"
)
@Schema
(
description
=
"custom_product_info表id"
)
private
Integer
info
I
d
;
private
Integer
info
_i
d
;
/**
/**
* 属性类ID
* 属性类ID
*/
*/
@Schema
(
description
=
"属性类ID"
)
@Schema
(
description
=
"属性类ID"
)
private
Integer
property
I
d
;
private
Integer
property
_i
d
;
/**
/**
* 属性值ID
* 属性值ID
*/
*/
@Schema
(
description
=
"属性值ID"
)
@Schema
(
description
=
"属性值ID"
)
private
Integer
value
I
d
;
private
Integer
value
_i
d
;
/**
/**
* 是否为SKU属性
* 是否为SKU属性
*/
*/
@Schema
(
description
=
"是否为SKU属性"
)
@Schema
(
description
=
"是否为SKU属性"
)
private
Boolean
skuProperty
;
private
Boolean
skuProperty
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoSkuPropertiesVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductInfoSnakeVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductItemVO.java
→
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductItem
Snake
VO.java
View file @
7b931415
...
@@ -22,7 +22,7 @@ import java.util.Date;
...
@@ -22,7 +22,7 @@ import java.util.Date;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"VO"
)
@Schema
(
description
=
"VO"
)
public
class
CustomProductItemVO
implements
Serializable
{
public
class
CustomProductItem
Snake
VO
implements
Serializable
{
@Serial
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
...
@@ -36,7 +36,7 @@ public class CustomProductItemVO implements Serializable {
...
@@ -36,7 +36,7 @@ public class CustomProductItemVO implements Serializable {
* 商品ID
* 商品ID
*/
*/
@Schema
(
description
=
"商品ID"
)
@Schema
(
description
=
"商品ID"
)
private
Integer
product
I
d
;
private
Integer
product
_i
d
;
/**
/**
* sku
* sku
...
@@ -48,7 +48,13 @@ public class CustomProductItemVO implements Serializable {
...
@@ -48,7 +48,13 @@ public class CustomProductItemVO implements Serializable {
* sku商品名称
* sku商品名称
*/
*/
@Schema
(
description
=
"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 {
...
@@ -60,151 +66,138 @@ public class CustomProductItemVO implements Serializable {
* 图片集
* 图片集
*/
*/
@Schema
(
description
=
"图片集"
)
@Schema
(
description
=
"图片集"
)
private
String
image
A
ry
;
private
String
image
_a
ry
;
/**
/**
* 属性分类ID1
* 属性分类ID1
*/
*/
@Schema
(
description
=
"属性分类ID1"
)
@Schema
(
description
=
"属性分类ID1"
)
private
Integer
property
CateI
d1
;
private
Integer
property
_cate_i
d1
;
/**
/**
* 属性分类ID2
* 属性分类ID2
*/
*/
@Schema
(
description
=
"属性分类ID2"
)
@Schema
(
description
=
"属性分类ID2"
)
private
Integer
property
CateI
d2
;
private
Integer
property
_cate_i
d2
;
/**
/**
* 属性分类ID3
* 属性分类ID3
*/
*/
@Schema
(
description
=
"属性分类ID3"
)
@Schema
(
description
=
"属性分类ID3"
)
private
Integer
property
CateI
d3
;
private
Integer
property
_cate_i
d3
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
property1
I
d
;
private
Integer
property1
_i
d
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
property2
I
d
;
private
Integer
property2
_i
d
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
Integer
property3
I
d
;
private
Integer
property3
_i
d
;
/**
/**
* 属性编码1
* 属性编码1
*/
*/
@Schema
(
description
=
"属性编码1"
)
@Schema
(
description
=
"属性编码1"
)
private
String
property
C
ode1
;
private
String
property
_c
ode1
;
/**
/**
* 属性编码2
* 属性编码2
*/
*/
@Schema
(
description
=
"属性编码2"
)
@Schema
(
description
=
"属性编码2"
)
private
String
property
C
ode2
;
private
String
property
_c
ode2
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
property
C
ode3
;
private
String
property
_c
ode3
;
/**
/**
* 属性名称1
* 属性名称1
*/
*/
@Schema
(
description
=
"属性名称1"
)
@Schema
(
description
=
"属性名称1"
)
private
String
option
E
nname1
;
private
String
option
_e
nname1
;
/**
/**
* 属性名称2
* 属性名称2
*/
*/
@Schema
(
description
=
"属性名称2"
)
@Schema
(
description
=
"属性名称2"
)
private
String
option
E
nname2
;
private
String
option
_e
nname2
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
option
E
nname3
;
private
String
option
_e
nname3
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
custom
V
alue1
;
private
String
custom
_v
alue1
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
custom
V
alue2
;
private
String
custom
_v
alue2
;
/**
/**
*
*
*/
*/
@Schema
(
description
=
""
)
@Schema
(
description
=
""
)
private
String
custom
V
alue3
;
private
String
custom
_v
alue3
;
/**
/**
* 工厂价
* 工厂价
*/
*/
@Schema
(
description
=
"工厂价"
)
@Schema
(
description
=
"工厂价"
)
private
BigDecimal
factory
P
rice
;
private
BigDecimal
factory
_p
rice
;
/**
/**
* 销售价
* 销售价
*/
*/
@Schema
(
description
=
"销售价"
)
@Schema
(
description
=
"销售价"
)
private
BigDecimal
sales
P
rice
;
private
BigDecimal
sales
_p
rice
;
/**
/**
* sku克重
* sku克重
*/
*/
@Schema
(
description
=
"sku克重"
)
@Schema
(
description
=
"sku克重"
)
private
BigDecimal
sku
W
eight
;
private
BigDecimal
sku
_w
eight
;
/**
/**
* 印花类型 0满印 1局部印
* 印花类型 0满印 1局部印
*/
*/
@Schema
(
description
=
"印花类型 0满印 1局部印"
)
@Schema
(
description
=
"印花类型 0满印 1局部印"
)
private
Integer
printType
;
private
Integer
print_type
;
/**
* 排序
*/
@Schema
(
description
=
"排序"
)
private
Integer
sort
;
/**
* 货号
*/
@Schema
(
description
=
"货号"
)
private
String
productNo
;
/**
/**
* 1正常码 2大码
* 1正常码 2大码
*/
*/
@Schema
(
description
=
"1正常码 2大码"
)
@Schema
(
description
=
"1正常码 2大码"
)
private
Integer
size
T
ype
;
private
Integer
size
_t
ype
;
/**
/**
*
创建时间
*
排序
*/
*/
@Schema
(
description
=
"
创建时间
"
)
@Schema
(
description
=
"
排序
"
)
private
Date
createTime
;
private
Integer
sort
;
/**
/**
*
更新
时间
*
创建
时间
*/
*/
@Schema
(
description
=
"
更新
时间"
)
@Schema
(
description
=
"
创建
时间"
)
private
Date
updateT
ime
;
private
Date
create_t
ime
;
}
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/CustomProductPropertiesValueVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductFactoryRelPageVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductFactoryRelVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-app/src/main/java/com/jomalls/custom/app/vo/ProductRemarkVO.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/DbDiyUserEntity.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/DbDiyXiaoguotuEntity.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/ProductFactoryRelEntity.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/entity/ProductTemplateInfoEntity.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/CustomProductInfoMapper.java
View file @
7b931415
...
@@ -3,6 +3,7 @@ package com.jomalls.custom.dal.mapper;
...
@@ -3,6 +3,7 @@ package com.jomalls.custom.dal.mapper;
import
com.jomalls.custom.dal.entity.CustomProductInfoEntity
;
import
com.jomalls.custom.dal.entity.CustomProductInfoEntity
;
import
com.jomalls.custom.mapper.BaseMapper
;
import
com.jomalls.custom.mapper.BaseMapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
/**
/**
* @author Lizh
* @author Lizh
...
@@ -12,4 +13,12 @@ import org.apache.ibatis.annotations.Mapper;
...
@@ -12,4 +13,12 @@ import org.apache.ibatis.annotations.Mapper;
*/
*/
@Mapper
@Mapper
public
interface
CustomProductInfoMapper
extends
BaseMapper
<
CustomProductInfoEntity
>
{
public
interface
CustomProductInfoMapper
extends
BaseMapper
<
CustomProductInfoEntity
>
{
/**
* 根据 SKU 查询商品
*
* @param sku 商品 SKU
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity
selectBySku
(
@Param
(
"sku"
)
String
sku
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/CustomProductWarehouseRelMapper.java
View file @
7b931415
...
@@ -3,6 +3,9 @@ package com.jomalls.custom.dal.mapper;
...
@@ -3,6 +3,9 @@ package com.jomalls.custom.dal.mapper;
import
com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity
;
import
com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity
;
import
com.jomalls.custom.mapper.BaseMapper
;
import
com.jomalls.custom.mapper.BaseMapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
/**
/**
* @author Lizh
* @author Lizh
...
@@ -12,4 +15,9 @@ import org.apache.ibatis.annotations.Mapper;
...
@@ -12,4 +15,9 @@ import org.apache.ibatis.annotations.Mapper;
*/
*/
@Mapper
@Mapper
public
interface
CustomProductWarehouseRelMapper
extends
BaseMapper
<
CustomProductWarehouseRelEntity
>
{
public
interface
CustomProductWarehouseRelMapper
extends
BaseMapper
<
CustomProductWarehouseRelEntity
>
{
/**
* 根据仓库 ID 列表查询关联关系
*/
List
<
CustomProductWarehouseRelEntity
>
selectByWarehouseIds
(
@Param
(
"warehouseIds"
)
List
<
Integer
>
warehouseIds
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/DbDiyUserMapper.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/DbDiyXiaoguotuMapper.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/ProductFactoryRelMapper.java
0 → 100644
View file @
7b931415
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
>
{
}
custom-server-domain/src/main/java/com/jomalls/custom/dal/mapper/ProductTemplateInfoMapper.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/CustomProductInfoDomainService.java
View file @
7b931415
...
@@ -11,5 +11,12 @@ import com.jomalls.custom.service.IBaseService;
...
@@ -11,5 +11,12 @@ import com.jomalls.custom.service.IBaseService;
*/
*/
public
interface
CustomProductInfoDomainService
extends
IBaseService
<
CustomProductInfoEntity
>
{
public
interface
CustomProductInfoDomainService
extends
IBaseService
<
CustomProductInfoEntity
>
{
/**
* 根据 SKU 查询商品
*
* @param sku 商品 SKU
* @return 商品实体,未找到返回 null
*/
CustomProductInfoEntity
getBySku
(
String
sku
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/CustomProductWarehouseRelDomainService.java
View file @
7b931415
...
@@ -3,6 +3,8 @@ package com.jomalls.custom.domain.service;
...
@@ -3,6 +3,8 @@ package com.jomalls.custom.domain.service;
import
com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity
;
import
com.jomalls.custom.dal.entity.CustomProductWarehouseRelEntity
;
import
com.jomalls.custom.service.IBaseService
;
import
com.jomalls.custom.service.IBaseService
;
import
java.util.List
;
/**
/**
* @author Lizh
* @author Lizh
* @version 0.01
* @version 0.01
...
@@ -11,5 +13,8 @@ import com.jomalls.custom.service.IBaseService;
...
@@ -11,5 +13,8 @@ import com.jomalls.custom.service.IBaseService;
*/
*/
public
interface
CustomProductWarehouseRelDomainService
extends
IBaseService
<
CustomProductWarehouseRelEntity
>
{
public
interface
CustomProductWarehouseRelDomainService
extends
IBaseService
<
CustomProductWarehouseRelEntity
>
{
/**
* 根据仓库 ID 列表查询关联
*/
List
<
CustomProductWarehouseRelEntity
>
selectByWarehouseIds
(
List
<
Integer
>
warehouseIds
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/DbDiyUserDomainService.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/DbDiyXiaoguotuDomainService.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/ProductFactoryRelDomainService.java
0 → 100644
View file @
7b931415
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
>
{
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/ProductTemplateInfoDomainService.java
0 → 100644
View file @
7b931415
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
);
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/CustomProductInfoDomainServiceImpl.java
View file @
7b931415
...
@@ -4,6 +4,7 @@ import com.jomalls.custom.dal.mapper.CustomProductInfoMapper;
...
@@ -4,6 +4,7 @@ import com.jomalls.custom.dal.mapper.CustomProductInfoMapper;
import
com.jomalls.custom.dal.entity.CustomProductInfoEntity
;
import
com.jomalls.custom.dal.entity.CustomProductInfoEntity
;
import
com.jomalls.custom.domain.service.CustomProductInfoDomainService
;
import
com.jomalls.custom.domain.service.CustomProductInfoDomainService
;
import
com.jomalls.custom.service.impl.BaseServiceImpl
;
import
com.jomalls.custom.service.impl.BaseServiceImpl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -22,6 +23,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr
...
@@ -22,6 +23,9 @@ public class CustomProductInfoDomainServiceImpl extends BaseServiceImpl<CustomPr
public
CustomProductInfoDomainServiceImpl
(
SqlSessionFactory
sqlSessionFactory
)
{
public
CustomProductInfoDomainServiceImpl
(
SqlSessionFactory
sqlSessionFactory
)
{
super
(
sqlSessionFactory
);
super
(
sqlSessionFactory
);
}
}
// 自定义方法或者基础方法重写
@Override
public
CustomProductInfoEntity
getBySku
(
String
sku
)
{
return
baseMapper
.
selectBySku
(
sku
);
}
}
}
\ No newline at end of file
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/CustomProductWarehouseRelDomainServiceImpl.java
View file @
7b931415
...
@@ -8,6 +8,8 @@ import org.apache.ibatis.session.SqlSessionFactory;
...
@@ -8,6 +8,8 @@ import org.apache.ibatis.session.SqlSessionFactory;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
/**
/**
* @author Lizh
* @author Lizh
...
@@ -22,6 +24,8 @@ public class CustomProductWarehouseRelDomainServiceImpl extends BaseServiceImpl<
...
@@ -22,6 +24,8 @@ public class CustomProductWarehouseRelDomainServiceImpl extends BaseServiceImpl<
public
CustomProductWarehouseRelDomainServiceImpl
(
SqlSessionFactory
sqlSessionFactory
)
{
public
CustomProductWarehouseRelDomainServiceImpl
(
SqlSessionFactory
sqlSessionFactory
)
{
super
(
sqlSessionFactory
);
super
(
sqlSessionFactory
);
}
}
// 自定义方法或者基础方法重写
@Override
public
List
<
CustomProductWarehouseRelEntity
>
selectByWarehouseIds
(
List
<
Integer
>
warehouseIds
)
{
return
baseMapper
.
selectByWarehouseIds
(
warehouseIds
);
}
}
}
\ No newline at end of file
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/DbDiyUserDomainServiceImpl.java
0 → 100644
View file @
7b931415
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
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/DbDiyXiaoguotuDomainServiceImpl.java
0 → 100644
View file @
7b931415
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
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/ProductFactoryRelDomainServiceImpl.java
0 → 100644
View file @
7b931415
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
);
}
}
custom-server-domain/src/main/java/com/jomalls/custom/domain/service/impl/ProductTemplateInfoDomainServiceImpl.java
0 → 100644
View file @
7b931415
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
);
}
}
custom-server-domain/src/main/resources/mapper/CustomProductBlacklistMapper.xml
View file @
7b931415
...
@@ -15,4 +15,12 @@
...
@@ -15,4 +15,12 @@
product_id,
product_id,
diy_user_id
diy_user_id
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductCnRemarkMapper.xml
View file @
7b931415
...
@@ -17,4 +17,12 @@
...
@@ -17,4 +17,12 @@
remark,
remark,
create_time
create_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductCraftRelMapper.xml
View file @
7b931415
...
@@ -15,4 +15,12 @@
...
@@ -15,4 +15,12 @@
product_id,
product_id,
craft_id
craft_id
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductDiyUserRelMapper.xml
View file @
7b931415
...
@@ -15,4 +15,12 @@
...
@@ -15,4 +15,12 @@
product_id,
product_id,
diy_user_id
diy_user_id
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductFactoryPriceIntervalRelMapper.xml
View file @
7b931415
...
@@ -19,4 +19,12 @@
...
@@ -19,4 +19,12 @@
price_max,
price_max,
price_min
price_min
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductFactoryPriceRelMapper.xml
View file @
7b931415
...
@@ -31,4 +31,12 @@
...
@@ -31,4 +31,12 @@
create_time,
create_time,
update_time
update_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductImageMapper.xml
View file @
7b931415
...
@@ -21,4 +21,12 @@
...
@@ -21,4 +21,12 @@
type,
type,
create_time
create_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductInfoMapper.xml
View file @
7b931415
...
@@ -81,4 +81,20 @@
...
@@ -81,4 +81,20 @@
diy_id,
diy_id,
diy_sku
diy_sku
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductInfoPropertyMapper.xml
View file @
7b931415
...
@@ -19,4 +19,12 @@
...
@@ -19,4 +19,12 @@
value_id,
value_id,
sku_property
sku_property
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductItemMapper.xml
View file @
7b931415
...
@@ -69,4 +69,12 @@
...
@@ -69,4 +69,12 @@
create_time,
create_time,
update_time
update_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductRemarkMapper.xml
View file @
7b931415
...
@@ -17,4 +17,12 @@
...
@@ -17,4 +17,12 @@
remark,
remark,
create_time
create_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomProductWarehouseRelMapper.xml
View file @
7b931415
...
@@ -15,4 +15,22 @@
...
@@ -15,4 +15,22 @@
product_id,
product_id,
warehouse_id
warehouse_id
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/CustomWarehouseInfoMapper.xml
View file @
7b931415
...
@@ -79,4 +79,12 @@
...
@@ -79,4 +79,12 @@
settlement_currency,
settlement_currency,
company_name_cn
company_name_cn
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/DbDiyMapper.xml
View file @
7b931415
...
@@ -107,4 +107,12 @@
...
@@ -107,4 +107,12 @@
new_standard,
new_standard,
diy_remark
diy_remark
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/DbDiyUserMapper.xml
0 → 100644
View file @
7b931415
<?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>
custom-server-domain/src/main/resources/mapper/DbDiyXiaoguotuMapper.xml
0 → 100644
View file @
7b931415
<?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>
custom-server-domain/src/main/resources/mapper/LogCustomProductMapper.xml
View file @
7b931415
...
@@ -21,4 +21,12 @@
...
@@ -21,4 +21,12 @@
description,
description,
create_time
create_time
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/ProductFactoryRelMapper.xml
0 → 100644
View file @
7b931415
<?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>
custom-server-domain/src/main/resources/mapper/ProductTemplateInfoMapper.xml
0 → 100644
View file @
7b931415
<?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>
custom-server-domain/src/main/resources/mapper/SysBillRuleMapper.xml
View file @
7b931415
...
@@ -38,4 +38,12 @@
...
@@ -38,4 +38,12 @@
FOR UPDATE
FOR UPDATE
</select>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysMenuMapper.xml
View file @
7b931415
...
@@ -62,4 +62,12 @@
...
@@ -62,4 +62,12 @@
AND m.perms IS NOT NULL
AND m.perms IS NOT NULL
AND m.perms != ''
AND m.perms != ''
</select>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysRoleDeptMapper.xml
View file @
7b931415
...
@@ -13,4 +13,12 @@
...
@@ -13,4 +13,12 @@
role_id,
role_id,
dept_id,
dept_id,
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysRoleMapper.xml
View file @
7b931415
...
@@ -45,4 +45,12 @@
...
@@ -45,4 +45,12 @@
LEFT JOIN sys_role r ON ur.role_id = r.role_id
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'
WHERE ur.user_id = #{userId} AND r.del_flag = '0' AND r.status = '0'
</select>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysRoleMenuMapper.xml
View file @
7b931415
...
@@ -13,4 +13,12 @@
...
@@ -13,4 +13,12 @@
role_id,
role_id,
menu_id,
menu_id,
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysUserMapper.xml
View file @
7b931415
...
@@ -48,4 +48,13 @@
...
@@ -48,4 +48,13 @@
ORDER BY created_at DESC
ORDER BY created_at DESC
</select>
</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>
</mapper>
\ No newline at end of file
custom-server-domain/src/main/resources/mapper/SysUserOldMapper.xml
View file @
7b931415
...
@@ -23,4 +23,12 @@
...
@@ -23,4 +23,12 @@
remark,
remark,
create_time,
create_time,
</sql>
</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>
</mapper>
custom-server-domain/src/main/resources/mapper/SysUserRoleMapper.xml
View file @
7b931415
...
@@ -13,4 +13,12 @@
...
@@ -13,4 +13,12 @@
user_id,
user_id,
role_id,
role_id,
</sql>
</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>
</mapper>
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BaseCategoryInfo
VO
.java
→
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BaseCategoryInfo
Model
.java
View file @
7b931415
...
@@ -6,6 +6,7 @@ import lombok.Builder;
...
@@ -6,6 +6,7 @@ import lombok.Builder;
import
lombok.Data
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.NoArgsConstructor
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.Date
;
import
java.util.Date
;
...
@@ -19,8 +20,9 @@ import java.util.Date;
...
@@ -19,8 +20,9 @@ import java.util.Date;
@NoArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@AllArgsConstructor
@Schema
(
description
=
"商品分类"
)
@Schema
(
description
=
"商品分类"
)
public
class
BaseCategoryInfo
VO
implements
Serializable
{
public
class
BaseCategoryInfo
Model
implements
Serializable
{
@Serial
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
private
Integer
id
;
private
Integer
id
;
...
...
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BasePropertyModel.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/BasePropertyValueModel.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/model/SaasAdminApiResponseModel.java
0 → 100644
View file @
7b931415
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
;
}
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/service/BaseCategoryInfoService.java
deleted
100644 → 0
View file @
627d26f8
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
;
}
}
custom-server-integrate/src/main/java/com/jomalls/custom/integrate/service/SaasAdminService.java
0 → 100644
View file @
7b931415
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
();
}
}
custom-server-starter/src/main/java/com/jomalls/custom/config/RedisConfig.java
View file @
7b931415
...
@@ -6,6 +6,7 @@ import org.redisson.config.Config;
...
@@ -6,6 +6,7 @@ import org.redisson.config.Config;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
...
@@ -23,20 +24,83 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
...
@@ -23,20 +24,83 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
*/
*/
@Configuration
@Configuration
public
class
RedisConfig
{
public
class
RedisConfig
{
/**
* Redis 地址配置
*/
@Value
(
"${spring.data.redis.host:localhost}"
)
@Value
(
"${spring.data.redis.host:localhost}"
)
private
String
host
;
private
String
host
;
/**
* Redis 端口
*/
@Value
(
"${spring.data.redis.port:6379}"
)
@Value
(
"${spring.data.redis.port:6379}"
)
private
int
port
;
private
int
port
;
/**
* Redis 密码
*/
@Value
(
"${spring.data.redis.password:}"
)
@Value
(
"${spring.data.redis.password:}"
)
private
String
password
;
private
String
password
;
/**
* Redis 数据库索引
*/
@Value
(
"${spring.data.redis.database:0}"
)
@Value
(
"${spring.data.redis.database:0}"
)
private
int
database
;
private
int
database
;
// ==================== RedisTemplate ====================
/**
* Redis 连接超时时间
*/
@Value
(
"${spring.data.redis.connect-timeout:3000}"
)
private
int
connectTimeout
;
/**
* Redis 读取超时
*/
@Value
(
"${spring.data.redis.timeout:3000}"
)
private
int
timeout
;
/**
* Redis 连接池最大连接数
*/
@Value
(
"${spring.data.redis.pool.max-active:8}"
)
private
int
maxActive
;
/**
* Redis 连接池最大空闲连接数
*/
@Value
(
"${spring.data.redis.pool.max-idle:4}"
)
private
int
maxIdle
;
/**
* Redis 连接池最小空闲连接数
*/
@Value
(
"${spring.data.redis.pool.min-idle:2}"
)
private
int
minIdle
;
/**
* Redisson 重试次数
*/
@Value
(
"${spring.data.redis.redisson.retry-attempts:3}"
)
private
int
retryAttempts
;
/**
* Redisson 重试间隔(毫秒)
*/
@Value
(
"${spring.data.redis.redisson.retry-interval:1000}"
)
private
int
retryInterval
;
/**
* Redisson 心跳间隔(毫秒)
*/
@Value
(
"${spring.data.redis.redisson.ping-interval:60000}"
)
private
int
pingInterval
;
/**
* Redisson 空闲连接超时(毫秒)
*/
@Value
(
"${spring.data.redis.redisson.idle-timeout:10000}"
)
private
int
idleTimeout
;
@Bean
@Bean
public
RedisTemplate
<
String
,
Object
>
redisTemplate
(
RedisConnectionFactory
factory
)
{
public
RedisTemplate
<
String
,
Object
>
redisTemplate
(
RedisConnectionFactory
factory
)
{
...
@@ -59,9 +123,12 @@ public class RedisConfig {
...
@@ -59,9 +123,12 @@ public class RedisConfig {
return
new
StringRedisTemplate
(
factory
);
return
new
StringRedisTemplate
(
factory
);
}
}
// ==================== Redisson ====================
/**
* Redisson 分布式锁客户端
* 使用 @Lazy 延迟初始化,避免启动时阻塞等待 Redis 连接
*/
@Bean
(
destroyMethod
=
"shutdown"
)
@Bean
(
destroyMethod
=
"shutdown"
)
@Lazy
public
RedissonClient
redissonClient
()
{
public
RedissonClient
redissonClient
()
{
Config
config
=
new
Config
();
Config
config
=
new
Config
();
String
address
=
"redis://"
+
host
+
":"
+
port
;
String
address
=
"redis://"
+
host
+
":"
+
port
;
...
@@ -70,9 +137,18 @@ public class RedisConfig {
...
@@ -70,9 +137,18 @@ public class RedisConfig {
.
setAddress
(
address
)
.
setAddress
(
address
)
.
setPassword
(
password
.
isBlank
()
?
null
:
password
)
.
setPassword
(
password
.
isBlank
()
?
null
:
password
)
.
setDatabase
(
database
)
.
setDatabase
(
database
)
.
setConnectionPoolSize
(
16
)
.
setConnectionPoolSize
(
maxActive
)
.
setConnectionMinimumIdleSize
(
4
);
.
setConnectionMinimumIdleSize
(
minIdle
)
.
setConnectTimeout
(
connectTimeout
)
.
setTimeout
(
timeout
)
// 重试配置,避免连接失败时无限等待
.
setRetryAttempts
(
retryAttempts
)
.
setRetryInterval
(
retryInterval
)
// 心跳配置,定期检测连接可用性
.
setPingConnectionInterval
(
pingInterval
)
// 空闲连接超时,及时释放无用连接
.
setIdleConnectionTimeout
(
idleTimeout
);
return
Redisson
.
create
(
config
);
return
Redisson
.
create
(
config
);
}
}
}
}
\ No newline at end of file
custom-server-starter/src/main/resources/application-redis.properties
View file @
7b931415
...
@@ -3,12 +3,32 @@ spring.data.redis.host=172.16.19.100
...
@@ -3,12 +3,32 @@ spring.data.redis.host=172.16.19.100
spring.data.redis.port
=
6379
spring.data.redis.port
=
6379
spring.data.redis.password
=
joshine.dev
spring.data.redis.password
=
joshine.dev
spring.data.redis.database
=
7
spring.data.redis.database
=
7
spring.data.redis.timeout
=
5000ms
spring.data.redis.connect-timeout
=
10000ms
## Lettuce连接池配置
## 超时配置(毫秒)
# 读取/写入超时
spring.data.redis.timeout
=
5000
# 连接超时(缩短,避免长时间等待)
spring.data.redis.connect-timeout
=
3000
## 连接池配置(适配RedissonClient)
spring.data.redis.pool.max-active
=
8
spring.data.redis.pool.max-idle
=
4
spring.data.redis.pool.min-idle
=
2
spring.data.redis.pool.max-wait
=
5000
## Lettuce连接池配置(Spring Data Redis使用)
spring.data.redis.lettuce.pool.enabled
=
true
spring.data.redis.lettuce.pool.enabled
=
true
spring.data.redis.lettuce.pool.max-active
=
16
spring.data.redis.lettuce.pool.max-active
=
8
spring.data.redis.lettuce.pool.max-idle
=
8
spring.data.redis.lettuce.pool.max-idle
=
4
spring.data.redis.lettuce.pool.min-idle
=
4
spring.data.redis.lettuce.pool.min-idle
=
2
spring.data.redis.lettuce.pool.max-wait
=
5000ms
spring.data.redis.lettuce.pool.max-wait
=
5000
## Redisson特有配置
# 重试次数
spring.data.redis.redisson.retry-attempts
=
3
# 重试间隔(毫秒)
spring.data.redis.redisson.retry-interval
=
1000
# 心跳间隔(毫秒)
spring.data.redis.redisson.ping-interval
=
60000
# 空闲连接超时(毫秒)
spring.data.redis.redisson.idle-timeout
=
10000
\ No newline at end of file
custom-server-starter/src/main/resources/application.properties
View file @
7b931415
...
@@ -67,4 +67,7 @@ resilience4j.retry.configs.default.retry-exceptions=java.util.concurrent.Timeout
...
@@ -67,4 +67,7 @@ resilience4j.retry.configs.default.retry-exceptions=java.util.concurrent.Timeout
# 以下异常不触发重试(客户端4xx错误已包装为RemoteServiceException,重试无意义)
# 以下异常不触发重试(客户端4xx错误已包装为RemoteServiceException,重试无意义)
resilience4j.retry.configs.default.ignore-exceptions
=
com.jomalls.custom.integrate.exception.RemoteServiceException
resilience4j.retry.configs.default.ignore-exceptions
=
com.jomalls.custom.integrate.exception.RemoteServiceException
# 远程 API 重试实例使用默认配置
# 远程 API 重试实例使用默认配置
resilience4j.retry.instances.remoteApi.base-config
=
default
resilience4j.retry.instances.remoteApi.base-config
=
default
\ No newline at end of file
server.admin.base-url
=
https://admin.jomalls.com
\ No newline at end of file
custom-server-starter/src/main/resources/logback.xml
→
custom-server-starter/src/main/resources/logback
-spring
.xml
View file @
7b931415
...
@@ -30,16 +30,17 @@
...
@@ -30,16 +30,17 @@
<pattern>
${log.pattern}
</pattern>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
<charset>
UTF-8
</charset>
</encoder>
</encoder>
<filter
class=
"ch.qos.logback.classic.filter.
Threshold
Filter"
>
<filter
class=
"ch.qos.logback.classic.filter.
Level
Filter"
>
<level>
INFO
</level>
<level>
INFO
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</filter>
</appender>
</appender>
<!-- 错误日志:仅 ERROR -->
<appender
name=
"file_warn"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<appender
name=
"file_error"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${log.path}/sys-warn.log
</file>
<file>
${log.path}/sys-error.log
</file>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${log.path}/sys-
error
.%d{yyyy-MM-dd}.log
</fileNamePattern>
<fileNamePattern>
${log.path}/sys-
warn
.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>
60
</maxHistory>
<maxHistory>
60
</maxHistory>
</rollingPolicy>
</rollingPolicy>
<encoder>
<encoder>
...
@@ -47,40 +48,45 @@
...
@@ -47,40 +48,45 @@
<charset>
UTF-8
</charset>
<charset>
UTF-8
</charset>
</encoder>
</encoder>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
ERROR
</level>
<level>
WARN
</level>
<onMatch>
ACCEPT
</onMatch>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</filter>
</appender>
</appender>
<!--
用户操作日志
-->
<!--
错误日志:仅 ERROR
-->
<appender
name=
"
sys-use
r"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<appender
name=
"
file_erro
r"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${log.path}/sys-
use
r.log
</file>
<file>
${log.path}/sys-
erro
r.log
</file>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${log.path}/sys-
use
r.%d{yyyy-MM-dd}.log
</fileNamePattern>
<fileNamePattern>
${log.path}/sys-
erro
r.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>
60
</maxHistory>
<maxHistory>
60
</maxHistory>
</rollingPolicy>
</rollingPolicy>
<encoder>
<encoder>
<pattern>
${log.pattern}
</pattern>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
<charset>
UTF-8
</charset>
</encoder>
</encoder>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
ERROR
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</appender>
</appender>
<!-- ==================== 框架日志级别控制 ==================== -->
<!-- ==================== 框架日志级别控制 ==================== -->
<!-- 项目代码 -->
<!-- 项目代码 -->
<logger
name=
"com.jomalls.custom"
level=
"
INFO
"
/>
<logger
name=
"com.jomalls.custom"
level=
"
DEBUG
"
/>
<!-- Spring 框架 -->
<!-- Spring 框架 -->
<logger
name=
"org.springframework"
level=
"
WARN
"
/>
<logger
name=
"org.springframework"
level=
"
DEBUG
"
/>
<logger
name=
"org.springframework.web"
level=
"
WARN
"
/>
<logger
name=
"org.springframework.web"
level=
"
DEBUG
"
/>
<!-- MyBatis / MyBatis-Plus -->
<!-- MyBatis / MyBatis-Plus -->
<logger
name=
"org.mybatis"
level=
"
WARN
"
/>
<logger
name=
"org.mybatis"
level=
"
DEBUG
"
/>
<logger
name=
"com.baomidou.mybatisplus"
level=
"
WARN
"
/>
<logger
name=
"com.baomidou.mybatisplus"
level=
"
DEBUG
"
/>
<!-- 数据库连接池 -->
<!-- 数据库连接池 -->
<logger
name=
"com.zaxxer.hikari"
level=
"
WARN
"
/>
<logger
name=
"com.zaxxer.hikari"
level=
"
DEBUG
"
/>
<!-- WebClient / Reactor Netty -->
<!-- WebClient / Reactor Netty -->
<logger
name=
"io.netty"
level=
"WARN"
/>
<logger
name=
"io.netty"
level=
"WARN"
/>
...
@@ -91,7 +97,7 @@
...
@@ -91,7 +97,7 @@
<logger
name=
"io.github.resilience4j"
level=
"INFO"
/>
<logger
name=
"io.github.resilience4j"
level=
"INFO"
/>
<!-- Redis / Lettuce -->
<!-- Redis / Lettuce -->
<logger
name=
"io.lettuce"
level=
"
WARN
"
/>
<logger
name=
"io.lettuce"
level=
"
DEBUG
"
/>
<!-- API 文档 -->
<!-- API 文档 -->
<logger
name=
"org.springdoc"
level=
"WARN"
/>
<logger
name=
"org.springdoc"
level=
"WARN"
/>
...
@@ -100,11 +106,7 @@
...
@@ -100,11 +106,7 @@
<root
level=
"INFO"
>
<root
level=
"INFO"
>
<appender-ref
ref=
"console"
/>
<appender-ref
ref=
"console"
/>
<appender-ref
ref=
"file_info"
/>
<appender-ref
ref=
"file_info"
/>
<appender-ref
ref=
"file_warn"
/>
<appender-ref
ref=
"file_error"
/>
<appender-ref
ref=
"file_error"
/>
</root>
</root>
<!-- 用户操作日志(独立 logger,不继承 root 的 appender,避免重复打印到控制台) -->
<logger
name=
"sys-user"
level=
"INFO"
additivity=
"false"
>
<appender-ref
ref=
"sys-user"
/>
</logger>
</configuration>
</configuration>
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductImageController.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImagePageVO
;
import
com.jomalls.custom.app.vo.CustomProductImageVO
;
import
com.jomalls.custom.app.vo.CustomProductImage
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductImageService
;
import
com.jomalls.custom.app.service.CustomProductImageService
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Parameter
;
...
@@ -33,13 +33,13 @@ public class CustomProductImageController {
...
@@ -33,13 +33,13 @@ public class CustomProductImageController {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductImageVO 条件model
* @param customProductImage
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
public
List
<
CustomProductImage
VO
>
list
(
@RequestBody
CustomProductImageVO
customProductImag
eVO
)
{
public
List
<
CustomProductImage
SnakeVO
>
list
(
@RequestBody
CustomProductImageSnakeVO
customProductImageSnak
eVO
)
{
return
customProductImageService
.
list
(
customProductImageVO
);
return
customProductImageService
.
list
(
customProductImage
Snake
VO
);
}
}
/**
/**
...
@@ -50,7 +50,7 @@ public class CustomProductImageController {
...
@@ -50,7 +50,7 @@ public class CustomProductImageController {
*/
*/
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
public
IPage
<
CustomProductImageVO
>
pageList
(
@RequestBody
CustomProductImagePageVO
customProductImagePageVO
)
{
public
IPage
<
CustomProductImage
Snake
VO
>
pageList
(
@RequestBody
CustomProductImagePageVO
customProductImagePageVO
)
{
return
customProductImageService
.
pageList
(
customProductImagePageVO
);
return
customProductImageService
.
pageList
(
customProductImagePageVO
);
}
}
...
@@ -63,31 +63,31 @@ public class CustomProductImageController {
...
@@ -63,31 +63,31 @@ public class CustomProductImageController {
*/
*/
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
public
CustomProductImageVO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
public
CustomProductImage
Snake
VO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
return
customProductImageService
.
info
(
id
);
return
customProductImageService
.
info
(
id
);
}
}
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductImageVO 保存对象
* @param customProductImage
Snake
VO 保存对象
*/
*/
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
public
void
save
(
@RequestBody
@Valid
CustomProductImage
VO
customProductImag
eVO
)
{
public
void
save
(
@RequestBody
@Valid
CustomProductImage
SnakeVO
customProductImageSnak
eVO
)
{
customProductImageService
.
save
(
customProductImageVO
);
customProductImageService
.
save
(
customProductImage
Snake
VO
);
}
}
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductImageVO 修改对象
* @param customProductImage
Snake
VO 修改对象
*/
*/
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
public
void
updateById
(
@RequestBody
CustomProductImage
VO
customProductImag
eVO
)
{
public
void
updateById
(
@RequestBody
CustomProductImage
SnakeVO
customProductImageSnak
eVO
)
{
customProductImageService
.
updateById
(
customProductImageVO
);
customProductImageService
.
updateById
(
customProductImage
Snake
VO
);
}
}
/**
/**
...
...
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductInfoController.java
View file @
7b931415
package
com
.
jomalls
.
custom
.
webapp
.
controller
;
package
com
.
jomalls
.
custom
.
webapp
.
controller
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.dto.CustomProductInfoDTO
;
import
com.jomalls.custom.app.dto.AddBlackListDTO
;
import
com.jomalls.custom.app.vo.CustomProductInfoVO
;
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.enums.CustomProductInfoStatusEnum
;
import
com.jomalls.custom.app.service.CustomProductInfoService
;
import
com.jomalls.custom.app.service.CustomProductInfoService
;
import
com.jomalls.custom.app.vo.CustomProductInfoSnakeVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoVO
;
import
com.jomalls.custom.app.vo.DbDiyVO
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
...
@@ -13,92 +19,116 @@ import org.springframework.beans.factory.annotation.Autowired;
...
@@ -13,92 +19,116 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* @author Lizh
* @author Lizh
* @version 0.0
1
* @version 0.0
2
* @description:
Controller
* @description:
定制商品 Controller(含组合编排操作端点)
* @date 2026-05-29 11:43:04
* @date 2026-05-29 11:43:04
*/
*/
@Slf4j
@Slf4j
@RestController
@RestController
@Tag
(
name
=
"/
customProductInfo"
,
description
=
"Controller
"
)
@Tag
(
name
=
"/
api/v2/product/info"
,
description
=
"定制商品接口
"
)
@RequestMapping
(
"/api/product/info"
)
@RequestMapping
(
"/api/
v2/
product/info"
)
public
class
CustomProductInfoController
{
public
class
CustomProductInfoController
{
@Autowired
@Autowired
private
CustomProductInfoService
customProductInfoService
;
private
CustomProductInfoService
customProductInfoService
;
/**
* 列表查询接口
*
* @param customProductInfoVO 条件model
* @return list集合
*/
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
public
List
<
CustomProductInfoVO
>
list
(
@RequestBody
CustomProductInfoVO
customProductInfoVO
)
{
return
customProductInfoService
.
list
(
customProductInfoVO
);
}
/**
* 根据条件查询分页列表接口
*
* @param param 分页入参model
* @return 分页对象
*/
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@RequestMapping
(
value
=
"/page"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/page"
,
method
=
RequestMethod
.
POST
)
public
IPage
<
CustomProductInfoVO
>
pageList
(
@RequestBody
CustomProductInfoDTO
param
)
{
public
IPage
<
CustomProductInfoVO
>
pageList
(
@RequestBody
CustomProductInfo
Snake
DTO
param
)
{
return
customProductInfoService
.
pageList
(
param
);
return
customProductInfoService
.
pageList
(
param
);
}
}
@Operation
(
summary
=
"创建商品"
,
description
=
"创建商品"
)
@PostMapping
(
"/create"
)
public
void
create
(
@RequestBody
@Valid
CustomProductInfoSnakeDTO
dto
)
{
customProductInfoService
.
saveFull
(
dto
);
}
@Operation
(
summary
=
"组合更新商品"
,
description
=
"事务内处理主表及子表的增/删/改差异"
)
@PostMapping
(
"/update"
)
public
void
update
(
@RequestBody
@Valid
CustomProductInfoUpdateDTO
dto
)
{
customProductInfoService
.
updateFull
(
dto
);
}
@Operation
(
summary
=
"根据 ID 或 SKU 获取完整数据"
,
description
=
"并行加载主表及所有子表数据后在 Java 层组合"
)
@GetMapping
(
"/get"
)
public
CustomProductInfoSnakeVO
getDetail
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
(
required
=
false
)
Integer
id
,
@Parameter
(
description
=
"商品 SKU"
)
@RequestParam
(
required
=
false
)
String
sku
,
@Parameter
(
description
=
"命名空间"
)
@RequestParam
(
required
=
false
)
String
namespace
)
{
return
customProductInfoService
.
getByIdOrSku
(
id
,
sku
,
namespace
);
}
@Operation
(
summary
=
"获取状态列表"
,
description
=
"返回所有商品状态枚举"
)
@GetMapping
(
"/getStatusList"
)
public
List
<
Map
<
String
,
Object
>>
getStatusList
()
{
return
CustomProductInfoStatusEnum
.
getAllStatusList
();
}
@Operation
(
summary
=
"绑定默认模型"
,
description
=
"设置商品的默认 DIY 模板"
)
@GetMapping
(
"/bindDefaultDiy"
)
public
void
bindDefaultDiy
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
,
@Parameter
(
description
=
"DIY 模板 ID"
)
@RequestParam
Integer
diyId
,
@Parameter
(
description
=
"DIY 模板 SKU"
)
@RequestParam
String
diySku
)
{
customProductInfoService
.
bindDefaultDiy
(
id
,
diyId
,
diySku
);
}
@Operation
(
summary
=
"获取绑定的模型"
,
description
=
"获取商品绑定的 DIY 模板列表"
)
@GetMapping
(
"/getBindsDiyById"
)
public
List
<
DbDiyVO
>
getBindsDiyById
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
)
{
return
customProductInfoService
.
getBindsDiyById
(
id
);
}
/**
@Operation
(
summary
=
"获取绑定的客户"
,
description
=
"获取商品绑定的 DIY 用户 ID 列表"
)
* 根据主键id查询详情
@GetMapping
(
"/getBindsDiyUserIdsById"
)
*
public
List
<
Integer
>
getBindsDiyUserIdsById
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
)
{
* @param id 主键
return
customProductInfoService
.
getBindsDiyUserById
(
id
);
* @return 实体model
*/
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
public
CustomProductInfoVO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
return
customProductInfoService
.
info
(
id
);
}
}
/**
@Operation
(
summary
=
"获取黑名单"
,
description
=
"获取商品黑名单 DIY 用户 ID 列表"
)
* 保存对象
@GetMapping
(
"/getBlackListById"
)
*
public
List
<
Integer
>
getBlackListById
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
)
{
* @param customProductInfoVO 保存对象
return
customProductInfoService
.
getBlackListById
(
id
);
*/
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
public
void
save
(
@RequestBody
@Valid
CustomProductInfoVO
customProductInfoVO
)
{
customProductInfoService
.
save
(
customProductInfoVO
);
}
}
@Operation
(
summary
=
"批量绑定客户"
,
description
=
"批量绑定/解绑商品与 DIY 用户的关联"
)
@PostMapping
(
"/bindsDiyUser"
)
public
void
bindsDiyUser
(
@RequestBody
@Valid
BindDiyUserDTO
dto
)
{
customProductInfoService
.
bindsDiyUser
(
dto
);
}
/**
@Operation
(
summary
=
"加入黑名单"
,
description
=
"批量将 DIY 用户加入商品黑名单"
)
* 根据id修改对象
@PostMapping
(
"/addBlackList"
)
*
public
void
addBlackList
(
@RequestBody
@Valid
AddBlackListDTO
dto
)
{
* @param customProductInfoVO 修改对象
customProductInfoService
.
addBlackList
(
dto
);
*/
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
public
void
updateById
(
@RequestBody
CustomProductInfoVO
customProductInfoVO
)
{
customProductInfoService
.
updateById
(
customProductInfoVO
);
}
}
/**
@Operation
(
summary
=
"获取绑定的工艺"
,
description
=
"获取商品绑定的工艺 ID 列表"
)
* 根据主键id进行删除
@GetMapping
(
"/getCraftById"
)
*
public
List
<
Long
>
getCraftById
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
)
{
* @param id 主键
return
customProductInfoService
.
getCraftById
(
id
);
*/
@Operation
(
summary
=
"根据主键id进行删除"
,
description
=
"根据主键id进行删除"
)
@RequestMapping
(
value
=
"/deleteById/{id}"
,
method
=
RequestMethod
.
DELETE
)
public
void
deleteById
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
customProductInfoService
.
deleteById
(
id
);
}
}
// ==================== ERP 专用端点(对齐 TS ApiCustomProductInfoController) ====================
@Operation
(
summary
=
"ERP 分页查询"
,
description
=
"包含黑名单过滤、用户折扣等 ERP 特定逻辑"
)
@PostMapping
(
"/erpPage"
)
public
IPage
<
CustomProductInfoVO
>
erpPage
(
@RequestBody
CustomProductInfoSnakeDTO
param
)
{
return
customProductInfoService
.
erpPage
(
param
);
}
@Operation
(
summary
=
"ERP 获取绑定 DIY"
,
description
=
"获取商品绑定的 DIY 模板(含效果图),支持按 userMark/namespace 过滤"
)
@GetMapping
(
"/getErpBindsDiyById"
)
public
List
<
DbDiyVO
>
getErpBindsDiyById
(
@Parameter
(
description
=
"商品 ID"
)
@RequestParam
Integer
id
,
@Parameter
(
description
=
"用户标识"
)
@RequestParam
(
required
=
false
)
String
userMark
,
@Parameter
(
description
=
"命名空间"
)
@RequestParam
(
required
=
false
)
String
namespace
)
{
return
customProductInfoService
.
getErpBindsDiyById
(
id
,
userMark
,
namespace
);
}
}
}
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductInfoPropertyController.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyPageVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoPropertyVO
;
import
com.jomalls.custom.app.vo.CustomProductInfoProperty
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductInfoPropertyService
;
import
com.jomalls.custom.app.service.CustomProductInfoPropertyService
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Parameter
;
...
@@ -33,13 +33,13 @@ public class CustomProductInfoPropertyController {
...
@@ -33,13 +33,13 @@ public class CustomProductInfoPropertyController {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductInfoPropertyVO 条件model
* @param customProductInfoProperty
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
public
List
<
CustomProductInfoProperty
VO
>
list
(
@RequestBody
CustomProductInfoPropertyVO
customProductInfoProperty
VO
)
{
public
List
<
CustomProductInfoProperty
SnakeVO
>
list
(
@RequestBody
CustomProductInfoPropertySnakeVO
customProductInfoPropertySnake
VO
)
{
return
customProductInfoPropertyService
.
list
(
customProductInfoPropertyVO
);
return
customProductInfoPropertyService
.
list
(
customProductInfoProperty
Snake
VO
);
}
}
/**
/**
...
@@ -50,7 +50,7 @@ public class CustomProductInfoPropertyController {
...
@@ -50,7 +50,7 @@ public class CustomProductInfoPropertyController {
*/
*/
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
public
IPage
<
CustomProductInfoPropertyVO
>
pageList
(
@RequestBody
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
)
{
public
IPage
<
CustomProductInfoProperty
Snake
VO
>
pageList
(
@RequestBody
CustomProductInfoPropertyPageVO
customProductInfoPropertyPageVO
)
{
return
customProductInfoPropertyService
.
pageList
(
customProductInfoPropertyPageVO
);
return
customProductInfoPropertyService
.
pageList
(
customProductInfoPropertyPageVO
);
}
}
...
@@ -63,31 +63,31 @@ public class CustomProductInfoPropertyController {
...
@@ -63,31 +63,31 @@ public class CustomProductInfoPropertyController {
*/
*/
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
public
CustomProductInfoPropertyVO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
public
CustomProductInfoProperty
Snake
VO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
return
customProductInfoPropertyService
.
info
(
id
);
return
customProductInfoPropertyService
.
info
(
id
);
}
}
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductInfoPropertyVO 保存对象
* @param customProductInfoProperty
Snake
VO 保存对象
*/
*/
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
public
void
save
(
@RequestBody
@Valid
CustomProductInfoProperty
VO
customProductInfoProperty
VO
)
{
public
void
save
(
@RequestBody
@Valid
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
)
{
customProductInfoPropertyService
.
save
(
customProductInfoPropertyVO
);
customProductInfoPropertyService
.
save
(
customProductInfoProperty
Snake
VO
);
}
}
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductInfoPropertyVO 修改对象
* @param customProductInfoProperty
Snake
VO 修改对象
*/
*/
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
public
void
updateById
(
@RequestBody
CustomProductInfoProperty
VO
customProductInfoProperty
VO
)
{
public
void
updateById
(
@RequestBody
CustomProductInfoProperty
SnakeVO
customProductInfoPropertySnake
VO
)
{
customProductInfoPropertyService
.
updateById
(
customProductInfoPropertyVO
);
customProductInfoPropertyService
.
updateById
(
customProductInfoProperty
Snake
VO
);
}
}
/**
/**
...
...
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/CustomProductItemController.java
View file @
7b931415
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
...
@@ -2,7 +2,7 @@ package com.jomalls.custom.webapp.controller;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemPageVO
;
import
com.jomalls.custom.app.vo.CustomProductItemVO
;
import
com.jomalls.custom.app.vo.CustomProductItem
Snake
VO
;
import
com.jomalls.custom.app.service.CustomProductItemService
;
import
com.jomalls.custom.app.service.CustomProductItemService
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Parameter
;
...
@@ -33,13 +33,13 @@ public class CustomProductItemController {
...
@@ -33,13 +33,13 @@ public class CustomProductItemController {
/**
/**
* 列表查询接口
* 列表查询接口
*
*
* @param customProductItemVO 条件model
* @param customProductItem
Snake
VO 条件model
* @return list集合
* @return list集合
*/
*/
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
public
List
<
CustomProductItem
VO
>
list
(
@RequestBody
CustomProductItemVO
customProductItem
VO
)
{
public
List
<
CustomProductItem
SnakeVO
>
list
(
@RequestBody
CustomProductItemSnakeVO
customProductItemSnake
VO
)
{
return
customProductItemService
.
list
(
customProductItemVO
);
return
customProductItemService
.
list
(
customProductItem
Snake
VO
);
}
}
/**
/**
...
@@ -50,7 +50,7 @@ public class CustomProductItemController {
...
@@ -50,7 +50,7 @@ public class CustomProductItemController {
*/
*/
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
public
IPage
<
CustomProductItemVO
>
pageList
(
@RequestBody
CustomProductItemPageVO
customProductItemPageVO
)
{
public
IPage
<
CustomProductItem
Snake
VO
>
pageList
(
@RequestBody
CustomProductItemPageVO
customProductItemPageVO
)
{
return
customProductItemService
.
pageList
(
customProductItemPageVO
);
return
customProductItemService
.
pageList
(
customProductItemPageVO
);
}
}
...
@@ -63,31 +63,31 @@ public class CustomProductItemController {
...
@@ -63,31 +63,31 @@ public class CustomProductItemController {
*/
*/
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
public
CustomProductItemVO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
public
CustomProductItem
Snake
VO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
return
customProductItemService
.
info
(
id
);
return
customProductItemService
.
info
(
id
);
}
}
/**
/**
* 保存对象
* 保存对象
*
*
* @param customProductItemVO 保存对象
* @param customProductItem
Snake
VO 保存对象
*/
*/
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
public
void
save
(
@RequestBody
@Valid
CustomProductItem
VO
customProductItem
VO
)
{
public
void
save
(
@RequestBody
@Valid
CustomProductItem
SnakeVO
customProductItemSnake
VO
)
{
customProductItemService
.
save
(
customProductItemVO
);
customProductItemService
.
save
(
customProductItem
Snake
VO
);
}
}
/**
/**
* 根据id修改对象
* 根据id修改对象
*
*
* @param customProductItemVO 修改对象
* @param customProductItem
Snake
VO 修改对象
*/
*/
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
public
void
updateById
(
@RequestBody
CustomProductItem
VO
customProductItem
VO
)
{
public
void
updateById
(
@RequestBody
CustomProductItem
SnakeVO
customProductItemSnake
VO
)
{
customProductItemService
.
updateById
(
customProductItemVO
);
customProductItemService
.
updateById
(
customProductItem
Snake
VO
);
}
}
/**
/**
...
...
custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/ProductFactoryRelController.java
0 → 100644
View file @
7b931415
package
com
.
jomalls
.
custom
.
webapp
.
controller
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.jomalls.custom.app.service.ProductFactoryRelService
;
import
com.jomalls.custom.app.vo.ProductFactoryRelPageVO
;
import
com.jomalls.custom.app.vo.ProductFactoryRelVO
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
jakarta.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
/**
* 产品-工厂关联 Controller
*
* @author Lizh
* @date 2026-06-06
*/
@Slf4j
@RestController
@Tag
(
name
=
"/productFactoryRel"
,
description
=
"产品-工厂关联接口"
)
@RequestMapping
(
"/productFactoryRel"
)
public
class
ProductFactoryRelController
{
@Autowired
private
ProductFactoryRelService
productFactoryRelService
;
@Operation
(
summary
=
"列表查询接口"
,
description
=
"根据条件查询列表接口(不分页)"
)
@RequestMapping
(
value
=
"/list"
,
method
=
RequestMethod
.
POST
)
public
List
<
ProductFactoryRelVO
>
list
(
@RequestBody
ProductFactoryRelVO
vo
)
{
return
productFactoryRelService
.
list
(
vo
);
}
@Operation
(
summary
=
"分页列表接口"
,
description
=
"根据条件查询分页列表接口"
)
@RequestMapping
(
value
=
"/pageList"
,
method
=
RequestMethod
.
POST
)
public
IPage
<
ProductFactoryRelVO
>
pageList
(
@RequestBody
ProductFactoryRelPageVO
param
)
{
return
productFactoryRelService
.
pageList
(
param
);
}
@Operation
(
summary
=
"根据主键id查询详情"
,
description
=
"根据主键id查询详情"
)
@RequestMapping
(
value
=
"/info/{id}"
,
method
=
RequestMethod
.
GET
)
public
ProductFactoryRelVO
info
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
return
productFactoryRelService
.
info
(
id
);
}
@Operation
(
summary
=
"保存对象"
,
description
=
"保存对象"
)
@RequestMapping
(
value
=
"/save"
,
method
=
RequestMethod
.
POST
)
public
void
save
(
@RequestBody
@Valid
ProductFactoryRelVO
vo
)
{
productFactoryRelService
.
save
(
vo
);
}
@Operation
(
summary
=
"根据id修改对象"
,
description
=
"根据id修改对象"
)
@RequestMapping
(
value
=
"/updateById"
,
method
=
RequestMethod
.
PUT
)
public
void
updateById
(
@RequestBody
ProductFactoryRelVO
vo
)
{
productFactoryRelService
.
updateById
(
vo
);
}
@Operation
(
summary
=
"根据主键id进行删除"
,
description
=
"根据主键id进行删除"
)
@RequestMapping
(
value
=
"/deleteById/{id}"
,
method
=
RequestMethod
.
DELETE
)
public
void
deleteById
(
@Parameter
(
description
=
"主键id"
,
required
=
true
)
@PathVariable
(
"id"
)
Integer
id
)
{
productFactoryRelService
.
deleteById
(
id
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment