Commit b287fdb9f2a78e10011b511e1e90f86e8c3c2e8d

Authored by 芋道源码
Committed by Gitee
2 parents 91769f0b 6c174d9c

!544 同步最新商城代码

Merge pull request !544 from 芋道源码/feature/mall_product
Showing 198 changed files with 3229 additions and 956 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
... ... @@ -27,8 +27,6 @@ public interface WebFilterOrderEnum {
27 27  
28 28 int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后面
29 29  
30   - int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面
31   -
32 30 int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面
33 31  
34 32 int DEMO_FILTER = Integer.MAX_VALUE;
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
... ... @@ -37,15 +37,4 @@ public interface GlobalErrorCodeConstants {
37 37  
38 38 ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
39 39  
40   - /**
41   - * 是否为服务端错误,参考 HTTP 5XX 错误码段
42   - *
43   - * @param code 错误码
44   - * @return 是否
45   - */
46   - static boolean isServerErrorCode(Integer code) {
47   - return code != null
48   - && code >= INTERNAL_SERVER_ERROR.getCode() && code <= INTERNAL_SERVER_ERROR.getCode() + 99;
49   - }
50   -
51 40 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
1 1 package cn.iocoder.yudao.framework.common.pojo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4   -import cn.iocoder.yudao.framework.common.exception.ServerException;
5 4 import cn.iocoder.yudao.framework.common.exception.ServiceException;
6 5 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
7 6 import com.fasterxml.jackson.annotation.JsonIgnore;
... ... @@ -92,10 +91,6 @@ public class CommonResult&lt;T&gt; implements Serializable {
92 91 if (isSuccess()) {
93 92 return;
94 93 }
95   - // 服务端异常
96   - if (GlobalErrorCodeConstants.isServerErrorCode(code)) {
97   - throw new ServerException(code, msg);
98   - }
99 94 // 业务异常
100 95 throw new ServiceException(code, msg);
101 96 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
4 4  
5 5 import java.time.Duration;
6 6 import java.time.LocalDateTime;
  7 +import java.time.LocalTime;
7 8  
8 9 /**
9 10 * 时间工具类,用于 {@link java.time.LocalDateTime}
... ... @@ -50,7 +51,7 @@ public class LocalDateTimeUtils {
50 51 * 判断当前时间是否在该时间范围内
51 52 *
52 53 * @param startTime 开始时间
53   - * @param endTime 结束时间
  54 + * @param endTime 结束时间
54 55 * @return 是否
55 56 */
56 57 public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime) {
... ... @@ -60,4 +61,24 @@ public class LocalDateTimeUtils {
60 61 return LocalDateTimeUtil.isIn(LocalDateTime.now(), startTime, endTime);
61 62 }
62 63  
  64 + /**
  65 + * 检查时间重叠 不包含日期
  66 + *
  67 + * @param startTime1 需要校验的开始时间
  68 + * @param endTime1 需要校验的结束时间
  69 + * @param startTime2 校验所需的开始时间
  70 + * @param endTime2 校验所需的结束时间
  71 + * @return 是否重叠
  72 + */
  73 + // TODO @puhui999:LocalDateTimeUtil.isOverlap() 是不是可以满足呀?
  74 + public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
  75 + // 判断时间是否重叠
  76 + // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
  77 + return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
  78 + // 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
  79 + || startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
  80 + // 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
  81 + || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
  82 + }
  83 +
63 84 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
... ... @@ -21,6 +21,7 @@ public class YudaoJacksonAutoConfiguration {
21 21 @Bean
22 22 public BeanPostProcessor objectMapperBeanPostProcessor() {
23 23 return new BeanPostProcessor() {
  24 +
24 25 @Override
25 26 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
26 27 if (!(bean instanceof ObjectMapper)) {
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
... ... @@ -17,12 +17,9 @@ import org.flowable.task.api.Task;
17 17 import org.flowable.task.api.history.HistoricTaskInstance;
18 18 import org.mapstruct.*;
19 19 import org.mapstruct.factory.Mappers;
20   -import org.springframework.beans.BeanUtils;
21 20  
22   -import java.util.Collections;
23 21 import java.util.List;
24 22 import java.util.Map;
25   -import java.util.stream.Collectors;
26 23  
27 24 /**
28 25 * Bpm 任务 Convert
... ... @@ -34,37 +31,9 @@ public interface BpmTaskConvert {
34 31  
35 32 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
36 33  
37   - /**
38   - * 复制对象
39   - *
40   - * @param source 源 要复制的对象
41   - * @param target 目标 复制到此对象
42   - * @param <T>
43   - *
44   - * @return
45   - */
46   - public static <T> T copy(Object source, Class<T> target) {
47   - if (source == null || target == null) {
48   - return null;
49   - }
50   - try {
51   - T newInstance = target.getDeclaredConstructor().newInstance();
52   - BeanUtils.copyProperties(source, newInstance);
53   - return newInstance;
54   - } catch (Exception e) {
55   - throw new RuntimeException(e);
56   - }
57   - }
58   -
59   - default <T, K> List<K> copyList(List<T> source, Class<K> target) {
60   - if (null == source || source.isEmpty()) {
61   - return Collections.emptyList();
62   - }
63   - return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
64   - }
65   -
66 34 default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks,
67   - Map<String, ProcessInstance> processInstanceMap, Map<Long, AdminUserRespDTO> userMap) {
  35 + Map<String, ProcessInstance> processInstanceMap,
  36 + Map<Long, AdminUserRespDTO> userMap) {
68 37 return CollectionUtils.convertList(tasks, task -> {
69 38 BpmTaskTodoPageItemRespVO respVO = convert1(task);
70 39 ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmActivityDO.java deleted
1   -package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2   -
3   -import com.fasterxml.jackson.annotation.JsonFormat;
4   -import lombok.*;
5   -import org.springframework.format.annotation.DateTimeFormat;
6   -
7   -import java.time.LocalDateTime;
8   -
9   -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10   -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
11   -
12   -/**
13   - * 任务流程关联表
14   - *
15   - * @author kemengkai
16   - * @create 2022-05-09 10:33
17   - */
18   -@Data
19   -@AllArgsConstructor
20   -@NoArgsConstructor
21   -public class BpmActivityDO {
22   -
23   - /**
24   - * 任务流程关联id
25   - */
26   - private String id;
27   -
28   - /**
29   - * 审批结果
30   - */
31   - private Integer rev;
32   -
33   - /**
34   - * 任务流程部署id
35   - */
36   - private String procDefId;
37   -
38   - /**
39   - * 任务流程id
40   - */
41   - private String processInstanceId;
42   -
43   - /**
44   - * 任务执行id
45   - */
46   - private String executionId;
47   -
48   - /**
49   - * 任务key
50   - */
51   - private String activityId;
52   -
53   - /**
54   - * 任务id
55   - */
56   - private String taskId;
57   -
58   - /**
59   - * 调用流程id
60   - */
61   - private String callProcInstId;
62   -
63   - /**
64   - * 任务名称
65   - */
66   - private String activityName;
67   -
68   - /**
69   - * 任务类型
70   - */
71   - private String activityType;
72   -
73   - /**
74   - * 任务审批人id
75   - */
76   - private String assignee;
77   -
78   - /**
79   - * 任务开始时间
80   - */
81   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
82   - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
83   - private LocalDateTime startTime;
84   -
85   - /**
86   - * 任务结束时间
87   - */
88   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
89   - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
90   - private LocalDateTime endTime;
91   -
92   - private Integer transactionOrder;
93   -
94   - private LocalDateTime duration;
95   -
96   - /**
97   - * 删除结果
98   - */
99   - private String deleteReason;
100   -
101   - /**
102   - * 租户id
103   - */
104   - private String tenantId;
105   -}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo;
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6   -@Schema(description = "管理后台 - 代码生成预览 Response VO,注意,每个文件都是一个该对象")
  6 +@Schema(description = "管理后台 - 代码生成预览 Response VO,注意,每个文件都是一个该对象")
7 7 @Data
8 8 public class CodegenPreviewRespVO {
9 9  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java
... ... @@ -70,7 +70,7 @@ public class CodegenColumnBaseVO {
70 70 @NotNull(message = "是否为 List 查询操作的字段不能为空")
71 71 private Boolean listOperation;
72 72  
73   - @Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "LIKE")
  73 + @Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "LIKE")
74 74 @NotNull(message = "List 查询操作的条件类型不能为空")
75 75 private String listOperationCondition;
76 76  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java
... ... @@ -12,7 +12,7 @@ import javax.validation.constraints.NotNull;
12 12 @Data
13 13 public class CodegenTableBaseVO {
14 14  
15   - @Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + @Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
16 16 @NotNull(message = "导入类型不能为空")
17 17 private Integer scene;
18 18  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java
... ... @@ -17,13 +17,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class CodegenTablePageReqVO extends PageParam {
19 19  
20   - @Schema(description = "表名称,模糊匹配", example = "yudao")
  20 + @Schema(description = "表名称,模糊匹配", example = "yudao")
21 21 private String tableName;
22 22  
23   - @Schema(description = "表描述,模糊匹配", example = "芋道")
  23 + @Schema(description = "表描述,模糊匹配", example = "芋道")
24 24 private String tableComment;
25 25  
26   - @Schema(description = "实体,模糊匹配", example = "Yudao")
  26 + @Schema(description = "实体,模糊匹配", example = "Yudao")
27 27 private String className;
28 28  
29 29 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java
... ... @@ -15,10 +15,10 @@ public class ConfigExportReqVO {
15 15 @Schema(description = "参数名称", example = "模糊匹配")
16 16 private String name;
17 17  
18   - @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username")
  18 + @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username")
19 19 private String key;
20 20  
21   - @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1")
  21 + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1")
22 22 private Integer type;
23 23  
24 24 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java
... ... @@ -17,13 +17,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class ConfigPageReqVO extends PageParam {
19 19  
20   - @Schema(description = "数据源名称,模糊匹配", example = "名称")
  20 + @Schema(description = "数据源名称,模糊匹配", example = "名称")
21 21 private String name;
22 22  
23   - @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username")
  23 + @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username")
24 24 private String key;
25 25  
26   - @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1")
  26 + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1")
27 27 private Integer type;
28 28  
29 29 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java
... ... @@ -21,7 +21,7 @@ public class ConfigRespVO extends ConfigBaseVO {
21 21 @Size(max = 100, message = "参数键名长度不能超过100个字符")
22 22 private String key;
23 23  
24   - @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  24 + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 25 private Integer type;
26 26  
27 27 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java
... ... @@ -14,7 +14,7 @@ import java.util.Map;
14 14 @ToString(callSuper = true)
15 15 public class FileConfigCreateReqVO extends FileConfigBaseVO {
16 16  
17   - @Schema(description = "存储器,参见 FileStorageEnum 枚举类参见 FileStorageEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @Schema(description = "存储器,参见 FileStorageEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
18 18 @NotNull(message = "存储器不能为空")
19 19 private Integer storage;
20 20  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java
... ... @@ -23,8 +23,8 @@ public class FileConfigPageReqVO extends PageParam {
23 23 @Schema(description = "存储器", example = "1")
24 24 private Integer storage;
25 25  
  26 + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
26 27 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
27   - @Schema(description = "创建时间")
28 28 private LocalDateTime[] createTime;
29 29  
30 30 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java
... ... @@ -18,7 +18,7 @@ public class FileConfigRespVO extends FileConfigBaseVO {
18 18 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 19 private Long id;
20 20  
21   - @Schema(description = "存储器,参见 FileStorageEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @Schema(description = "存储器,参见 FileStorageEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
22 22 @NotNull(message = "存储器不能为空")
23 23 private Integer storage;
24 24  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java
... ... @@ -17,14 +17,14 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class FilePageReqVO extends PageParam {
19 19  
20   - @Schema(description = "文件路径,模糊匹配", example = "yudao")
  20 + @Schema(description = "文件路径,模糊匹配", example = "yudao")
21 21 private String path;
22 22  
23   - @Schema(description = "文件类型,模糊匹配", example = "application/octet-stream")
  23 + @Schema(description = "文件类型,模糊匹配", example = "jpg")
24 24 private String type;
25 25  
  26 + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
26 27 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
27   - @Schema(description = "创建时间")
28 28 private LocalDateTime[] createTime;
29 29  
30 30 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java
... ... @@ -12,13 +12,13 @@ import lombok.ToString;
12 12 @ToString(callSuper = true)
13 13 public class JobPageReqVO extends PageParam {
14 14  
15   - @Schema(description = "任务名称,模糊匹配", example = "测试任务")
  15 + @Schema(description = "任务名称,模糊匹配", example = "测试任务")
16 16 private String name;
17 17  
18   - @Schema(description = "任务状态,参见 JobStatusEnum 枚举", example = "1")
  18 + @Schema(description = "任务状态,参见 JobStatusEnum 枚举", example = "1")
19 19 private Integer status;
20 20  
21   - @Schema(description = "处理器的名字,模糊匹配", example = "sysUserSessionTimeoutJob")
  21 + @Schema(description = "处理器的名字,模糊匹配", example = "sysUserSessionTimeoutJob")
22 22 private String handlerName;
23 23  
24 24 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java
... ... @@ -43,7 +43,7 @@ public class JobLogBaseVO {
43 43 @Schema(description = "执行时长", example = "123")
44 44 private Integer duration;
45 45  
46   - @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  46 + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
47 47 @NotNull(message = "任务状态不能为空")
48 48 private Integer status;
49 49  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java
... ... @@ -8,14 +8,14 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 定时任务 Excel 导出 Request VO,参数和 JobLogPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 定时任务 Excel 导出 Request VO,参数和 JobLogPageReqVO 是一致的")
12 12 @Data
13 13 public class JobLogExportReqVO {
14 14  
15 15 @Schema(description = "任务编号", example = "10")
16 16 private Long jobId;
17 17  
18   - @Schema(description = "处理器的名字,模糊匹配")
  18 + @Schema(description = "处理器的名字,模糊匹配")
19 19 private String handlerName;
20 20  
21 21 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ... @@ -26,7 +26,7 @@ public class JobLogExportReqVO {
26 26 @Schema(description = "结束执行时间")
27 27 private LocalDateTime endTime;
28 28  
29   - @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举")
  29 + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举")
30 30 private Integer status;
31 31  
32 32 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java
... ... @@ -20,7 +20,7 @@ public class JobLogPageReqVO extends PageParam {
20 20 @Schema(description = "任务编号", example = "10")
21 21 private Long jobId;
22 22  
23   - @Schema(description = "处理器的名字,模糊匹配")
  23 + @Schema(description = "处理器的名字,模糊匹配")
24 24 private String handlerName;
25 25  
26 26 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ... @@ -31,7 +31,7 @@ public class JobLogPageReqVO extends PageParam {
31 31 @Schema(description = "结束执行时间")
32 32 private LocalDateTime endTime;
33 33  
34   - @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举")
  34 + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举")
35 35 private Integer status;
36 36  
37 37 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java
... ... @@ -24,7 +24,7 @@ public class ApiAccessLogBaseVO {
24 24 @NotNull(message = "用户编号不能为空")
25 25 private Long userId;
26 26  
27   - @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  27 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
28 28 @NotNull(message = "用户类型不能为空")
29 29 private Integer userType;
30 30  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - API 访问日志 Excel 导出 Request VO,参数和 ApiAccessLogPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - API 访问日志 Excel 导出 Request VO,参数和 ApiAccessLogPageReqVO 是一致的")
12 12 @Data
13 13 public class ApiAccessLogExportReqVO {
14 14  
... ... @@ -21,11 +21,11 @@ public class ApiAccessLogExportReqVO {
21 21 @Schema(description = "应用名", example = "dashboard")
22 22 private String applicationName;
23 23  
24   - @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy")
  24 + @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy")
25 25 private String requestUrl;
26 26  
  27 + @Schema(description = "开始时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
27 28 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
28   - @Schema(description = "开始请求时间")
29 29 private LocalDateTime[] beginTime;
30 30  
31 31 @Schema(description = "执行时长,大于等于,单位:毫秒", example = "100")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java
... ... @@ -26,11 +26,11 @@ public class ApiAccessLogPageReqVO extends PageParam {
26 26 @Schema(description = "应用名", example = "dashboard")
27 27 private String applicationName;
28 28  
29   - @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy")
  29 + @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy")
30 30 private String requestUrl;
31 31  
  32 + @Schema(description = "开始时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
32 33 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
33   - @Schema(description = "开始请求时间")
34 34 private LocalDateTime[] beginTime;
35 35  
36 36 @Schema(description = "执行时长,大于等于,单位:毫秒", example = "100")
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - API 错误日志 Excel 导出 Request VO,参数和 ApiErrorLogPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - API 错误日志 Excel 导出 Request VO,参数和 ApiErrorLogPageReqVO 是一致的")
12 12 @Data
13 13 public class ApiErrorLogExportReqVO {
14 14  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java
... ... @@ -7,7 +7,7 @@ import org.springframework.format.annotation.DateTimeFormat;
7 7  
8 8 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
9 9  
10   -@Schema(description = "管理后台 - 字典类型 Excel 导出 Request VO,参数和 TestDemoPageReqVO 是一致的")
  10 +@Schema(description = "管理后台 - 字典类型 Excel 导出 Request VO,参数和 TestDemoPageReqVO 是一致的")
11 11 @Data
12 12 public class TestDemoExportReqVO {
13 13  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java
... ... @@ -57,7 +57,7 @@ public class DatabaseTableServiceImpl implements DatabaseTableService {
57 57 strategyConfig.addExclude("ACT_[\\S\\s]+|QRTZ_[\\S\\s]+|FLW_[\\S\\s]+");
58 58 }
59 59  
60   - GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.TIME_PACK).build(); // 只使用 Date 类型,不使用 LocalDate
  60 + GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.TIME_PACK).build(); // 只使用 LocalDateTime 类型,不使用 LocalDate
61 61 ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, strategyConfig.build(),
62 62 null, globalConfig, null);
63 63 // 按照名字排序
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java
... ... @@ -79,7 +79,7 @@ public class TestDemoServiceImpl implements TestDemoService {
79 79  
80 80 @Override
81 81 public PageResult<TestDemoDO> getTestDemoPage(TestDemoPageReqVO pageReqVO) {
82   - testDemoMapper.selectList2();
  82 +// testDemoMapper.selectList2();
83 83 return testDemoMapper.selectPage(pageReqVO);
84 84 }
85 85  
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
... ... @@ -30,14 +30,13 @@ public interface ProductSkuApi {
30 30 */
31 31 List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
32 32  
33   - // TODO puhui999:入参用 Collection<Long> 更通用
34 33 /**
35 34 * 批量查询 SKU 数组
36 35 *
37 36 * @param spuIds SPU 编号列表
38 37 * @return SKU 数组
39 38 */
40   - List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds);
  39 + List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds);
41 40  
42 41 /**
43 42 * 更新 SKU 库存
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
... ... @@ -45,10 +45,8 @@ public interface ErrorCodeConstants {
45 45 ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
46 46  
47 47 // ========== 商品 评价 1008007000 ==========
48   - ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
49   - ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
50   - ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
51   - ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在");
  48 + ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品评价不存在");
  49 + ErrorCode COMMENT_ORDER_EXISTS = new ErrorCode(1008007001, "订单的商品评价已存在");
52 50  
53 51 // ========== 商品 收藏 1008008000 ==========
54 52 ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
... ... @@ -43,7 +43,7 @@ public class ProductSkuApiImpl implements ProductSkuApi {
43 43 }
44 44  
45 45 @Override
46   - public List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds) {
  46 + public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) {
47 47 if (CollUtil.isEmpty(spuIds)) {
48 48 return Collections.emptyList();
49 49 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java
... ... @@ -26,23 +26,10 @@ public class ProductCommentBaseVO {
26 26 @NotNull(message = "评价人头像不能为空")
27 27 private String userAvatar;
28 28  
29   - // TODO @puhui:spuId、spuName 是不是只有 ProductCommentRespVO 有呀。
30   - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
31   - @NotNull(message = "商品 SPU 编号不能为空")
32   - private Long spuId;
33   -
34   - @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
35   - @NotNull(message = "商品 SPU 名称不能为空")
36   - private String spuName;
37   -
38 29 @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
39 30 @NotNull(message = "商品 SKU 编号不能为空")
40 31 private Long skuId;
41 32  
42   - @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
43   - @NotNull(message = "评分星级不能为空")
44   - private Integer scores;
45   -
46 33 @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
47 34 @NotNull(message = "描述星级不能为空")
48 35 private Integer descriptionScores;
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java
... ... @@ -35,9 +35,8 @@ public class ProductCommentPageReqVO extends PageParam {
35 35 @InEnum(ProductCommentScoresEnum.class)
36 36 private Integer scores;
37 37  
38   - // TODO @puhui999:replyStatus 哈
39 38 @Schema(description = "商家是否回复", example = "true")
40   - private Boolean replied;
  39 + private Boolean replyStatus;
41 40  
42 41 @Schema(description = "创建时间")
43 42 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java
... ... @@ -5,6 +5,7 @@ import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6 6 import lombok.ToString;
7 7  
  8 +import javax.validation.constraints.NotNull;
8 9 import java.time.LocalDateTime;
9 10  
10 11 @Schema(description = "管理后台 - 商品评价 Response VO")
... ... @@ -40,4 +41,15 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
40 41 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
41 42 private LocalDateTime createTime;
42 43  
  44 + @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
  45 + private Integer scores;
  46 +
  47 + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
  48 + @NotNull(message = "商品 SPU 编号不能为空")
  49 + private Long spuId;
  50 +
  51 + @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  52 + @NotNull(message = "商品 SPU 名称不能为空")
  53 + private String spuName;
  54 +
43 55 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
... ... @@ -21,6 +21,7 @@ import javax.annotation.Resource;
21 21 import javax.servlet.http.HttpServletResponse;
22 22 import javax.validation.Valid;
23 23 import java.io.IOException;
  24 +import java.util.Collection;
24 25 import java.util.List;
25 26 import java.util.Map;
26 27  
... ... @@ -29,11 +30,6 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
29 30 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
30 31 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
31 32  
32   -/**
33   - * 商品 SPU 相关接口
34   - *
35   - * @author HUIHUI
36   - */
37 33 @Tag(name = "管理后台 - 商品 SPU")
38 34 @RestController
39 35 @RequestMapping("/product/spu")
... ... @@ -100,6 +96,15 @@ public class ProductSpuController {
100 96 return success(ProductSpuConvert.INSTANCE.convertList02(list));
101 97 }
102 98  
  99 + @GetMapping("/list")
  100 + @Operation(summary = "获得商品 SPU 详情列表")
  101 + @Parameter(name = "spuIds", description = "spu 编号列表", required = true, example = "[1,2,3]")
  102 + @PreAuthorize("@ss.hasPermission('product:spu:query')")
  103 + public CommonResult<List<ProductSpuDetailRespVO>> getSpuList(@RequestParam("spuIds") Collection<Long> spuIds) {
  104 + return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespListVO(
  105 + productSpuService.getSpuList(spuIds), productSkuService.getSkuListBySpuId(spuIds)));
  106 + }
  107 +
103 108 @GetMapping("/page")
104 109 @Operation(summary = "获得商品 SPU 分页")
105 110 @PreAuthorize("@ss.hasPermission('product:spu:query')")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java
... ... @@ -9,11 +9,6 @@ import lombok.ToString;
9 9 import javax.validation.Valid;
10 10 import java.util.List;
11 11  
12   -/**
13   - * 商品 SPU 创建 Request VO
14   - *
15   - * @author HUIHUI
16   - */
17 12 @Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
18 13 @Data
19 14 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
... ... @@ -8,12 +8,6 @@ import lombok.ToString;
8 8  
9 9 import java.util.List;
10 10  
11   -/**
12   - * 商品 SPU 详细 Response VO
13   - * 包括关联的 SKU 等信息
14   - *
15   - * @author HUIHUI
16   - */
17 11 @Schema(description = "管理后台 - 商品 SPU 详细 Response VO")
18 12 @Data
19 13 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
... ... @@ -10,12 +10,7 @@ import java.time.LocalDateTime;
10 10  
11 11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 12  
13   -/**
14   - * 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的
15   - *
16   - * @author HUIHUI
17   - */
18   -@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
  13 +@Schema(description = "管理后台 - 商品 SPU 导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
19 14 @Data
20 15 @NoArgsConstructor
21 16 @AllArgsConstructor
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
... ... @@ -11,11 +11,6 @@ import java.time.LocalDateTime;
11 11  
12 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
13 13  
14   -/**
15   - * 商品 SPU 分页 Request VO
16   - *
17   - * @author HUIHUI
18   - */
19 14 @Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
20 15 @Data
21 16 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
... ... @@ -7,11 +7,6 @@ import lombok.ToString;
7 7  
8 8 import java.time.LocalDateTime;
9 9  
10   -/**
11   - * 商品 SPU Response VO
12   - *
13   - * @author HUIHUI
14   - */
15 10 @Schema(description = "管理后台 - 商品 SPU Response VO")
16 11 @Data
17 12 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java
... ... @@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5 import lombok.ToString;
6 6  
7   -/**
8   - * 商品 SPU 精简 Response VO
9   - * TODO 商品 SPU 精简 VO 暂时没有使用到,用到的时候再按需添加\修改属性
10   - * @author HUIHUI
11   - */
12 7 @Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
13 8 @Data
14 9 @ToString(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java
... ... @@ -12,11 +12,6 @@ import javax.validation.Valid;
12 12 import javax.validation.constraints.NotNull;
13 13 import java.util.List;
14 14  
15   -/**
16   - * 商品 SPU 更新 Request VO
17   - *
18   - * @author HUIHUI
19   - */
20 15 @Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
21 16 @Data
22 17 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java
... ... @@ -7,11 +7,6 @@ import lombok.Data;
7 7  
8 8 import javax.validation.constraints.NotNull;
9 9  
10   -/**
11   - * 商品 SPU Status 更新 Request VO
12   - *
13   - * @author HUIHUI
14   - */
15 10 @Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO")
16 11 @Data
17 12 public class ProductSpuUpdateStatusReqVO{
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
1 1 package cn.iocoder.yudao.module.product.controller.app.comment;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.ObjectUtil;
5 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 7 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
8 8 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
9 9 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
10   -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
11 10 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
12 11 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
13 12 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
14 13 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
15 14 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  15 +import com.google.common.collect.Maps;
16 16 import io.swagger.v3.oas.annotations.Operation;
17 17 import io.swagger.v3.oas.annotations.Parameter;
18 18 import io.swagger.v3.oas.annotations.Parameters;
... ... @@ -26,11 +26,9 @@ import org.springframework.web.bind.annotation.RestController;
26 26  
27 27 import javax.annotation.Resource;
28 28 import javax.validation.Valid;
29   -import java.util.HashMap;
30 29 import java.util.List;
31 30 import java.util.Map;
32 31 import java.util.Set;
33   -import java.util.stream.Collectors;
34 32  
35 33 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
36 34  
... ... @@ -53,34 +51,24 @@ public class AppProductCommentController {
53 51 @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"),
54 52 @Parameter(name = "count", description = "数量", required = true, example = "10")
55 53 })
56   - public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
57   - @RequestParam(value = "count", defaultValue = "10") Integer count) {
  54 + public CommonResult<List<AppProductCommentRespVO>> getCommentList(
  55 + @RequestParam("spuId") Long spuId,
  56 + @RequestParam(value = "count", defaultValue = "10") Integer count) {
58 57 return success(productCommentService.getCommentList(spuId, count));
59 58 }
60 59  
61 60 @GetMapping("/page")
62 61 @Operation(summary = "获得商品评价分页")
63 62 public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
64   - PageResult<AppProductCommentRespVO> page = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
65   - // TODO @puhui CollUtils 有简化 convertmap 和 list 的方法
66   - Set<Long> skuIds = page.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
  63 + // TODO @puhui999:写到 convert 里,可以更简洁哈。
  64 + PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
  65 + Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
67 66 List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
68   - Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
  67 + Map<Long, ProductSkuDO> skuDOMap = Maps.newLinkedHashMapWithExpectedSize(skuIds.size());
69 68 if (CollUtil.isNotEmpty(skuList)) {
70   - skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c)));
  69 + skuDOMap.putAll(CollectionUtils.convertMap(skuList, ProductSkuDO::getId, c -> c));
71 70 }
72   - // TODO @puihui999:下面也可以放到 convert 里哈
73   - page.getList().forEach(item -> {
74   - // 判断用户是否选择匿名
75   - if (ObjectUtil.equal(item.getAnonymous(), true)) {
76   - item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
77   - }
78   - ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
79   - if (productSkuDO != null) {
80   - List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
81   - item.setSkuProperties(skuProperties);
82   - }
83   - });
  71 + PageResult<AppProductCommentRespVO> page = ProductCommentConvert.INSTANCE.convertPage02(commentDOPage, skuDOMap);
84 72 return success(page);
85 73 }
86 74  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java
... ... @@ -10,11 +10,6 @@ import javax.validation.constraints.Size;
10 10 import java.time.LocalDateTime;
11 11 import java.util.List;
12 12  
13   -/**
14   - * 用户 App - 商品评价详情 Response VO
15   - *
16   - * @author HUIHUI
17   - */
18 13 @Schema(description = "用户 App - 商品评价详情 Response VO")
19 14 @Data
20 15 @ToString(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
1 1 package cn.iocoder.yudao.module.product.convert.comment;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
4 6 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
5 7 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
6 8 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
... ... @@ -19,6 +21,7 @@ import org.mapstruct.factory.Mappers;
19 21 import java.math.BigDecimal;
20 22 import java.math.RoundingMode;
21 23 import java.util.List;
  24 +import java.util.Map;
22 25  
23 26 /**
24 27 * 商品评价 Convert
... ... @@ -32,19 +35,33 @@ public interface ProductCommentConvert {
32 35  
33 36 ProductCommentRespVO convert(ProductCommentDO bean);
34 37  
35   - // TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈
36   - @Mapping(target = "goodCount", source = "goodCount")
37   - @Mapping(target = "mediocreCount", source = "mediocreCount")
38   - @Mapping(target = "negativeCount", source = "negativeCount")
  38 + @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
39 39 AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
40   -
  40 + @Named("calculateOverallScore")
  41 + default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
  42 + return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
  43 + }
  44 +
41 45 List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
42 46  
43   - List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);
44   -
45 47 PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
46 48  
47   - PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
  49 + PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
  50 +
  51 + default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult,
  52 + Map<Long, ProductSkuDO> skuMap) {
  53 + PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
  54 + page.getList().forEach(item -> {
  55 + // 判断用户是否选择匿名
  56 + if (ObjectUtil.equal(item.getAnonymous(), true)) {
  57 + item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
  58 + }
  59 + MapUtils.findAndThen(skuMap, item.getSkuId(),
  60 + sku -> item.setSkuProperties(convertList01(sku.getProperties())));
  61 + });
  62 + return page;
  63 + }
  64 + List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);
48 65  
49 66 /**
50 67 * 计算综合评分
... ... @@ -63,14 +80,19 @@ public interface ProductCommentConvert {
63 80  
64 81 ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO);
65 82  
66   - @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
  83 + @Mapping(target = "scores",
  84 + expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
67 85 default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) {
68 86 ProductCommentDO commentDO = convert(createReqDTO);
69   - commentDO.setUserId(user.getId());
70   - commentDO.setUserNickname(user.getNickname());
71   - commentDO.setUserAvatar(user.getAvatar());
72   - commentDO.setSpuId(spuDO.getId());
73   - commentDO.setSpuName(spuDO.getName());
  87 + if (user != null) {
  88 + commentDO.setUserId(user.getId());
  89 + commentDO.setUserNickname(user.getNickname());
  90 + commentDO.setUserAvatar(user.getAvatar());
  91 + }
  92 + if (spuDO != null) {
  93 + commentDO.setSpuId(spuDO.getId());
  94 + commentDO.setSpuName(spuDO.getName());
  95 + }
74 96 return commentDO;
75 97 }
76 98  
... ... @@ -78,7 +100,8 @@ public interface ProductCommentConvert {
78 100 @Mapping(target = "orderId", constant = "0L")
79 101 @Mapping(target = "orderItemId", constant = "0L")
80 102 @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)")
81   - @Mapping(target = "scores", expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
  103 + @Mapping(target = "scores",
  104 + expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
82 105 ProductCommentDO convert(ProductCommentCreateReqVO createReq);
83 106  
84 107 List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list);
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
... ... @@ -18,8 +18,10 @@ import org.mapstruct.factory.Mappers;
18 18  
19 19 import java.util.ArrayList;
20 20 import java.util.List;
  21 +import java.util.Map;
21 22  
22 23 import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
  24 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
23 25  
24 26 /**
25 27 * 商品 SPU Convert
... ... @@ -107,4 +109,16 @@ public interface ProductSpuConvert {
107 109 return detailRespVO;
108 110 }
109 111  
  112 + default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
  113 + List<ProductSpuDetailRespVO> vos = new ArrayList<>(spus.size());
  114 + Map<Long, List<ProductSkuDO>> skuMultiMap = convertMultiMap(skus, ProductSkuDO::getSpuId);
  115 + // TODO @puhui999:可以直接使用 CollUtils.convertList
  116 + spus.forEach(spu -> {
  117 + ProductSpuDetailRespVO detailRespVO = convert03(spu);
  118 + detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skuMultiMap.get(spu.getId())));
  119 + vos.add(detailRespVO);
  120 + });
  121 + return vos;
  122 + }
  123 +
110 124 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
... ... @@ -26,6 +26,7 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
26 26 }
27 27  
28 28 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
  29 + // TODO @puhui999:是不是不用 apply 拉?直接用 mybatis 的方法就好啦
29 30 // 构建好评查询语句:好评计算 总评 >= 4
30 31 if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
31 32 queryWrapper.apply("scores >= 4");
... ... @@ -51,11 +52,11 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
51 52 return selectPage(reqVO, queryWrapper);
52 53 }
53 54  
54   - default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long spuId) {
  55 + default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long skuId) {
55 56 return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
56 57 .eq(ProductCommentDO::getUserId, userId)
57 58 .eq(ProductCommentDO::getOrderItemId, orderItemId)
58   - .eq(ProductCommentDO::getSpuId, spuId));
  59 + .eq(ProductCommentDO::getSpuId, skuId));
59 60 }
60 61  
61 62 default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) {
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java
... ... @@ -54,7 +54,7 @@ public interface ProductCommentService {
54 54 * @param visible 是否可见
55 55 * @return 商品评价分页
56 56 */
57   - PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
  57 + PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
58 58  
59 59 /**
60 60 * 创建商品评论
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
... ... @@ -81,7 +81,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
81 81 @Transactional(rollbackFor = Exception.class)
82 82 public void createComment(ProductCommentCreateReqVO createReqVO) {
83 83 // 校验评论
84   - validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
  84 + validateComment(createReqVO.getSkuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
85 85  
86 86 ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO);
87 87 productCommentMapper.insert(commentDO);
... ... @@ -108,11 +108,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
108 108 return commentDO.getId();
109 109 }
110 110  
111   - private void validateComment(Long spuId, Long userId, Long orderItemId) {
  111 + private void validateComment(Long skuId, Long userId, Long orderItemId) {
112 112 // 判断当前订单的当前商品用户是否评价过
113   - ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, spuId);
  113 + ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
114 114 if (null != exist) {
115   - throw exception(ORDER_SPU_COMMENT_EXISTS);
  115 + throw exception(COMMENT_ORDER_EXISTS);
116 116 }
117 117 }
118 118  
... ... @@ -141,23 +141,17 @@ public class ProductCommentServiceImpl implements ProductCommentService {
141 141 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
142 142 // 查询商品 id = spuId 的所有差评数量
143 143 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
144   - ).setScores(3.0); // TODO @puhui999:这里要实现下;;
  144 + );
145 145 }
146 146  
147 147 @Override
148 148 public List<AppProductCommentRespVO> getCommentList(Long spuId, Integer count) {
149   - // 校验商品 spu 是否存在
150   - // TODO @puhui 这里校验可以去掉哈。
151   - ProductSpuDO spuDO = validateSpu(spuId);
152   - return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuDO.getId(), count).getList());
  149 + return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuId, count).getList());
153 150 }
154 151  
155   - // TODO @puhui 可以放到 controller 去 convert 哈
156 152 @Override
157   - public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
158   - // TODO @puhui 可以放到 controller 去 convert 哈
159   - return ProductCommentConvert.INSTANCE.convertPage02(
160   - productCommentMapper.selectPage(pageVO, visible));
  153 + public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
  154 + return productCommentMapper.selectPage(pageVO, visible);
161 155 }
162 156  
163 157 @Override
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
... ... @@ -90,7 +90,7 @@ public interface ProductSkuService {
90 90 * @param spuIds spu 编码集合
91 91 * @return 商品 sku 集合
92 92 */
93   - List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds);
  93 + List<ProductSkuDO> getSkuListBySpuId(Collection<Long> spuIds);
94 94  
95 95 /**
96 96 * 通过 spuId 删除 sku 信息
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
... ... @@ -148,7 +148,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
148 148 }
149 149  
150 150 @Override
151   - public List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds) {
  151 + public List<ProductSkuDO> getSkuListBySpuId(Collection<Long> spuIds) {
152 152 return productSkuMapper.selectListBySpuId(spuIds);
153 153 }
154 154  
... ...
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java
... ... @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen
10 10 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
11 11 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
12 12 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
13   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
14 13 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
15 14 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
16 15 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
... ... @@ -128,7 +127,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
128 127 productCommentPageReqVO.setSpuId(spuId);
129 128 productCommentPageReqVO.setSpuName("感冒药");
130 129 productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores());
131   - productCommentPageReqVO.setReplied(Boolean.TRUE);
  130 + productCommentPageReqVO.setReplyStatus(Boolean.TRUE);
132 131  
133 132 PageResult<ProductCommentDO> commentPage = productCommentService.getCommentPage(productCommentPageReqVO);
134 133 PageResult<ProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO));
... ... @@ -138,15 +137,15 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
138 137 assertEquals(8, all.getTotal());
139 138  
140 139 // 测试获取所有商品分页评论数据
141   - PageResult<AppProductCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
  140 + PageResult<ProductCommentDO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
142 141 assertEquals(7, result1.getTotal());
143 142  
144 143 // 测试获取所有商品分页中评数据
145   - PageResult<AppProductCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
  144 + PageResult<ProductCommentDO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
146 145 assertEquals(2, result2.getTotal());
147 146  
148 147 // 测试获取指定 spuId 商品分页中评数据
149   - PageResult<AppProductCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
  148 + PageResult<ProductCommentDO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
150 149 assertEquals(2, result3.getTotal());
151 150  
152 151 // 测试分页 tab count
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
  4 +
  5 +import javax.validation.Valid;
  6 +
  7 +// TODO @puhui999:CombinationRecordApi 分成活动、记录哈
  8 +// TODO @芋艿:后面也再撸撸这几个接口
  9 +/**
  10 + * 拼团活动 API 接口
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +public interface CombinationApi {
  15 +
  16 + /**
  17 + * 创建开团记录
  18 + *
  19 + * @param reqDTO 请求 DTO
  20 + */
  21 + void createRecord(@Valid CombinationRecordReqDTO reqDTO);
  22 +
  23 + /**
  24 + * 获取开团记录状态
  25 + *
  26 + * @param userId 用户编号
  27 + * @param orderId 订单编号
  28 + */
  29 + boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
  30 +
  31 + /**
  32 + * 更新开团记录状态
  33 + *
  34 + * @param userId 用户编号
  35 + * @param orderId 订单编号
  36 + * @param status 状态值
  37 + */
  38 + void updateRecordStatus(Long userId, Long orderId, Integer status);
  39 +
  40 + /**
  41 + * 更新开团记录状态和开始时间
  42 + *
  43 + * @param userId 用户编号
  44 + * @param orderId 订单编号
  45 + * @param status 状态值
  46 + */
  47 + void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status);
  48 +
  49 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotEmpty;
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +// TODO @puhui999:CombinationRecordCreateReqDTO,这样更容易知道是创建噢
  9 +/**
  10 + * 拼团记录 Request DTO
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +@Data
  15 +public class CombinationRecordReqDTO {
  16 +
  17 + /**
  18 + * 拼团活动编号
  19 + */
  20 + @NotNull(message = "拼团活动编号不能为空")
  21 + private Long activityId;
  22 + /**
  23 + * spu 编号
  24 + */
  25 + @NotNull(message = "spu 编号不能为空")
  26 + private Long spuId;
  27 + /**
  28 + * sku 编号
  29 + */
  30 + @NotNull(message = "sku 编号不能为空")
  31 + private Long skuId;
  32 + /**
  33 + * 用户编号
  34 + */
  35 + @NotNull(message = "用户编号不能为空")
  36 + private Long userId;
  37 + /**
  38 + * 订单编号
  39 + */
  40 + @NotNull(message = "订单编号不能为空")
  41 + private Long orderId;
  42 + /**
  43 + * 团长编号
  44 + */
  45 + @NotNull(message = "团长编号不能为空")
  46 + private Long headId;
  47 + /**
  48 + * 商品名字
  49 + */
  50 + @NotEmpty(message = "商品名字不能为空")
  51 + private String spuName;
  52 + /**
  53 + * 商品图片
  54 + */
  55 + @NotEmpty(message = "商品图片不能为空")
  56 + private String picUrl;
  57 + /**
  58 + * 拼团商品单价
  59 + */
  60 + @NotNull(message = "拼团商品单价不能为空")
  61 + private Integer combinationPrice;
  62 + /**
  63 + * 用户昵称
  64 + */
  65 + @NotEmpty(message = "用户昵称不能为空")
  66 + private String nickname;
  67 + /**
  68 + * 用户头像
  69 + */
  70 + @NotEmpty(message = "用户头像不能为空")
  71 + private String avatar;
  72 + /**
  73 + * 开团状态:正在开团 拼团成功 拼团失败 TODO 等待支付
  74 + */
  75 + @NotNull(message = "开团状态不能为空")
  76 + private Integer status;
  77 +
  78 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4  
5 5 /**
6 6 * Promotion 错误码枚举类
7   - *
  7 + * <p>
8 8 * promotion 系统,使用 1-013-000-000 段
9 9 */
10 10 public interface ErrorCodeConstants {
... ... @@ -42,8 +42,7 @@ public interface ErrorCodeConstants {
42 42 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013006004, "满减送活动已关闭,不能重复关闭");
43 43 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013006005, "满减送活动已结束,不能关闭");
44 44  
45   - // ========== Price 相关 1013007000 ============
46   - ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1013007000, "支付价格计算异常,原因:价格小于等于 0");
  45 + // ========== TODO 空着 1013007000 ============
47 46  
48 47 // ========== 秒杀活动 1013008000 ==========
49 48 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在");
... ... @@ -58,5 +57,13 @@ public interface ErrorCodeConstants {
58 57 ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1013009001, "秒杀时段冲突");
59 58 ErrorCode SECKILL_TIME_EQUAL = new ErrorCode(1013009002, "秒杀时段开始时间和结束时间不能相等");
60 59 ErrorCode SECKILL_START_TIME_BEFORE_END_TIME = new ErrorCode(1013009003, "秒杀时段开始时间不能在结束时间之后");
  60 + ErrorCode SECKILL_TIME_DISABLE = new ErrorCode(1013009004, "秒杀时段已关闭");
  61 +
  62 + // ========== 拼团活动 1013010000 ==========
  63 + ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在");
  64 + ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010001, "存在商品参加了其它拼团活动");
  65 + ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改");
  66 + ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除");
  67 + ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013010004, "拼团不存在");
61 68  
62 69 }
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/combination/CombinationRecordStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.enums.combination;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 拼团状态枚举
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum CombinationRecordStatusEnum implements IntArrayValuable {
  17 +
  18 + WAITING(0, "未付款"),
  19 + IN_PROGRESS(1, "进行中"),
  20 + SUCCESS(2, "拼团成功"),
  21 + FAILED(3, "拼团失败");
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CombinationRecordStatusEnum::getStatus).toArray();
  24 +
  25 + /**
  26 + * 状态值
  27 + */
  28 + private final Integer status;
  29 + /**
  30 + * 状态名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public int[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
  5 +import org.springframework.stereotype.Service;
  6 +
  7 +import javax.annotation.Resource;
  8 +import java.time.LocalDateTime;
  9 +
  10 +/**
  11 + * 拼团活动 API 实现类
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Service
  16 +public class CombinationApiImpl implements CombinationApi {
  17 +
  18 + @Resource
  19 + private CombinationActivityService activityService;
  20 +
  21 + @Override
  22 + public void createRecord(CombinationRecordReqDTO reqDTO) {
  23 + activityService.createRecord(reqDTO);
  24 + }
  25 +
  26 + @Override
  27 + public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
  28 + return activityService.validateRecordStatusIsSuccess(userId, orderId);
  29 + }
  30 +
  31 + @Override
  32 + public void updateRecordStatus(Long userId, Long orderId, Integer status) {
  33 + activityService.updateRecordStatusByUserIdAndOrderId(userId, orderId, status);
  34 + }
  35 +
  36 + @Override
  37 + public void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status) {
  38 + activityService.updateRecordStatusAndStartTimeByUserIdAndOrderId(userId, orderId, status, LocalDateTime.now());
  39 + }
  40 +
  41 +
  42 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  8 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  9 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  10 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.*;
  11 +import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
  12 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  13 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  14 +import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import org.springframework.security.access.prepost.PreAuthorize;
  19 +import org.springframework.validation.annotation.Validated;
  20 +import org.springframework.web.bind.annotation.*;
  21 +
  22 +import javax.annotation.Resource;
  23 +import javax.servlet.http.HttpServletResponse;
  24 +import javax.validation.Valid;
  25 +import java.io.IOException;
  26 +import java.util.Collection;
  27 +import java.util.List;
  28 +import java.util.Set;
  29 +
  30 +import static cn.hutool.core.collection.CollectionUtil.newArrayList;
  31 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  32 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  33 +
  34 +@Tag(name = "管理后台 - 拼团活动")
  35 +@RestController
  36 +@RequestMapping("/promotion/combination-activity")
  37 +@Validated
  38 +public class CombinationActivityController {
  39 +
  40 + @Resource
  41 + private CombinationActivityService combinationActivityService;
  42 + @Resource
  43 + private ProductSpuApi spuApi;
  44 +
  45 + @PostMapping("/create")
  46 + @Operation(summary = "创建拼团活动")
  47 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:create')")
  48 + public CommonResult<Long> createCombinationActivity(@Valid @RequestBody CombinationActivityCreateReqVO createReqVO) {
  49 + return success(combinationActivityService.createCombinationActivity(createReqVO));
  50 + }
  51 +
  52 + @PutMapping("/update")
  53 + @Operation(summary = "更新拼团活动")
  54 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:update')")
  55 + public CommonResult<Boolean> updateCombinationActivity(@Valid @RequestBody CombinationActivityUpdateReqVO updateReqVO) {
  56 + combinationActivityService.updateCombinationActivity(updateReqVO);
  57 + return success(true);
  58 + }
  59 +
  60 + @DeleteMapping("/delete")
  61 + @Operation(summary = "删除拼团活动")
  62 + @Parameter(name = "id", description = "编号", required = true)
  63 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:delete')")
  64 + public CommonResult<Boolean> deleteCombinationActivity(@RequestParam("id") Long id) {
  65 + combinationActivityService.deleteCombinationActivity(id);
  66 + return success(true);
  67 + }
  68 +
  69 + @GetMapping("/get")
  70 + @Operation(summary = "获得拼团活动")
  71 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  72 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
  73 + public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
  74 + CombinationActivityDO activity = combinationActivityService.getCombinationActivity(id);
  75 + List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(newArrayList(id));
  76 + return success(CombinationActivityConvert.INSTANCE.convert(activity, products));
  77 + }
  78 +
  79 + @GetMapping("/list")
  80 + @Operation(summary = "获得拼团活动列表")
  81 + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
  82 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
  83 + public CommonResult<List<CombinationActivityRespVO>> getCombinationActivityList(@RequestParam("ids") Collection<Long> ids) {
  84 + List<CombinationActivityDO> list = combinationActivityService.getCombinationActivityList(ids);
  85 + return success(CombinationActivityConvert.INSTANCE.convertList(list));
  86 + }
  87 +
  88 + @GetMapping("/page")
  89 + @Operation(summary = "获得拼团活动分页")
  90 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
  91 + public CommonResult<PageResult<CombinationActivityRespVO>> getCombinationActivityPage(
  92 + @Valid CombinationActivityPageReqVO pageVO) {
  93 + PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
  94 + // TODO @puhui999:可以不一定 aIds,直接批量查询结果出来;下面也是类似;
  95 + Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getId);
  96 + List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(aIds);
  97 + Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getSpuId);
  98 + List<ProductSpuRespDTO> spus = spuApi.getSpuList(spuIds);
  99 + return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
  100 + }
  101 +
  102 + @GetMapping("/export-excel")
  103 + @Operation(summary = "导出拼团活动 Excel")
  104 + @PreAuthorize("@ss.hasPermission('promotion:combination-activity:export')")
  105 + @OperateLog(type = EXPORT)
  106 + public void exportCombinationActivityExcel(@Valid CombinationActivityExportReqVO exportReqVO,
  107 + HttpServletResponse response) throws IOException {
  108 + List<CombinationActivityDO> list = combinationActivityService.getCombinationActivityList(exportReqVO);
  109 + // 导出 Excel
  110 + List<CombinationActivityExcelVO> datas = CombinationActivityConvert.INSTANCE.convertList02(list);
  111 + ExcelUtils.write(response, "拼团活动.xls", "数据", CombinationActivityExcelVO.class, datas);
  112 + }
  113 +
  114 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 + * 拼团活动 Base VO,提供给添加、修改、详细的子 VO 使用
  14 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 + */
  16 +@Data
  17 +public class CombinationActivityBaseVO {
  18 +
  19 + @Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
  20 + @NotNull(message = "拼团名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "商品 SPU 编号,关联 ProductSpuDO 的 id", example = "[1,2,3]")
  24 + @NotNull(message = "拼团商品不能为空")
  25 + private Long spuId;
  26 +
  27 + @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
  28 + @NotNull(message = "总限购数量不能为空")
  29 + private Integer totalLimitCount;
  30 +
  31 + @Schema(description = "单次限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "28265")
  32 + @NotNull(message = "单次限购数量不能为空")
  33 + private Integer singleLimitCount;
  34 +
  35 + // TODO @puhui999:是不是弄成 2 个字段会好点哈。开始、结束
  36 + @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
  37 + @NotNull(message = "活动时间不能为空")
  38 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  39 + private LocalDateTime[] activityTime;
  40 +
  41 + @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
  42 + @NotNull(message = "开团人数不能为空")
  43 + private Integer userSize;
  44 +
  45 + @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED)
  46 + @NotNull(message = "限制时长不能为空")
  47 + private Integer limitDuration;
  48 +
  49 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - 拼团活动创建 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
  17 +
  18 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + @Valid
  20 + private List<CombinationProductCreateReqVO> products;
  21 +
  22 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +// TODO @puhui999:如无必要,导出都可以删除哈
  11 +/**
  12 + * 拼团活动 Excel VO
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Data
  17 +public class CombinationActivityExcelVO {
  18 +
  19 + @ExcelProperty("活动编号")
  20 + private Long id;
  21 +
  22 + @ExcelProperty("拼团名称")
  23 + private String name;
  24 +
  25 + @ExcelProperty("商品 SPU 编号关联 ProductSpuDO 的 id")
  26 + private Long spuId;
  27 +
  28 + @ExcelProperty("总限购数量")
  29 + private Integer totalLimitCount;
  30 +
  31 + @ExcelProperty("单次限购数量")
  32 + private Integer singleLimitCount;
  33 +
  34 + @ExcelProperty("开始时间")
  35 + private LocalDateTime startTime;
  36 +
  37 + @ExcelProperty("结束时间")
  38 + private LocalDateTime endTime;
  39 +
  40 + @ExcelProperty("开团人数")
  41 + private Integer userSize;
  42 +
  43 + @ExcelProperty("开团组数")
  44 + private Integer totalNum;
  45 +
  46 + @ExcelProperty("成团组数")
  47 + private Integer successNum;
  48 +
  49 + @ExcelProperty("参与人数")
  50 + private Integer orderUserCount;
  51 +
  52 + @ExcelProperty("虚拟成团")
  53 + private Integer virtualGroup;
  54 +
  55 + @ExcelProperty(value = "活动状态:0开启 1关闭", converter = DictConvert.class)
  56 + @DictFormat("common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
  57 + private Integer status;
  58 +
  59 + @ExcelProperty("限制时长(小时)")
  60 + private Integer limitDuration;
  61 +
  62 + @ExcelProperty("创建时间")
  63 + private LocalDateTime createTime;
  64 +
  65 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +// TODO @puhui999:如无必要,导出都可以删除哈
  12 +@Schema(description = "管理后台 - 拼团活动 Excel 导出 Request VO,参数和 CombinationActivityPageReqVO 是一致的")
  13 +@Data
  14 +public class CombinationActivityExportReqVO {
  15 +
  16 + @Schema(description = "拼团名称", example = "赵六")
  17 + private String name;
  18 +
  19 + @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "14016")
  20 + private Long spuId;
  21 +
  22 + @Schema(description = "总限购数量", example = "16218")
  23 + private Integer totalLimitCount;
  24 +
  25 + @Schema(description = "单次限购数量", example = "28265")
  26 + private Integer singleLimitCount;
  27 +
  28 + @Schema(description = "开始时间")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] startTime;
  31 +
  32 + @Schema(description = "结束时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] endTime;
  35 +
  36 + @Schema(description = "开团人数")
  37 + private Integer userSize;
  38 +
  39 + @Schema(description = "开团组数")
  40 + private Integer totalNum;
  41 +
  42 + @Schema(description = "成团组数")
  43 + private Integer successNum;
  44 +
  45 + @Schema(description = "参与人数", example = "25222")
  46 + private Integer orderUserCount;
  47 +
  48 + @Schema(description = "虚拟成团")
  49 + private Integer virtualGroup;
  50 +
  51 + @Schema(description = "活动状态:0开启 1关闭", example = "0")
  52 + private Integer status;
  53 +
  54 + @Schema(description = "限制时长(小时)")
  55 + private Integer limitDuration;
  56 +
  57 + @Schema(description = "创建时间")
  58 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  59 + private LocalDateTime[] createTime;
  60 +
  61 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 拼团活动分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class CombinationActivityPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "拼团名称", example = "赵六")
  21 + private String name;
  22 +
  23 + @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "14016")
  24 + private Long spuId;
  25 +
  26 + @Schema(description = "总限购数量", example = "16218")
  27 + private Integer totalLimitCount;
  28 +
  29 + @Schema(description = "单次限购数量", example = "28265")
  30 + private Integer singleLimitCount;
  31 +
  32 + @Schema(description = "开始时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] startTime;
  35 +
  36 + @Schema(description = "结束时间")
  37 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  38 + private LocalDateTime[] endTime;
  39 +
  40 + @Schema(description = "开团人数")
  41 + private Integer userSize;
  42 +
  43 + @Schema(description = "开团组数")
  44 + private Integer totalNum;
  45 +
  46 + @Schema(description = "成团组数")
  47 + private Integer successNum;
  48 +
  49 + @Schema(description = "参与人数", example = "25222")
  50 + private Integer orderUserCount;
  51 +
  52 + @Schema(description = "虚拟成团")
  53 + private Integer virtualGroup;
  54 +
  55 + @Schema(description = "活动状态:0开启 1关闭", example = "0")
  56 + private Integer status;
  57 +
  58 + @Schema(description = "限制时长(小时)")
  59 + private Integer limitDuration;
  60 +
  61 + @Schema(description = "创建时间")
  62 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  63 + private LocalDateTime[] createTime;
  64 +
  65 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +@Schema(description = "管理后台 - 拼团活动 Response VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class CombinationActivityRespVO extends CombinationActivityBaseVO {
  19 +
  20 + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
  21 + private String spuName;
  22 +
  23 + @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
  24 + private String picUrl;
  25 +
  26 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  27 + private Long id;
  28 +
  29 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + private LocalDateTime createTime;
  31 +
  32 + @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotNull(message = "开团人数不能为空")
  34 + private Integer userSize;
  35 +
  36 + @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + @NotNull(message = "开团组数不能为空")
  38 + private Integer totalNum;
  39 +
  40 + @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + @NotNull(message = "成团组数不能为空")
  42 + private Integer successNum;
  43 +
  44 + @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)
  45 + @NotNull(message = "虚拟成团不能为空")
  46 + private Integer virtualGroup;
  47 +
  48 + @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  49 + @NotNull(message = "活动状态不能为空")
  50 + private Integer status;
  51 +
  52 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  53 + @Valid
  54 + private List<CombinationProductRespVO> products;
  55 +
  56 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - 拼团活动更新 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
  18 +
  19 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  20 + @NotNull(message = "活动编号不能为空")
  21 + private Long id;
  22 +
  23 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @Valid
  25 + private List<CombinationProductUpdateReqVO> products;
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 + * 拼团商品 Base VO,提供给添加、修改、详细的子 VO 使用
  10 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 + */
  12 +@Data
  13 +public class CombinationProductBaseVO {
  14 +
  15 + @Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
  16 + @NotNull(message = "商品 spuId 不能为空")
  17 + private Long spuId;
  18 +
  19 + @Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
  20 + @NotNull(message = "商品 skuId 不能为空")
  21 + private Long skuId;
  22 +
  23 + @Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
  24 + @NotNull(message = "拼团价格,单位分不能为空")
  25 + private Integer activePrice;
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 拼团商品创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class CombinationProductCreateReqVO extends CombinationProductBaseVO {
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelProperty;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +// TODO @puhui999:可以考虑删除 excel 导出哈
  9 +/**
  10 + * 拼团商品 Excel VO
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +@Data
  15 +public class CombinationProductExcelVO {
  16 +
  17 + @ExcelProperty("编号")
  18 + private Long id;
  19 +
  20 + @ExcelProperty("拼团活动编号")
  21 + private Long activityId;
  22 +
  23 + @ExcelProperty("商品 SPU 编号")
  24 + private Long spuId;
  25 +
  26 + @ExcelProperty("商品 SKU 编号")
  27 + private Long skuId;
  28 +
  29 + @ExcelProperty("拼团商品状态")
  30 + private Integer activityStatus;
  31 +
  32 + @ExcelProperty("活动开始时间点")
  33 + private LocalDateTime activityStartTime;
  34 +
  35 + @ExcelProperty("活动结束时间点")
  36 + private LocalDateTime activityEndTime;
  37 +
  38 + @ExcelProperty("拼团价格,单位分")
  39 + private Integer activePrice;
  40 +
  41 + @ExcelProperty("创建时间")
  42 + private LocalDateTime createTime;
  43 +
  44 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +// TODO @puhui999:可以考虑删除 excel 导出哈
  12 +@Schema(description = "管理后台 - 拼团商品 Excel 导出 Request VO,参数和 CombinationProductPageReqVO 是一致的")
  13 +@Data
  14 +public class CombinationProductExportReqVO {
  15 +
  16 + @Schema(description = "拼团活动编号", example = "6829")
  17 + private Long activityId;
  18 +
  19 + @Schema(description = "商品 SPU 编号", example = "18731")
  20 + private Long spuId;
  21 +
  22 + @Schema(description = "商品 SKU 编号", example = "31675")
  23 + private Long skuId;
  24 +
  25 + @Schema(description = "拼团商品状态", example = "2")
  26 + private Integer activityStatus;
  27 +
  28 + @Schema(description = "活动开始时间点")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] activityStartTime;
  31 +
  32 + @Schema(description = "活动结束时间点")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] activityEndTime;
  35 +
  36 + @Schema(description = "拼团价格,单位分", example = "27682")
  37 + private Integer activePrice;
  38 +
  39 + @Schema(description = "创建时间")
  40 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  41 + private LocalDateTime[] createTime;
  42 +
  43 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 拼团商品分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class CombinationProductPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "拼团活动编号", example = "6829")
  21 + private Long activityId;
  22 +
  23 + @Schema(description = "商品 SPU 编号", example = "18731")
  24 + private Long spuId;
  25 +
  26 + @Schema(description = "商品 SKU 编号", example = "31675")
  27 + private Long skuId;
  28 +
  29 + @Schema(description = "拼团商品状态", example = "2")
  30 + private Integer activityStatus;
  31 +
  32 + @Schema(description = "活动开始时间点")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] activityStartTime;
  35 +
  36 + @Schema(description = "活动结束时间点")
  37 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  38 + private LocalDateTime[] activityEndTime;
  39 +
  40 + @Schema(description = "拼团价格,单位分", example = "27682")
  41 + private Integer activePrice;
  42 +
  43 + @Schema(description = "创建时间")
  44 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  45 + private LocalDateTime[] createTime;
  46 +
  47 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 拼团商品 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class CombinationProductRespVO extends CombinationProductBaseVO {
  15 +
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 拼团商品更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class CombinationProductUpdateReqVO extends CombinationProductBaseVO {
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
... ... @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  7 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 8 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*;
6 9 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
7 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
... ... @@ -18,6 +21,7 @@ import javax.annotation.Resource;
18 21 import javax.validation.Valid;
19 22 import java.util.Collection;
20 23 import java.util.List;
  24 +import java.util.Set;
21 25  
22 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
23 27  
... ... @@ -29,6 +33,8 @@ public class SeckillActivityController {
29 33  
30 34 @Resource
31 35 private SeckillActivityService seckillActivityService;
  36 + @Resource
  37 + private ProductSpuApi spuApi;
32 38  
33 39 @PostMapping("/create")
34 40 @Operation(summary = "创建秒杀活动")
... ... @@ -69,11 +75,8 @@ public class SeckillActivityController {
69 75 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
70 76 public CommonResult<SeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
71 77 SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id);
72   - if (seckillActivity == null) {
73   - return success(null);
74   - }
75   - List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id);
76   - return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity,seckillProducts));
  78 + List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id);
  79 + return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity, seckillProducts));
77 80 }
78 81  
79 82 @GetMapping("/list")
... ... @@ -90,7 +93,11 @@ public class SeckillActivityController {
90 93 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
91 94 public CommonResult<PageResult<SeckillActivityRespVO>> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) {
92 95 PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(pageVO);
93   - return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult));
  96 + Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), SeckillActivityDO::getId);
  97 + List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(aIds);
  98 + Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), SeckillActivityDO::getSpuId);
  99 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(spuIds);
  100 + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, seckillProducts, spuList));
94 101 }
95 102  
96 103 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
... ... @@ -19,11 +19,6 @@ import java.util.List;
19 19  
20 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 21  
22   -/**
23   - * 管理后台 - 秒杀时段相关接口
24   - *
25   - * @author HUIHUI
26   - */
27 22 @Tag(name = "管理后台 - 秒杀时段")
28 23 @RestController
29 24 @RequestMapping("/promotion/seckill-config")
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
... ... @@ -20,10 +20,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
20 20 @Data
21 21 public class SeckillActivityBaseVO {
22 22  
23   - // TODO @puhui999:对应单 spuId 哈
24 23 @Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
25 24 @NotNull(message = "秒杀活动商品不能为空")
26   - private List<Long> spuIds;
  25 + private Long spuId;
27 26  
28 27 @Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
29 28 @NotNull(message = "秒杀活动名称不能为空")
... ... @@ -56,8 +55,4 @@ public class SeckillActivityBaseVO {
56 55 @Schema(description = "单次限够数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "31683")
57 56 private Integer singleLimitCount;
58 57  
59   - // TODO @puhui999:这个应该是计算出来的字段,只返回,create 和 update 不用哈
60   - @Schema(description = "秒杀总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
61   - private Integer totalStock;
62   -
63 58 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java
... ... @@ -6,26 +6,46 @@ import lombok.Data;
6 6 import lombok.EqualsAndHashCode;
7 7 import lombok.ToString;
8 8  
  9 +import java.time.LocalDateTime;
9 10 import java.util.List;
10 11  
11   -/**
12   - * 管理后台 - 秒杀活动 Response VO
13   - *
14   - * @author HUIHUI
15   - */
16 12 @Schema(description = "管理后台 - 秒杀活动 Response VO")
17 13 @Data
18 14 @EqualsAndHashCode(callSuper = true)
19 15 @ToString(callSuper = true)
20 16 public class SeckillActivityRespVO extends SeckillActivityBaseVO {
21 17  
  18 + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
  19 + private String spuName;
  20 +
  21 + @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
  22 + private String picUrl;
  23 +
22 24 @Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
23 25 private Long id;
24 26  
25 27 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
26   - private List<SeckillProductRespVO> products; // TODO puhui: 考虑是否去除
  28 + private List<SeckillProductRespVO> products;
27 29  
28 30 @Schema(description = "活动状态 开启:0 禁用:1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
29 31 private Integer status;
30 32  
  33 + @Schema(description = "订单实付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22354")
  34 + private Integer totalPrice;
  35 +
  36 + @Schema(description = "秒杀库存", example = "10")
  37 + private Integer stock;
  38 +
  39 + @Schema(description = "秒杀总库存", example = "20")
  40 + private Integer totalStock;
  41 +
  42 + @Schema(description = "新增订单数", example = "20")
  43 + private Integer orderCount;
  44 +
  45 + @Schema(description = "付款人数", example = "20")
  46 + private Integer userCount;
  47 +
  48 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  49 + private LocalDateTime createTime;
  50 +
31 51 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java
1 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
2 2  
  3 +import com.fasterxml.jackson.annotation.JsonIgnore;
3 4 import io.swagger.v3.oas.annotations.media.Schema;
4 5 import lombok.Data;
5 6  
  7 +import javax.validation.constraints.AssertTrue;
6 8 import javax.validation.constraints.NotNull;
  9 +import java.time.LocalTime;
  10 +import java.util.List;
7 11  
8 12 /**
9 13 * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用
... ... @@ -26,12 +30,24 @@ public class SeckillConfigBaseVO {
26 30 @NotNull(message = "结束时间点不能为空")
27 31 private String endTime;
28 32  
29   - @Schema(description = "秒杀主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
30   - @NotNull(message = "秒杀主图不能为空")
31   - private String picUrl;
  33 + @Schema(description = "秒杀轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
  34 + @NotNull(message = "秒杀轮播图不能为空")
  35 + private List<String> sliderPicUrls;
32 36  
33 37 @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
34 38 @NotNull(message = "状态不能为空")
35 39 private Integer status;
36 40  
  41 + @AssertTrue(message = "秒杀时段开始时间和结束时间不能相等")
  42 + @JsonIgnore
  43 + public boolean isValidStartTimeValid() {
  44 + return !LocalTime.parse(startTime).equals(LocalTime.parse(endTime));
  45 + }
  46 +
  47 + @AssertTrue(message = "秒杀时段开始时间不能在结束时间之后")
  48 + @JsonIgnore
  49 + public boolean isValidEndTimeValid() {
  50 + return !LocalTime.parse(startTime).isAfter(LocalTime.parse(endTime));
  51 + }
  52 +
37 53 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java
... ... @@ -6,12 +6,6 @@ import lombok.Data;
6 6 import lombok.EqualsAndHashCode;
7 7 import lombok.ToString;
8 8  
9   -// TODO @puhui:VO 上不写注释,已经有注解啦。
10   -/**
11   - * 管理后台 - 秒杀时段分页 Request VO
12   - *
13   - * @author HUIHUI
14   - */
15 9 @Schema(description = "管理后台 - 秒杀时段分页 Request VO")
16 10 @Data
17 11 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
... ... @@ -14,11 +14,6 @@ import javax.validation.constraints.NotNull;
14 14 @Data
15 15 public class SeckillProductBaseVO {
16 16  
17   - // TODO @puhui:spuId 不用传递;因为一个秒杀活动只对应一个 SPU 哈;
18   - @Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
19   - @NotNull(message = "商品spu_id不能为空")
20   - private Long spuId;
21   -
22 17 @Schema(description = "商品sku_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
23 18 @NotNull(message = "商品sku_id不能为空")
24 19 private Long skuId;
... ... @@ -31,5 +26,4 @@ public class SeckillProductBaseVO {
31 26 @NotNull(message = "秒杀库存不能为空")
32 27 private Integer stock;
33 28  
34   -
35 29 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductCreateReqVO.java
1 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
2 2  
3   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
4   -import lombok.*;
5   -import java.util.*;
6 3 import io.swagger.v3.oas.annotations.media.Schema;
7   -import javax.validation.constraints.*;
8   -
9   -/**
10   - * 管理后台 - 秒杀参与商品创建 Request VO
11   - *
12   - * @author HUIHUI
13   - */
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
14 7 @Schema(description = "管理后台 - 秒杀参与商品创建 Request VO")
15 8 @Data
16 9 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductRespVO.java
1 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.*;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
5 8 import java.time.LocalDateTime;
6 9  
7   -/**
8   - * 管理后台 - 秒杀参与商品 Response VO
9   - *
10   - * @author HUIHUI
11   - */
12 10 @Schema(description = "管理后台 - 秒杀参与商品 Response VO")
13 11 @Data
14 12 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductUpdateReqVO.java
1 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.*;
5   -import javax.validation.constraints.*;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
6 7  
7   -/**
8   - * 管理后台 - 秒杀参与商品更新 Request VO
9   - *
10   - * @author HUIHUI
11   - */
12 8 @Schema(description = "管理后台 - 秒杀参与商品更新 Request VO")
13 9 @Data
14 10 @EqualsAndHashCode(callSuper = true)
15 11 @ToString(callSuper = true)
16 12 public class SeckillProductUpdateReqVO extends SeckillProductBaseVO {
17 13  
18   - @Schema(description = "秒杀参与商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "256")
19   - @NotNull(message = "秒杀参与商品编号不能为空")
20   - private Long id;
21   -
22 14 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.convert.combination;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExcelVO;
  9 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
  10 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
  13 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
  14 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  15 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  16 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationRecordDO;
  17 +import org.mapstruct.Mapper;
  18 +import org.mapstruct.Mapping;
  19 +import org.mapstruct.Mappings;
  20 +import org.mapstruct.Named;
  21 +import org.mapstruct.factory.Mappers;
  22 +
  23 +import java.time.LocalDateTime;
  24 +import java.util.ArrayList;
  25 +import java.util.List;
  26 +import java.util.Map;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  29 +
  30 +/**
  31 + * 拼团活动 Convert
  32 + *
  33 + * @author HUIHUI
  34 + */
  35 +@Mapper
  36 +public interface CombinationActivityConvert {
  37 +
  38 + CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class);
  39 +
  40 + @Mappings({
  41 + @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
  42 + @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
  43 + })
  44 + CombinationActivityDO convert(CombinationActivityCreateReqVO bean);
  45 +
  46 + @Mappings({
  47 + @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
  48 + @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
  49 + })
  50 + CombinationActivityDO convert(CombinationActivityUpdateReqVO bean);
  51 +
  52 + @Named("mergeTime")
  53 + default LocalDateTime[] mergeTime(LocalDateTime startTime, LocalDateTime endTime) {
  54 + // TODO 有点怪第一次这样写 hh
  55 + LocalDateTime[] localDateTime = new LocalDateTime[2];
  56 + localDateTime[0] = startTime;
  57 + localDateTime[1] = endTime;
  58 + return localDateTime;
  59 + }
  60 +
  61 + @Mappings({
  62 + @Mapping(target = "activityTime", expression = "java(mergeTime(bean.getStartTime(),bean.getEndTime()))")
  63 + })
  64 + CombinationActivityRespVO convert(CombinationActivityDO bean);
  65 +
  66 + CombinationProductRespVO convert(CombinationProductDO bean);
  67 +
  68 + default CombinationActivityRespVO convert(CombinationActivityDO bean, List<CombinationProductDO> productDOs) {
  69 + CombinationActivityRespVO respVO = convert(bean);
  70 + respVO.setProducts(convertList2(productDOs));
  71 + return respVO;
  72 + }
  73 +
  74 + List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list);
  75 +
  76 + PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page);
  77 +
  78 + default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page,
  79 + List<CombinationProductDO> productList,
  80 + List<ProductSpuRespDTO> spuList) {
  81 + // TODO @puhui999:c -> c 可以去掉哈
  82 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId, c -> c);
  83 + PageResult<CombinationActivityRespVO> pageResult = convertPage(page);
  84 + pageResult.getList().forEach(item -> {
  85 + // TODO @puhui999:最好 MapUtils.findAndThen,万一没找到呢,啊哈哈。
  86 + item.setSpuName(spuMap.get(item.getSpuId()).getName());
  87 + item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl());
  88 + item.setProducts(convertList2(productList));
  89 + });
  90 + return pageResult;
  91 + }
  92 +
  93 + List<CombinationProductRespVO> convertList2(List<CombinationProductDO> productDOs);
  94 +
  95 + List<CombinationActivityExcelVO> convertList02(List<CombinationActivityDO> list);
  96 +
  97 + @Mappings({
  98 + @Mapping(target = "id", ignore = true),
  99 + @Mapping(target = "activityId", source = "activityDO.id"),
  100 + @Mapping(target = "spuId", source = "activityDO.spuId"),
  101 + @Mapping(target = "skuId", source = "vo.skuId"),
  102 + @Mapping(target = "activePrice", source = "vo.activePrice"),
  103 + @Mapping(target = "activityStartTime", source = "activityDO.startTime"),
  104 + @Mapping(target = "activityEndTime", source = "activityDO.endTime")
  105 + })
  106 + CombinationProductDO convert(CombinationActivityDO activityDO, CombinationProductBaseVO vo);
  107 +
  108 + default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<? extends CombinationProductBaseVO> products) {
  109 + List<CombinationProductDO> list = new ArrayList<>();
  110 + products.forEach(sku -> {
  111 + CombinationProductDO productDO = convert(activityDO, sku);
  112 + // TODO 状态设置
  113 + productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
  114 + list.add(productDO);
  115 + });
  116 + return list;
  117 + }
  118 +
  119 + // TODO @puhui999:这个方法的参数,调整成 productDOs、vos、activityDO;因为 productDOs 是主角;
  120 + // 然后,这个方法,感觉不是为了 convert,而是为了补全;
  121 + default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO,
  122 + List<CombinationProductUpdateReqVO> vos,
  123 + List<CombinationProductDO> productDOs) {
  124 + Map<Long, Long> longMap = convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
  125 + List<CombinationProductDO> list = new ArrayList<>();
  126 + vos.forEach(sku -> {
  127 + CombinationProductDO productDO = convert(activityDO, sku);
  128 + productDO.setId(longMap.get(sku.getSkuId()));
  129 + // TODO @puhui999:是是不是用 activityDO 的状态;
  130 + productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
  131 + list.add(productDO);
  132 + });
  133 + return list;
  134 + }
  135 +
  136 + CombinationRecordDO convert(CombinationRecordReqDTO reqDTO);
  137 +
  138 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
1 1 package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
2 2  
3   -import cn.hutool.core.util.ObjectUtil;
4 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
6 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
7 8 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
8 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
9 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
10   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
  13 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
11 14 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
12 15 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
13 16 import org.mapstruct.Mapper;
  17 +import org.mapstruct.Mapping;
  18 +import org.mapstruct.Mappings;
14 19 import org.mapstruct.factory.Mappers;
15 20  
16 21 import java.util.ArrayList;
17 22 import java.util.List;
  23 +import java.util.Map;
18 24  
19 25 /**
20 26 * 秒杀活动 Convert
... ... @@ -26,8 +32,6 @@ public interface SeckillActivityConvert {
26 32  
27 33 SeckillActivityConvert INSTANCE = Mappers.getMapper(SeckillActivityConvert.class);
28 34  
29   - SeckillProductDO convert(SeckillProductCreateReqVO product);
30   -
31 35 SeckillActivityDO convert(SeckillActivityCreateReqVO bean);
32 36  
33 37 SeckillActivityDO convert(SeckillActivityUpdateReqVO bean);
... ... @@ -38,53 +42,61 @@ public interface SeckillActivityConvert {
38 42  
39 43 PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
40 44  
41   - SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts);
42   -
43   -
44   - /**
45   - * 比较两个秒杀商品对象是否相等
46   - *
47   - * @param productDO 数据库中的商品
48   - * @param productVO 前端传入的商品
49   - * @return 是否匹配
50   - */
51   - default boolean isEquals(SeckillProductDO productDO, SeckillProductCreateReqVO productVO) {
52   - return ObjectUtil.equals(productDO.getSpuId(), 1) // TODO puhui:再看看
53   - && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
54   - && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
55   - //&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
56   - //&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
  45 + default PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page, List<SeckillProductDO> seckillProducts, List<ProductSpuRespDTO> spuList) {
  46 + Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId, c -> c);
  47 + PageResult<SeckillActivityRespVO> pageResult = convertPage(page);
  48 + pageResult.getList().forEach(item -> {
  49 + item.setSpuName(spuMap.get(item.getSpuId()).getName());
  50 + item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl());
  51 + item.setProducts(convertList2(seckillProducts));
  52 + });
  53 + return pageResult;
57 54 }
58 55  
59   - /**
60   - * 比较两个秒杀商品对象是否相等
61   - *
62   - * @param productDO 商品1
63   - * @param productVO 商品2
64   - * @return 是否匹配
65   - */
66   - default boolean isEquals(SeckillProductDO productDO, SeckillProductDO productVO) {
67   - return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
68   - && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
69   - && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
70   - //&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
71   - //&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
  56 + SeckillActivityDetailRespVO convert1(SeckillActivityDO seckillActivity);
  57 +
  58 + default SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts) {
  59 + SeckillActivityDetailRespVO respVO = convert1(seckillActivity);
  60 + respVO.setProducts(convertList2(seckillProducts));
  61 + return respVO;
72 62 }
73 63  
74   - default List<SeckillProductDO> convertList(SeckillActivityDO seckillActivity, List<SeckillProductCreateReqVO> products) {
  64 + @Mappings({
  65 + @Mapping(target = "id", ignore = true),
  66 + @Mapping(target = "activityId", source = "activityDO.id"),
  67 + @Mapping(target = "configIds", source = "activityDO.configIds"),
  68 + @Mapping(target = "spuId", source = "activityDO.spuId"),
  69 + @Mapping(target = "skuId", source = "vo.skuId"),
  70 + @Mapping(target = "seckillPrice", source = "vo.seckillPrice"),
  71 + @Mapping(target = "stock", source = "vo.stock"),
  72 + @Mapping(target = "activityStartTime", source = "activityDO.startTime"),
  73 + @Mapping(target = "activityEndTime", source = "activityDO.endTime")
  74 + })
  75 + SeckillProductDO convert(SeckillActivityDO activityDO, SeckillProductBaseVO vo);
  76 +
  77 + default List<SeckillProductDO> convertList(SeckillActivityDO activityDO, List<? extends SeckillProductBaseVO> products) {
75 78 List<SeckillProductDO> list = new ArrayList<>();
76 79 products.forEach(sku -> {
77   - SeckillProductDO productDO = new SeckillProductDO();
78   - productDO.setActivityId(seckillActivity.getId());
79   - productDO.setConfigIds(seckillActivity.getConfigIds());
80   - productDO.setSpuId(sku.getSpuId());
81   - productDO.setSkuId(sku.getSkuId());
82   - productDO.setSeckillPrice(sku.getSeckillPrice());
83   - productDO.setStock(sku.getStock());
  80 + SeckillProductDO productDO = convert(activityDO, sku);
  81 + productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
  82 + list.add(productDO);
  83 + });
  84 + return list;
  85 + }
  86 +
  87 + // TODO @puhui999:同拼团那个 convert 想通的情况哈。
  88 + default List<SeckillProductDO> convertList1(SeckillActivityDO activityDO, List<SeckillProductUpdateReqVO> vos, List<SeckillProductDO> productDOs) {
  89 + Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, SeckillProductDO::getSkuId, SeckillProductDO::getId);
  90 + List<SeckillProductDO> list = new ArrayList<>();
  91 + vos.forEach(sku -> {
  92 + SeckillProductDO productDO = convert(activityDO, sku);
  93 + productDO.setId(longMap.get(sku.getSkuId()));
84 94 productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
85   - productDO.setActivityStartTime(seckillActivity.getStartTime());
86   - productDO.setActivityEndTime(seckillActivity.getEndTime());
  95 + list.add(productDO);
87 96 });
88 97 return list;
89 98 }
  99 +
  100 + List<SeckillProductRespVO> convertList2(List<SeckillProductDO> productDOs);
  101 +
90 102 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +// TODO @puhui999:是不是应该在 combination 哈?
  13 +/**
  14 + * 拼团活动 DO
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +@TableName("promotion_combination_activity")
  19 +@KeySequence("promotion_combination_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class CombinationActivityDO extends BaseDO {
  27 +
  28 + /**
  29 + * 活动编号
  30 + */
  31 + @TableId
  32 + private Long id;
  33 + /**
  34 + * 拼团名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 商品 SPU 编号
  39 + *
  40 + * 关联 ProductSpuDO 的 id
  41 + */
  42 + private Long spuId;
  43 + /**
  44 + * 总限购数量
  45 + */
  46 + private Integer totalLimitCount;
  47 + /**
  48 + * 单次限购数量
  49 + */
  50 + private Integer singleLimitCount;
  51 + /**
  52 + * 开始时间
  53 + */
  54 + private LocalDateTime startTime;
  55 + /**
  56 + * 结束时间
  57 + */
  58 + private LocalDateTime endTime;
  59 + /**
  60 + * 几人团
  61 + */
  62 + private Integer userSize;
  63 + /**
  64 + * 开团组数
  65 + */
  66 + private Integer totalNum;
  67 + /**
  68 + * 成团组数
  69 + */
  70 + private Integer successNum;
  71 + /**
  72 + * 参与人数
  73 + */
  74 + private Integer orderUserCount;
  75 + /**
  76 + * 虚拟成团
  77 + */
  78 + private Integer virtualGroup;
  79 + /**
  80 + * 活动状态:0开启 1关闭
  81 + *
  82 + * 枚举 {@link CommonStatusEnum}
  83 + */
  84 + private Integer status;
  85 + /**
  86 + * 限制时长(小时)
  87 + */
  88 + private Integer limitDuration;
  89 +
  90 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationProductDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 拼团商品 DO
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@TableName("promotion_combination_product")
  17 +@KeySequence("promotion_combination_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class CombinationProductDO extends BaseDO {
  25 +
  26 + /**
  27 + * 编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 拼团活动编号
  33 + */
  34 + private Long activityId;
  35 + /**
  36 + * 商品 SPU 编号
  37 + */
  38 + private Long spuId;
  39 + /**
  40 + * 商品 SKU 编号
  41 + */
  42 + private Long skuId;
  43 + /**
  44 + * 拼团商品状态
  45 + */
  46 + private Integer activityStatus;
  47 + /**
  48 + * 活动开始时间点
  49 + */
  50 + private LocalDateTime activityStartTime;
  51 + /**
  52 + * 活动结束时间点
  53 + */
  54 + private LocalDateTime activityEndTime;
  55 + /**
  56 + * 拼团价格,单位分
  57 + */
  58 + private Integer activePrice;
  59 +
  60 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationRecordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +/**
  13 + * 拼团记录 DO
  14 + *
  15 + * @author HUIHUI
  16 + */
  17 +@TableName("promotion_combination_record")
  18 +@KeySequence("promotion_combination_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class CombinationRecordDO extends BaseDO {
  26 +
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 拼团活动编号
  31 + */
  32 + private Long activityId;
  33 + /**
  34 + * SPU 编号
  35 + */
  36 + private Long spuId;
  37 + /**
  38 + * SKU 编号
  39 + */
  40 + private Long skuId;
  41 + /**
  42 + * 用户编号
  43 + */
  44 + private Long userId;
  45 + /**
  46 + * 订单编号
  47 + */
  48 + private Long orderId;
  49 + /**
  50 + * 团长编号
  51 + *
  52 + * 关联 {@link CombinationRecordDO#getUserId()}
  53 + */
  54 + private Long headId;
  55 + /**
  56 + * 商品名字
  57 + */
  58 + private String spuName;
  59 + /**
  60 + * 商品图片
  61 + */
  62 + private String picUrl;
  63 + /**
  64 + * 拼团商品单价
  65 + */
  66 + private Integer combinationPrice;
  67 + /**
  68 + * 用户昵称
  69 + */
  70 + private String nickname;
  71 + /**
  72 + * 用户头像
  73 + */
  74 + private String avatar;
  75 + /**
  76 + * 开团状态
  77 + *
  78 + * 关联 {@link CombinationRecordStatusEnum}
  79 + */
  80 + private Integer status;
  81 + /**
  82 + * 是否虚拟成团
  83 + */
  84 + private Boolean virtualGroup;
  85 + /**
  86 + * 过期时间,单位:小时
  87 + *
  88 + * 关联 {@link CombinationActivityDO#getLimitDuration()}
  89 + */
  90 + private Integer expireTime;
  91 + /**
  92 + * 开始时间 (订单付款后开始的时间)
  93 + */
  94 + private LocalDateTime startTime;
  95 + /**
  96 + * 结束时间(成团时间/失败时间)
  97 + */
  98 + private LocalDateTime endTime;
  99 + /**
  100 + * 开团需要人数
  101 + *
  102 + * 关联 {@link CombinationActivityDO#getUserSize()}
  103 + */
  104 + private Integer userSize;
  105 + /**
  106 + * 已加入拼团人数
  107 + */
  108 + private Integer userCount;
  109 +
  110 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
... ... @@ -34,8 +34,7 @@ public class SeckillActivityDO extends BaseDO {
34 34 /**
35 35 * 秒杀活动商品
36 36 */
37   - @TableField(typeHandler = LongListTypeHandler.class)
38   - private List<Long> spuIds;
  37 + private Long spuId;
39 38 /**
40 39 * 秒杀活动名称
41 40 */
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
... ... @@ -47,11 +47,11 @@ public class SeckillProductDO extends BaseDO {
47 47 @TableField(typeHandler = LongListTypeHandler.class)
48 48 private List<Long> configIds;
49 49 /**
50   - * 商品 spu_id
  50 + * 商品 SPU 编号
51 51 */
52 52 private Long spuId;
53 53 /**
54   - * 商品 sku_id
  54 + * 商品 SKU 编号
55 55 */
56 56 private Long skuId;
57 57 /**
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java
... ... @@ -3,22 +3,27 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig;
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 5 import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableField;
6 7 import com.baomidou.mybatisplus.annotation.TableId;
7 8 import com.baomidou.mybatisplus.annotation.TableName;
8   -import lombok.Data;
9   -import lombok.EqualsAndHashCode;
10   -import lombok.ToString;
  9 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  10 +import lombok.*;
  11 +
  12 +import java.util.List;
11 13  
12 14 /**
13 15 * 秒杀时段 DO
14 16 *
15 17 * @author 芋道源码
16 18 */
17   -@TableName("promotion_seckill_config")
  19 +@TableName(value = "promotion_seckill_config", autoResultMap = true)
18 20 @KeySequence("promotion_seckill_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 21 @Data
20 22 @EqualsAndHashCode(callSuper = true)
21 23 @ToString(callSuper = true)
  24 +@Builder
  25 +@NoArgsConstructor
  26 +@AllArgsConstructor
22 27 public class SeckillConfigDO extends BaseDO {
23 28  
24 29 /**
... ... @@ -38,11 +43,11 @@ public class SeckillConfigDO extends BaseDO {
38 43 * 结束时间点
39 44 */
40 45 private String endTime;
41   - // TODO puhui999:应该是轮播图; private List<String> sliderPicUrls;
42 46 /**
43   - * 秒杀主图
  47 + * 秒杀轮播图
44 48 */
45   - private String picUrl;
  49 + @TableField(typeHandler = JacksonTypeHandler.class)
  50 + private List<String> sliderPicUrls;
46 51 /**
47 52 * 状态
48 53 *
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +// TODO @puhui999:是不是应该在 combination 哈?
  14 +/**
  15 + * 拼团活动 Mapper
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +@Mapper
  20 +public interface CombinationActivityMapper extends BaseMapperX<CombinationActivityDO> {
  21 +
  22 + default PageResult<CombinationActivityDO> selectPage(CombinationActivityPageReqVO reqVO) {
  23 + return selectPage(reqVO, new LambdaQueryWrapperX<CombinationActivityDO>()
  24 + .likeIfPresent(CombinationActivityDO::getName, reqVO.getName())
  25 + .orderByDesc(CombinationActivityDO::getId));
  26 + }
  27 +
  28 + default List<CombinationActivityDO> selectList(CombinationActivityExportReqVO reqVO) {
  29 + return selectList(new LambdaQueryWrapperX<CombinationActivityDO>()
  30 + .likeIfPresent(CombinationActivityDO::getName, reqVO.getName())
  31 + .eqIfPresent(CombinationActivityDO::getStatus, reqVO.getStatus())
  32 + .orderByDesc(CombinationActivityDO::getId));
  33 + }
  34 +
  35 + default List<CombinationActivityDO> selectListByStatus(Integer status) {
  36 + return selectList(CombinationActivityDO::getStatus, status);
  37 + }
  38 +
  39 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationProductMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 拼团商品 Mapper
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +@Mapper
  20 +public interface CombinationProductMapper extends BaseMapperX<CombinationProductDO> {
  21 +
  22 + default PageResult<CombinationProductDO> selectPage(CombinationProductPageReqVO reqVO) {
  23 + return selectPage(reqVO, new LambdaQueryWrapperX<CombinationProductDO>()
  24 + .eqIfPresent(CombinationProductDO::getActivityId, reqVO.getActivityId())
  25 + .eqIfPresent(CombinationProductDO::getSpuId, reqVO.getSpuId())
  26 + .eqIfPresent(CombinationProductDO::getSkuId, reqVO.getSkuId())
  27 + .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus())
  28 + .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime())
  29 + .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime())
  30 + .eqIfPresent(CombinationProductDO::getActivePrice, reqVO.getActivePrice())
  31 + .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime())
  32 + .orderByDesc(CombinationProductDO::getId));
  33 + }
  34 +
  35 + default List<CombinationProductDO> selectList(CombinationProductExportReqVO reqVO) {
  36 + return selectList(new LambdaQueryWrapperX<CombinationProductDO>()
  37 + .eqIfPresent(CombinationProductDO::getActivityId, reqVO.getActivityId())
  38 + .eqIfPresent(CombinationProductDO::getSpuId, reqVO.getSpuId())
  39 + .eqIfPresent(CombinationProductDO::getSkuId, reqVO.getSkuId())
  40 + .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus())
  41 + .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime())
  42 + .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime())
  43 + .eqIfPresent(CombinationProductDO::getActivePrice, reqVO.getActivePrice())
  44 + .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime())
  45 + .orderByDesc(CombinationProductDO::getId));
  46 + }
  47 +
  48 + default List<CombinationProductDO> selectListByActivityIds(Collection<Long> ids) {
  49 + return selectList(CombinationProductDO::getActivityId, ids);
  50 + }
  51 +
  52 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationRecordDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 拼团记录 Mapper
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Mapper
  16 +public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> {
  17 +
  18 + default CombinationRecordDO selectRecord(Long userId, Long orderId) {
  19 + return selectOne(CombinationRecordDO::getUserId, userId,
  20 + CombinationRecordDO::getOrderId, orderId);
  21 + }
  22 +
  23 + default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
  24 + return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
  25 + .eq(CombinationRecordDO::getHeadId, headId)
  26 + .eq(CombinationRecordDO::getStatus, status));
  27 + }
  28 +
  29 + default List<CombinationRecordDO> selectListByStatus(Integer status) {
  30 + return selectList(CombinationRecordDO::getStatus, status);
  31 + }
  32 +
  33 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
... ... @@ -21,6 +21,10 @@ public interface SeckillProductMapper extends BaseMapperX&lt;SeckillProductDO&gt; {
21 21 return selectList(SeckillProductDO::getActivityId, id);
22 22 }
23 23  
  24 + default List<SeckillProductDO> selectListByActivityId(Collection<Long> ids) {
  25 + return selectList(SeckillProductDO::getActivityId, ids);
  26 + }
  27 +
24 28 default List<SeckillProductDO> selectListBySkuIds(Collection<Long> skuIds) {
25 29 return selectList(SeckillProductDO::getSkuId, skuIds);
26 30 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java
... ... @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
7 7 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
  10 +import java.util.List;
  11 +
10 12 @Mapper
11 13 public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
12 14  
... ... @@ -17,4 +19,8 @@ public interface SeckillConfigMapper extends BaseMapperX&lt;SeckillConfigDO&gt; {
17 19 .orderByDesc(SeckillConfigDO::getId));
18 20 }
19 21  
  22 + default List<SeckillConfigDO> selectListByStatus(Integer status) {
  23 + return selectList(SeckillConfigDO::getStatus, status);
  24 + }
  25 +
20 26 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.combination;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  11 +
  12 +import javax.validation.Valid;
  13 +import java.time.LocalDateTime;
  14 +import java.util.Collection;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 拼团活动 Service 接口
  19 + *
  20 + * @author HUIHUI
  21 + */
  22 +public interface CombinationActivityService {
  23 +
  24 + /**
  25 + * 创建拼团活动
  26 + *
  27 + * @param createReqVO 创建信息
  28 + * @return 编号
  29 + */
  30 + Long createCombinationActivity(@Valid CombinationActivityCreateReqVO createReqVO);
  31 +
  32 + /**
  33 + * 更新拼团活动
  34 + *
  35 + * @param updateReqVO 更新信息
  36 + */
  37 + void updateCombinationActivity(@Valid CombinationActivityUpdateReqVO updateReqVO);
  38 +
  39 + /**
  40 + * 删除拼团活动
  41 + *
  42 + * @param id 编号
  43 + */
  44 + void deleteCombinationActivity(Long id);
  45 +
  46 + /**
  47 + * 获得拼团活动
  48 + *
  49 + * @param id 编号
  50 + * @return 拼团活动
  51 + */
  52 + CombinationActivityDO getCombinationActivity(Long id);
  53 +
  54 + /**
  55 + * 获得拼团活动列表
  56 + *
  57 + * @param ids 编号
  58 + * @return 拼团活动列表
  59 + */
  60 + List<CombinationActivityDO> getCombinationActivityList(Collection<Long> ids);
  61 +
  62 + /**
  63 + * 获得拼团活动分页
  64 + *
  65 + * @param pageReqVO 分页查询
  66 + * @return 拼团活动分页
  67 + */
  68 + PageResult<CombinationActivityDO> getCombinationActivityPage(CombinationActivityPageReqVO pageReqVO);
  69 +
  70 + /**
  71 + * 获得拼团活动列表, 用于 Excel 导出
  72 + *
  73 + * @param exportReqVO 查询条件
  74 + * @return 拼团活动列表
  75 + */
  76 + List<CombinationActivityDO> getCombinationActivityList(CombinationActivityExportReqVO exportReqVO);
  77 +
  78 + /**
  79 + * 获得拼团活动商品列表
  80 + *
  81 + * @param ids 拼团活动 ids
  82 + * @return 拼团活动的商品列表
  83 + */
  84 + List<CombinationProductDO> getProductsByActivityIds(Collection<Long> ids);
  85 +
  86 + // TODO @puhui999:拆一个 CombinationRecordService 里,方法名可以简洁成 updateRecordStatusByOrderId;service 方法可以稍微简单一点,如果是 update 方法
  87 + /**
  88 + * 更新拼团状态
  89 + *
  90 + * @param userId 用户编号
  91 + * @param orderId 订单编号
  92 + * @param status 状态
  93 + */
  94 + void updateRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status);
  95 +
  96 + /**
  97 + * 更新拼团状态和开始时间
  98 + *
  99 + * @param userId 用户编号
  100 + * @param orderId 订单编号
  101 + * @param status 状态
  102 + * @param startTime 开始时间
  103 + */
  104 + void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime);
  105 +
  106 + // TODO @puhui999:拆一个 CombinationRecordService 里
  107 + /**
  108 + * 创建拼团记录
  109 + *
  110 + * @param reqDTO 创建信息
  111 + */
  112 + void createRecord(CombinationRecordReqDTO reqDTO);
  113 +
  114 + /**
  115 + * 获得拼团状态
  116 + *
  117 + * @param userId 用户编号
  118 + * @param orderId 订单编号
  119 + * @return 拼团状态
  120 + */
  121 + boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
  122 +
  123 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.combination;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.collection.CollectionUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  9 +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
  10 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  11 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  12 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  13 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
  14 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  16 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  17 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  18 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
  19 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
  20 +import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
  21 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  22 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  23 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationRecordDO;
  24 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper;
  25 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationProductMapper;
  26 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationRecordMapper;
  27 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
  28 +import org.springframework.stereotype.Service;
  29 +import org.springframework.transaction.annotation.Transactional;
  30 +import org.springframework.validation.annotation.Validated;
  31 +
  32 +import javax.annotation.Resource;
  33 +import java.time.LocalDateTime;
  34 +import java.util.Collection;
  35 +import java.util.List;
  36 +import java.util.Set;
  37 +
  38 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  39 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  40 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  41 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
  42 +
  43 +/**
  44 + * 拼团活动 Service 实现类
  45 + *
  46 + * @author HUIHUI
  47 + */
  48 +@Service
  49 +@Validated
  50 +public class CombinationActivityServiceImpl implements CombinationActivityService {
  51 +
  52 + @Resource
  53 + private CombinationActivityMapper combinationActivityMapper;
  54 + @Resource
  55 + private CombinationRecordMapper recordMapper;
  56 + @Resource
  57 + private CombinationProductMapper combinationProductMapper;
  58 + @Resource
  59 + private ProductSpuApi productSpuApi;
  60 + @Resource
  61 + private ProductSkuApi productSkuApi;
  62 +
  63 + @Override
  64 + public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
  65 + // 校验商品 SPU 是否存在是否参加的别的活动
  66 + validateProductCombinationConflict(createReqVO.getSpuId(), null);
  67 + // 获取所选 spu下的所有 sku
  68 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
  69 + // 校验商品 sku 是否存在
  70 + validateProductSkuExistence(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId);
  71 +
  72 + // TODO 艿艿 有个小问题:现在有活动时间和限制时长,活动时间的结束时间早于设置的限制时间怎么算状态比如:
  73 + // 活动时间 2023-08-05 15:00:00 - 2023-08-05 15:20:00 限制时长 2小时,那么活动时间结束就结束还是加时到满两小时
  74 + // 插入拼团活动
  75 + CombinationActivityDO activityDO = CombinationActivityConvert.INSTANCE.convert(createReqVO);
  76 + // TODO 营销相关属性初始化
  77 + activityDO.setTotalNum(0);
  78 + activityDO.setSuccessNum(0);
  79 + activityDO.setOrderUserCount(0);
  80 + activityDO.setVirtualGroup(0);
  81 + activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  82 + combinationActivityMapper.insert(activityDO);
  83 + // 插入商品
  84 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList(activityDO, createReqVO.getProducts());
  85 + combinationProductMapper.insertBatch(productDOs);
  86 + // 返回
  87 + return activityDO.getId();
  88 + }
  89 +
  90 + private void validateProductCombinationConflict(Long spuId, Long activityId) {
  91 + // 校验商品 spu 是否存在
  92 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
  93 + if (CollUtil.isEmpty(spuList)) {
  94 + throw exception(SPU_NOT_EXISTS);
  95 + }
  96 + // 查询所有开启的拼团活动
  97 + List<CombinationActivityDO> activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  98 + // 更新时排除自己
  99 + if (activityId != null) {
  100 + activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  101 + }
  102 + // 过滤出所有 spuIds 有交集的活动
  103 + List<CombinationActivityDO> doList = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getId(), spuId));
  104 + if (CollUtil.isNotEmpty(doList)) {
  105 + throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
  106 + }
  107 + }
  108 +
  109 + @Override
  110 + public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) {
  111 + // 校验存在
  112 + CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId());
  113 + // 校验状态
  114 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  115 + throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
  116 + }
  117 + // 校验商品冲突
  118 + validateProductCombinationConflict(updateReqVO.getSpuId(), updateReqVO.getId());
  119 + // 获取所选 spu下的所有 sku
  120 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
  121 + // 校验商品 sku 是否存在
  122 + validateProductSkuExistence(skus, updateReqVO.getProducts(), CombinationProductUpdateReqVO::getSkuId);
  123 +
  124 + // 更新
  125 + CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
  126 + combinationActivityMapper.updateById(updateObj);
  127 + // 更新商品
  128 + updateCombinationProduct(updateObj, updateReqVO.getProducts());
  129 + }
  130 +
  131 + /**
  132 + * 更新秒杀商品
  133 + * TODO 更新商品要不要封装成通用方法
  134 + *
  135 + * @param updateObj DO
  136 + * @param products 商品配置
  137 + */
  138 + private void updateCombinationProduct(CombinationActivityDO updateObj, List<CombinationProductUpdateReqVO> products) {
  139 + List<CombinationProductDO> combinationProductDOs = combinationProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
  140 + // 数据库中的活动商品
  141 + Set<Long> convertSet = CollectionUtils.convertSet(combinationProductDOs, CombinationProductDO::getSkuId);
  142 + // 前端传过来的活动商品
  143 + Set<Long> convertSet1 = CollectionUtils.convertSet(products, CombinationProductUpdateReqVO::getSkuId);
  144 + // 删除后台存在的前端不存在的商品
  145 + List<Long> d = CollectionUtils.filterList(convertSet, item -> !convertSet1.contains(item));
  146 + if (CollUtil.isNotEmpty(d)) {
  147 + combinationProductMapper.deleteBatchIds(d);
  148 + }
  149 + // 前端存在的后端不存在的商品
  150 + List<Long> c = CollectionUtils.filterList(convertSet1, item -> !convertSet.contains(item));
  151 + if (CollUtil.isNotEmpty(c)) {
  152 + List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
  153 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList(updateObj, vos);
  154 + combinationProductMapper.insertBatch(productDOs);
  155 + }
  156 + // 更新已存在的商品
  157 + List<Long> u = CollectionUtils.filterList(convertSet1, convertSet::contains);
  158 + if (CollUtil.isNotEmpty(u)) {
  159 + List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
  160 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList1(updateObj, vos, combinationProductDOs);
  161 + combinationProductMapper.updateBatch(productDOs);
  162 + }
  163 + }
  164 +
  165 + @Override
  166 + public void deleteCombinationActivity(Long id) {
  167 + // 校验存在
  168 + CombinationActivityDO activityDO = validateCombinationActivityExists(id);
  169 + // 校验状态
  170 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  171 + throw exception(COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  172 + }
  173 +
  174 + // 删除
  175 + combinationActivityMapper.deleteById(id);
  176 + }
  177 +
  178 + private CombinationActivityDO validateCombinationActivityExists(Long id) {
  179 + CombinationActivityDO activityDO = combinationActivityMapper.selectById(id);
  180 + if (activityDO == null) {
  181 + throw exception(COMBINATION_ACTIVITY_NOT_EXISTS);
  182 + }
  183 + return activityDO;
  184 + }
  185 +
  186 + @Override
  187 + public CombinationActivityDO getCombinationActivity(Long id) {
  188 + return validateCombinationActivityExists(id);
  189 + }
  190 +
  191 + @Override
  192 + public List<CombinationActivityDO> getCombinationActivityList(Collection<Long> ids) {
  193 + return combinationActivityMapper.selectBatchIds(ids);
  194 + }
  195 +
  196 + @Override
  197 + public PageResult<CombinationActivityDO> getCombinationActivityPage(CombinationActivityPageReqVO pageReqVO) {
  198 + return combinationActivityMapper.selectPage(pageReqVO);
  199 + }
  200 +
  201 + @Override
  202 + public List<CombinationActivityDO> getCombinationActivityList(CombinationActivityExportReqVO exportReqVO) {
  203 + return combinationActivityMapper.selectList(exportReqVO);
  204 + }
  205 +
  206 + @Override
  207 + public List<CombinationProductDO> getProductsByActivityIds(Collection<Long> ids) {
  208 + return combinationProductMapper.selectListByActivityIds(ids);
  209 + }
  210 +
  211 + @Override
  212 + public void updateRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status) {
  213 + // 校验拼团是否存在
  214 + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
  215 +
  216 + // 更新状态
  217 + recordDO.setStatus(status);
  218 + recordMapper.updateById(recordDO);
  219 + }
  220 +
  221 + @Override
  222 + @Transactional(rollbackFor = Exception.class)
  223 + public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) {
  224 + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
  225 + // 更新状态
  226 + recordDO.setStatus(status);
  227 + // 更新开始时间
  228 + recordDO.setStartTime(startTime);
  229 + recordMapper.updateById(recordDO);
  230 +
  231 + // 更新拼团参入人数
  232 + List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
  233 + if (CollUtil.isNotEmpty(recordDOs)) {
  234 + recordDOs.forEach(item -> {
  235 + item.setUserCount(recordDOs.size());
  236 + // 校验拼团是否满足要求
  237 + if (recordDOs.size() >= recordDO.getUserSize()) {
  238 + item.setStatus(CombinationRecordStatusEnum.SUCCESS.getStatus());
  239 + }
  240 + });
  241 + }
  242 + recordMapper.updateBatch(recordDOs);
  243 + }
  244 +
  245 + private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) {
  246 + // 校验拼团是否存在
  247 + CombinationRecordDO recordDO = recordMapper.selectRecord(userId, orderId);
  248 + if (recordDO == null) {
  249 + throw exception(COMBINATION_RECORD_NOT_EXISTS);
  250 + }
  251 + return recordDO;
  252 + }
  253 +
  254 + @Override
  255 + public void createRecord(CombinationRecordReqDTO reqDTO) {
  256 + // 校验拼团活动
  257 + CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
  258 + // TODO @puhui999:需要校验下,它当前是不是已经参加了该拼团;
  259 + // TODO @puhui999: 父拼团是否存在,是否已经满了
  260 +
  261 + CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
  262 + record.setVirtualGroup(false);
  263 + // TODO @puhui999:过期时间,应该是 Date 哈;
  264 + record.setExpireTime(activity.getLimitDuration());
  265 + record.setUserSize(activity.getUserSize());
  266 + recordMapper.insert(record);
  267 + }
  268 +
  269 + @Override
  270 + public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
  271 + CombinationRecordDO record = validateCombinationRecord(userId, orderId);
  272 + // TODO @puhui999:可以搞个 getRecrod 方法,然后业务通过 CombinationRecordStatusEnum.isSuccess 方法校验
  273 + return ObjectUtil.equal(record.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus());
  274 + }
  275 +
  276 + // TODO @puhui999:status 传入进来搞哈;
  277 + /**
  278 + * APP 端获取开团记录
  279 + *
  280 + * @return 开团记录
  281 + */
  282 + public List<CombinationRecordDO> getRecordList() {
  283 + return recordMapper.selectListByStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
  284 + }
  285 +
  286 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java
... ... @@ -79,4 +79,12 @@ public interface SeckillActivityService {
79 79 */
80 80 List<SeckillProductDO> getSeckillProductListByActivityId(Long id);
81 81  
  82 + /**
  83 + * 通过活动编号获取活动商品
  84 + *
  85 + * @param ids 活动编号
  86 + * @return 活动商品列表
  87 + */
  88 + List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> ids);
  89 +
82 90 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
1 1 package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.ArrayUtil;
5 4 import cn.hutool.core.util.ObjectUtil;
6 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
... ... @@ -13,29 +12,28 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
13 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
14 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
15 14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
16   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
  16 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
17 17 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
18 18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
19 19 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
20 20 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
21 21 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper;
22   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
23 22 import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService;
24 23 import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
25 24 import org.springframework.stereotype.Service;
  25 +import org.springframework.transaction.annotation.Transactional;
26 26 import org.springframework.validation.annotation.Validated;
27 27  
28 28 import javax.annotation.Resource;
29 29 import java.util.Collection;
30 30 import java.util.List;
31 31 import java.util.Set;
32   -import java.util.stream.Collectors;
33 32  
34 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35   -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
36 34 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
37 35 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
38   -import static java.util.Arrays.asList;
  36 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
39 37  
40 38 /**
41 39 * 秒杀活动 Service 实现类
... ... @@ -58,155 +56,150 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
58 56 private ProductSkuApi productSkuApi;
59 57  
60 58 @Override
  59 + @Transactional(rollbackFor = Exception.class)
61 60 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
62 61 // 校验商品秒秒杀时段是否冲突
63   - validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuIds());
  62 + validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);
  63 + // 获取所选 spu 下的所有 sku
  64 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(createReqVO.getSpuId()));
64 65 // 校验商品 sku 是否存在
65   - validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts());
  66 + // TODO @puhui999:直接校验 sku 数量,是不是就完事啦,不需要校验的特别严谨哈;
  67 + validateProductSkuExistence(skus, createReqVO.getProducts(), SeckillProductCreateReqVO::getSkuId);
66 68  
67 69 // 插入秒杀活动
68 70 SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
69   - .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
  71 + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()))
  72 + .setTotalStock(CollectionUtils.getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum));
70 73 seckillActivityMapper.insert(activity);
71 74 // 插入商品
  75 + // TODO @puhui999:products 要注意复数哈
72 76 List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts());
73 77 seckillProductMapper.insertBatch(product);
74 78 return activity.getId();
75 79 }
76 80  
77   - private <T extends SeckillProductBaseVO> void validateProductSkuExistence(List<Long> spuIds, List<T> products) {
78   - // 校验 spu 个数是否相等
79   - // TODO @puhui999:不用校验 SPU 哈,只校验 sku 对应的 spuId 是否一致;
80   - Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId);
81   - if (ObjectUtil.notEqual(spuIds.size(), convertedSpuIds.size())) {
82   - throw exception(SKU_NOT_EXISTS);
83   - }
84   - // 获取所选 spu下的所有 sku
85   - // TODO @puhui999:变量可以简单一点;skus
86   - List<ProductSkuRespDTO> skuRespDTOs = productSkuApi.getSkuListBySpuId(spuIds);
87   - // 校验 sku 个数是否一致
88   - Set<Long> skuIdsSet = CollectionUtils.convertSet(products, T::getSkuId);
89   - Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skuRespDTOs, ProductSkuRespDTO::getId);
90   - if (ObjectUtil.notEqual(skuIdsSet.size(), skuIdsSet1.size())) {
91   - throw exception(SKU_NOT_EXISTS);
92   - }
93   - // 校验 skuId 是否存在
94   - if (!skuIdsSet1.containsAll(skuIdsSet) || !skuIdsSet.containsAll(skuIdsSet1)) {
95   - throw exception(SKU_NOT_EXISTS);
96   - }
97   - }
98   -
99   - private void validateProductSpuSeckillConflict(List<Long> configIds, List<Long> spuIds) {
  81 + private void validateProductSpuSeckillConflict(List<Long> configIds, Long spuId, Long activityId) {
100 82 // 校验秒杀时段是否存在
101 83 seckillConfigService.validateSeckillConfigExists(configIds);
102 84 // 校验商品 spu 是否存在
103   - List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
104   - if (ObjectUtil.notEqual(spuIds.size(), spuList.size())) {
  85 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
  86 + if (CollUtil.isEmpty(spuList)) {
105 87 throw exception(SPU_NOT_EXISTS);
106 88 }
107 89 // 查询所有开启的秒杀活动
108 90 List<SeckillActivityDO> activityDOs = seckillActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
109   - // 过滤出所有 spuIds 有交集的活动
110   - List<SeckillActivityDO> doList = activityDOs.stream().filter(s -> {
111   - // 判断 spu 是否有交集
112   - List<Long> spuIdsClone = ArrayUtil.clone(s.getSpuIds());
113   - spuIdsClone.retainAll(spuIds);
114   - if (CollUtil.isEmpty(spuIdsClone)) {
115   - return false;
116   - }
  91 + if (activityId != null) {
  92 + // 更新时移除本活动
  93 + activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  94 + }
  95 + // 过滤出所有 spuId 有交集的活动
  96 + List<SeckillActivityDO> activityDOs1 = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getSpuId(), spuId));
  97 + if (CollUtil.isNotEmpty(activityDOs1)) {
  98 + throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
  99 + }
  100 + List<SeckillActivityDO> activityDOs2 = CollectionUtils.convertList(activityDOs, c -> c, s -> {
117 101 // 判断秒杀时段是否有交集
118   - List<Long> configIdsClone = ArrayUtil.clone(s.getConfigIds());
  102 + // TODO @puhui999:是不是 containsAny 就是有交集呀
  103 + List<Long> configIdsClone = CollUtil.newArrayList(s.getConfigIds());
119 104 configIdsClone.retainAll(configIds);
120 105 return CollUtil.isNotEmpty(configIdsClone);
121   - }).collect(Collectors.toList());
122   - if (CollUtil.isNotEmpty(doList)) {
123   - throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
  106 + });
  107 + if (CollUtil.isNotEmpty(activityDOs2)) {
  108 + throw exception(SECKILL_TIME_CONFLICTS);
124 109 }
125 110 }
126 111  
127 112 @Override
  113 + @Transactional(rollbackFor = Exception.class)
128 114 public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) {
129 115 // 校验存在
130 116 SeckillActivityDO seckillActivity = validateSeckillActivityExists(updateReqVO.getId());
131   - if (CommonStatusEnum.ENABLE.getStatus().equals(seckillActivity.getStatus())) {
  117 + if (CommonStatusEnum.DISABLE.getStatus().equals(seckillActivity.getStatus())) {
132 118 throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
133 119 }
134 120 // 校验商品是否冲突
135   - validateProductSpuSeckillConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuIds());
  121 + validateProductSpuSeckillConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuId(), updateReqVO.getId());
  122 + // 获取所选 spu下的所有 sku
  123 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(updateReqVO.getSpuId()));
136 124 // 校验商品 sku 是否存在
137   - validateProductSkuExistence(updateReqVO.getSpuIds(), updateReqVO.getProducts());
  125 + validateProductSkuExistence(skus, updateReqVO.getProducts(), SeckillProductUpdateReqVO::getSkuId);
138 126  
139 127 // 更新活动
140 128 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
141   - .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()));
  129 + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()))
  130 + .setTotalStock(CollectionUtils.getSumValue(updateReqVO.getProducts(), SeckillProductUpdateReqVO::getStock, Integer::sum));
142 131 seckillActivityMapper.updateById(updateObj);
143 132 // 更新商品
144   - //updateSeckillProduct(updateReqVO);
  133 + updateSeckillProduct(updateObj, updateReqVO.getProducts());
145 134 }
146 135  
147 136  
148 137 /**
149 138 * 更新秒杀商品
150   - * 后台查出的数据和前台查出的数据进行遍历,
151   - * 1. 对前台数据进行遍历:如果不存在于后台的 sku 中需要新增
152   - * 2. 对后台数据进行遍历:如果不存在于前台的 sku 中需要删除
153   - * 3. 最后对当前活动商品全部更新,更新秒杀时段id列表
154 139 *
155   - * @param updateReqVO 更新的请求VO
  140 + * @param updateObj 更新的活动
  141 + * @param products 商品配置
156 142 */
157   - private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) {
158   - // TODO puhui999:要不这里简单一点;删除原本的,插入新增的;不做的这么细致
159   - // TODO puhui999:后续完善
160   - //List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateReqVO.getId());
161   - //List<SeckillProductUpdateReqVO> products = updateReqVO.getProducts();
162   -
163   - ////计算需要删除的数据
164   - //List<Long> deleteIds = CollectionUtils.convertList(seckillProductDOs, SeckillProductDO::getId,
165   - // seckillProductDO -> products.stream()
166   - // .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product)));
167   - //if (CollUtil.isNotEmpty(deleteIds)) {
168   - // seckillProductMapper.deleteBatchIds(deleteIds);
169   - //}
170   - //
171   - //// 计算需要新增的数据
172   - //List<SeckillProductDO> newSeckillProductDOs = CollectionUtils.convertList(products,
173   - // product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId()));
174   - //newSeckillProductDOs.removeIf(product -> seckillProductDOs.stream()
175   - // .anyMatch(seckillProduct -> SeckillActivityConvert.INSTANCE.isEquals(seckillProduct, product)));
176   - //if (CollUtil.isNotEmpty(newSeckillProductDOs)) {
177   - // seckillProductMapper.insertBatch(newSeckillProductDOs);
178   - //}
179   -
180   - //全量更新当前活动商品的秒杀时段id列表(timeIds)
181   - seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getConfigIds());
  143 + // TODO @puhui999:我在想,我们是不是可以封装一个 CollUtil 的方法,传入两个数组,判断出哪些是新增、哪些是修改、哪些是删除;
  144 + // 例如说,products 先转化成 SeckillProductDO;然后,基于一个 func(key1, key2) 做比对;
  145 + // 如果可以跑通,所有涉及到这种逻辑的,都可以服用哈。
  146 + private void updateSeckillProduct(SeckillActivityDO updateObj, List<SeckillProductUpdateReqVO> products) {
  147 + // 数据库中的活动商品
  148 + List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());
  149 + Set<Long> dbSkuIds = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);
  150 + // 1. 删除后台存在的前端不存在的商品
  151 + // TODO @puhui999:delete 应该是 id,不是 skuId 哈
  152 + Set<Long> voSkuIds = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);
  153 + List<Long> d = CollectionUtils.filterList(dbSkuIds, item -> !voSkuIds.contains(item));
  154 + if (CollUtil.isNotEmpty(d)) {
  155 + seckillProductMapper.deleteBatchIds(d);
  156 + }
  157 + // 2. 前端存在的后端不存在的商品
  158 + List<Long> c = CollectionUtils.filterList(voSkuIds, item -> !dbSkuIds.contains(item));
  159 + if (CollUtil.isNotEmpty(c)) {
  160 + List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
  161 + List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(updateObj, vos);
  162 + seckillProductMapper.insertBatch(productDOs);
  163 + }
  164 + // 3. 更新已存在的商品
  165 + List<Long> u = CollectionUtils.filterList(voSkuIds, dbSkuIds::contains);
  166 + if (CollUtil.isNotEmpty(u)) {
  167 + List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
  168 + List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList1(updateObj, vos, seckillProductDOs);
  169 + seckillProductMapper.updateBatch(productDOs);
  170 + }
182 171 }
183 172  
184 173 @Override
  174 + @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这个不用加事务哈
185 175 public void closeSeckillActivity(Long id) {
  176 + // TODO 待验证没使用过
186 177 // 校验存在
187   - SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
188   - if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
  178 + SeckillActivityDO activity = validateSeckillActivityExists(id);
  179 + if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
189 180 throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
190 181 }
191   - if (PromotionActivityStatusEnum.END.getStatus().equals(seckillActivity.getStatus())) {
192   - throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END);
193   - }
  182 +
194 183 // 更新
195   - SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
  184 + SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus());
196 185 seckillActivityMapper.updateById(updateObj);
197 186 }
198 187  
199 188 @Override
  189 + @Transactional(rollbackFor = Exception.class)
200 190 public void deleteSeckillActivity(Long id) {
201 191 // 校验存在
202 192 SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
203   - List<Integer> statuses = asList(PromotionActivityStatusEnum.CLOSE.getStatus(), PromotionActivityStatusEnum.END.getStatus());
204   - if (!statuses.contains(seckillActivity.getStatus())) {
  193 + if (CommonStatusEnum.ENABLE.getStatus().equals(seckillActivity.getStatus())) {
205 194 throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
206 195 }
207 196  
208   - // 删除
  197 + // 删除活动
209 198 seckillActivityMapper.deleteById(id);
  199 + // 删除活动商品
  200 + List<SeckillProductDO> productDOs = seckillProductMapper.selectListByActivityId(id);
  201 + Set<Long> convertSet = CollectionUtils.convertSet(productDOs, SeckillProductDO::getSkuId);
  202 + seckillProductMapper.deleteBatchIds(convertSet);
210 203 }
211 204  
212 205 private SeckillActivityDO validateSeckillActivityExists(Long id) {
... ... @@ -219,7 +212,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
219 212  
220 213 @Override
221 214 public SeckillActivityDO getSeckillActivity(Long id) {
222   - return seckillActivityMapper.selectById(id);
  215 + return validateSeckillActivityExists(id);
223 216 }
224 217  
225 218 @Override
... ... @@ -237,4 +230,9 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
237 230 return seckillProductMapper.selectListByActivityId(id);
238 231 }
239 232  
  233 + @Override
  234 + public List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> ids) {
  235 + return seckillProductMapper.selectListByActivityId(ids);
  236 + }
  237 +
240 238 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java
1 1 package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
4 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
6 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
7 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
8 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
... ... @@ -10,14 +13,13 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo
10 13 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
11 14 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
12 15 import org.springframework.stereotype.Service;
  16 +import org.springframework.transaction.annotation.Transactional;
13 17 import org.springframework.validation.annotation.Validated;
14 18  
15 19 import javax.annotation.Resource;
16 20 import java.time.LocalTime;
17 21 import java.util.Collection;
18 22 import java.util.List;
19   -import java.util.Set;
20   -import java.util.stream.Collectors;
21 23  
22 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 25 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
... ... @@ -35,9 +37,10 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
35 37 private SeckillConfigMapper seckillConfigMapper;
36 38  
37 39 @Override
  40 + @Transactional(rollbackFor = Exception.class)
38 41 public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
39 42 // 校验时间段是否冲突
40   - validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime());
  43 + validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null);
41 44  
42 45 // 插入
43 46 SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO);
... ... @@ -47,18 +50,30 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
47 50 }
48 51  
49 52 @Override
  53 + @Transactional(rollbackFor = Exception.class)
50 54 public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
51 55 // 校验存在
52 56 validateSeckillConfigExists(updateReqVO.getId());
53 57 // 校验时间段是否冲突
54   - validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime());
  58 + validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime(), updateReqVO.getId());
55 59  
56 60 // 更新
57 61 SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO);
58 62 seckillConfigMapper.updateById(updateObj);
59 63 }
60 64  
  65 + // TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧; 更新状态不用那么多必须的参数,更新的时候需要校验时间段
61 66 @Override
  67 + public void updateSeckillConfigStatus(Long id, Integer status) {
  68 + // 校验秒杀时段是否存在
  69 + validateSeckillConfigExists(id);
  70 +
  71 + // 更新状态
  72 + seckillConfigMapper.updateById(new SeckillConfigDO().setId(id).setStatus(status));
  73 + }
  74 +
  75 + @Override
  76 + @Transactional(rollbackFor = Exception.class)
62 77 public void deleteSeckillConfig(Long id) {
63 78 // 校验存在
64 79 validateSeckillConfigExists(id);
... ... @@ -79,39 +94,29 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
79 94 * @param startTime 开始时间
80 95 * @param endTime 结束时间
81 96 */
82   - private void validateSeckillConfigConflict(String startTime, String endTime) {
  97 + private void validateSeckillConfigConflict(String startTime, String endTime, Long seckillConfigId) {
83 98 LocalTime startTime1 = LocalTime.parse(startTime);
84 99 LocalTime endTime1 = LocalTime.parse(endTime);
85   - // TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈;
86   - // 检查选择的时间是否相等
87   - if (startTime1.equals(endTime1)) {
88   - throw exception(SECKILL_TIME_EQUAL);
89   - }
90   - // 检查开始时间是否在结束时间之前
91   - if (startTime1.isAfter(endTime1)) {
92   - throw exception(SECKILL_START_TIME_BEFORE_END_TIME);
93   - }
94 100 // 查询出所有的时段配置
95 101 List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
  102 + // 更新时排除自己
  103 + if (seckillConfigId != null) {
  104 + configDOs.removeIf(item -> ObjectUtil.equal(item.getId(), seckillConfigId));
  105 + }
96 106 // 过滤出重叠的时段 ids
97   - // TODO @puhui999:感觉 findOne 就可以了?
98   - Set<Long> ids = configDOs.stream().filter((config) -> {
  107 + boolean hasConflict = configDOs.stream().anyMatch(config -> {
99 108 LocalTime startTime2 = LocalTime.parse(config.getStartTime());
100 109 LocalTime endTime2 = LocalTime.parse(config.getEndTime());
101 110 // 判断时间是否重叠
102   - // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
103   - // todo @puhui999:LocalDateUtils 可以写个工具类?是否是有重叠的时间?感觉别的场景,可能也会有需要
104   - return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
105   - // 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
106   - || startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
107   - // 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
108   - || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
109   - }).map(SeckillConfigDO::getId).collect(Collectors.toSet());
110   - if (CollUtil.isNotEmpty(ids)) {
  111 + return LocalDateTimeUtils.checkTimeOverlap(startTime1, endTime1, startTime2, endTime2);
  112 + });
  113 +
  114 + if (hasConflict) {
111 115 throw exception(SECKILL_TIME_CONFLICTS);
112 116 }
113 117 }
114 118  
  119 +
115 120 @Override
116 121 public SeckillConfigDO getSeckillConfig(Long id) {
117 122 return seckillConfigMapper.selectById(id);
... ... @@ -127,10 +132,18 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
127 132 if (CollUtil.isEmpty(configIds)) {
128 133 throw exception(SECKILL_TIME_NOT_EXISTS);
129 134 }
130   - if (seckillConfigMapper.selectBatchIds(configIds).size() != configIds.size()) {
  135 + List<SeckillConfigDO> configDOs = seckillConfigMapper.selectBatchIds(configIds);
  136 + if (CollUtil.isEmpty(configDOs)) {
  137 + throw exception(SECKILL_TIME_NOT_EXISTS);
  138 + }
  139 + // 过滤出关闭的时段
  140 + List<SeckillConfigDO> filterList = CollectionUtils.filterList(configDOs, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.DISABLE.getStatus()));
  141 + if (CollUtil.isNotEmpty(filterList)) {
  142 + throw exception(SECKILL_TIME_DISABLE);
  143 + }
  144 + if (configDOs.size() != configIds.size()) {
131 145 throw exception(SECKILL_TIME_NOT_EXISTS);
132 146 }
133   - // TODO @puhui999:应该要校验个 status 哈;如果有禁用的,也不行
134 147 }
135 148  
136 149 @Override
... ... @@ -138,23 +151,10 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
138 151 return seckillConfigMapper.selectPage(pageVO);
139 152 }
140 153  
141   - // TODO @puhui999:写个查询状态的; 尽可能通用哈
  154 + // TODO @puhui999:改成传入 enable 状态哈。一个通用的 getSeckillConfigList 方法
142 155 @Override
143 156 public List<SeckillConfigDO> getListAllSimple() {
144   - return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
145   - }
146   -
147   - // TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧;
148   - @Override
149   - public void updateSeckillConfigStatus(Long id, Integer status) {
150   - // 校验秒杀时段是否存在
151   - validateSeckillConfigExists(id);
152   -
153   - SeckillConfigDO seckillConfigDO = new SeckillConfigDO();
154   - seckillConfigDO.setId(id);
155   - seckillConfigDO.setStatus(status);
156   - // 更新状态
157   - seckillConfigMapper.updateById(seckillConfigDO);
  157 + return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
158 158 }
159 159  
160 160 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
1 1 package cn.iocoder.yudao.module.promotion.util;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 6 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  7 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
5 8  
6 9 import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +import java.util.Set;
  12 +import java.util.function.Function;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  15 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
7 16  
8 17 /**
9 18 * 活动工具类
... ... @@ -22,4 +31,16 @@ public class PromotionUtils {
22 31 return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
23 32 }
24 33  
  34 + // TODO @puhui999:写个注释哈。
  35 + public static <T> void validateProductSkuExistence(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
  36 + // 校验 sku 个数是否一致
  37 + Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);
  38 + Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId);
  39 + // 校验 skuId 是否存在
  40 + List<Long> f = CollectionUtils.filterList(skuIdsSet, s -> !skuIdsSet1.contains(s));
  41 + if (CollUtil.isNotEmpty(f)) {
  42 + throw exception(SKU_NOT_EXISTS);
  43 + }
  44 + }
  45 +
25 46 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.combination;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper;
  11 +import org.junit.jupiter.api.Disabled;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.springframework.context.annotation.Import;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
  19 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  20 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  21 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  22 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  23 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  24 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;
  25 +import static org.junit.jupiter.api.Assertions.*;
  26 +
  27 +// TODO 芋艿:等完成后,在补全单测
  28 +/**
  29 + * {@link CombinationActivityServiceImpl} 的单元测试类
  30 + *
  31 + * @author HUIHUI
  32 + */
  33 +@Import(CombinationActivityServiceImpl.class)
  34 +public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
  35 +
  36 + @Resource
  37 + private CombinationActivityServiceImpl combinationActivityService;
  38 +
  39 + @Resource
  40 + private CombinationActivityMapper combinationActivityMapper;
  41 +
  42 + @Test
  43 + public void testCreateCombinationActivity_success() {
  44 + // 准备参数
  45 + CombinationActivityCreateReqVO reqVO = randomPojo(CombinationActivityCreateReqVO.class);
  46 +
  47 + // 调用
  48 + Long combinationActivityId = combinationActivityService.createCombinationActivity(reqVO);
  49 + // 断言
  50 + assertNotNull(combinationActivityId);
  51 + // 校验记录的属性是否正确
  52 + CombinationActivityDO combinationActivity = combinationActivityMapper.selectById(combinationActivityId);
  53 + assertPojoEquals(reqVO, combinationActivity);
  54 + }
  55 +
  56 + @Test
  57 + public void testUpdateCombinationActivity_success() {
  58 + // mock 数据
  59 + CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class);
  60 + combinationActivityMapper.insert(dbCombinationActivity);// @Sql: 先插入出一条存在的数据
  61 + // 准备参数
  62 + CombinationActivityUpdateReqVO reqVO = randomPojo(CombinationActivityUpdateReqVO.class, o -> {
  63 + o.setId(dbCombinationActivity.getId()); // 设置更新的 ID
  64 + });
  65 +
  66 + // 调用
  67 + combinationActivityService.updateCombinationActivity(reqVO);
  68 + // 校验是否更新正确
  69 + CombinationActivityDO combinationActivity = combinationActivityMapper.selectById(reqVO.getId()); // 获取最新的
  70 + assertPojoEquals(reqVO, combinationActivity);
  71 + }
  72 +
  73 + @Test
  74 + public void testUpdateCombinationActivity_notExists() {
  75 + // 准备参数
  76 + CombinationActivityUpdateReqVO reqVO = randomPojo(CombinationActivityUpdateReqVO.class);
  77 +
  78 + // 调用, 并断言异常
  79 + assertServiceException(() -> combinationActivityService.updateCombinationActivity(reqVO), COMBINATION_ACTIVITY_NOT_EXISTS);
  80 + }
  81 +
  82 + @Test
  83 + public void testDeleteCombinationActivity_success() {
  84 + // mock 数据
  85 + CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class);
  86 + combinationActivityMapper.insert(dbCombinationActivity);// @Sql: 先插入出一条存在的数据
  87 + // 准备参数
  88 + Long id = dbCombinationActivity.getId();
  89 +
  90 + // 调用
  91 + combinationActivityService.deleteCombinationActivity(id);
  92 + // 校验数据不存在了
  93 + assertNull(combinationActivityMapper.selectById(id));
  94 + }
  95 +
  96 + @Test
  97 + public void testDeleteCombinationActivity_notExists() {
  98 + // 准备参数
  99 + Long id = randomLongId();
  100 +
  101 + // 调用, 并断言异常
  102 + assertServiceException(() -> combinationActivityService.deleteCombinationActivity(id), COMBINATION_ACTIVITY_NOT_EXISTS);
  103 + }
  104 +
  105 + @Test
  106 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  107 + public void testGetCombinationActivityPage() {
  108 + // mock 数据
  109 + CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class, o -> { // 等会查询到
  110 + o.setName(null);
  111 + //o.setSpuId(null);
  112 + o.setTotalLimitCount(null);
  113 + o.setSingleLimitCount(null);
  114 + o.setStartTime(null);
  115 + o.setEndTime(null);
  116 + o.setUserSize(null);
  117 + o.setTotalNum(null);
  118 + o.setSuccessNum(null);
  119 + o.setOrderUserCount(null);
  120 + o.setVirtualGroup(null);
  121 + o.setStatus(null);
  122 + o.setLimitDuration(null);
  123 + o.setCreateTime(null);
  124 + });
  125 + combinationActivityMapper.insert(dbCombinationActivity);
  126 + // 测试 name 不匹配
  127 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setName(null)));
  128 + // 测试 spuId 不匹配
  129 + //combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
  130 + // 测试 totalLimitCount 不匹配
  131 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalLimitCount(null)));
  132 + // 测试 singleLimitCount 不匹配
  133 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSingleLimitCount(null)));
  134 + // 测试 startTime 不匹配
  135 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setStartTime(null)));
  136 + // 测试 endTime 不匹配
  137 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setEndTime(null)));
  138 + // 测试 userSize 不匹配
  139 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setUserSize(null)));
  140 + // 测试 totalNum 不匹配
  141 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalNum(null)));
  142 + // 测试 successNum 不匹配
  143 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessNum(null)));
  144 + // 测试 orderUserCount 不匹配
  145 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setOrderUserCount(null)));
  146 + // 测试 virtualGroup 不匹配
  147 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setVirtualGroup(null)));
  148 + // 测试 status 不匹配
  149 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setStatus(null)));
  150 + // 测试 limitDuration 不匹配
  151 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setLimitDuration(null)));
  152 + // 测试 createTime 不匹配
  153 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setCreateTime(null)));
  154 + // 准备参数
  155 + CombinationActivityPageReqVO reqVO = new CombinationActivityPageReqVO();
  156 + reqVO.setName(null);
  157 + reqVO.setSpuId(null);
  158 + reqVO.setTotalLimitCount(null);
  159 + reqVO.setSingleLimitCount(null);
  160 + reqVO.setStartTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  161 + reqVO.setEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  162 + reqVO.setUserSize(null);
  163 + reqVO.setTotalNum(null);
  164 + reqVO.setSuccessNum(null);
  165 + reqVO.setOrderUserCount(null);
  166 + reqVO.setVirtualGroup(null);
  167 + reqVO.setStatus(null);
  168 + reqVO.setLimitDuration(null);
  169 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  170 +
  171 + // 调用
  172 + PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(reqVO);
  173 + // 断言
  174 + assertEquals(1, pageResult.getTotal());
  175 + assertEquals(1, pageResult.getList().size());
  176 + assertPojoEquals(dbCombinationActivity, pageResult.getList().get(0));
  177 + }
  178 +
  179 + @Test
  180 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  181 + public void testGetCombinationActivityList() {
  182 + // mock 数据
  183 + CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class, o -> { // 等会查询到
  184 + o.setName(null);
  185 + //o.setSpuId(null);
  186 + o.setTotalLimitCount(null);
  187 + o.setSingleLimitCount(null);
  188 + o.setStartTime(null);
  189 + o.setEndTime(null);
  190 + o.setUserSize(null);
  191 + o.setTotalNum(null);
  192 + o.setSuccessNum(null);
  193 + o.setOrderUserCount(null);
  194 + o.setVirtualGroup(null);
  195 + o.setStatus(null);
  196 + o.setLimitDuration(null);
  197 + o.setCreateTime(null);
  198 + });
  199 + combinationActivityMapper.insert(dbCombinationActivity);
  200 + // 测试 name 不匹配
  201 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setName(null)));
  202 + // 测试 spuId 不匹配
  203 + //combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
  204 + // 测试 totalLimitCount 不匹配
  205 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalLimitCount(null)));
  206 + // 测试 singleLimitCount 不匹配
  207 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSingleLimitCount(null)));
  208 + // 测试 startTime 不匹配
  209 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setStartTime(null)));
  210 + // 测试 endTime 不匹配
  211 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setEndTime(null)));
  212 + // 测试 userSize 不匹配
  213 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setUserSize(null)));
  214 + // 测试 totalNum 不匹配
  215 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalNum(null)));
  216 + // 测试 successNum 不匹配
  217 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSuccessNum(null)));
  218 + // 测试 orderUserCount 不匹配
  219 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setOrderUserCount(null)));
  220 + // 测试 virtualGroup 不匹配
  221 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setVirtualGroup(null)));
  222 + // 测试 status 不匹配
  223 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setStatus(null)));
  224 + // 测试 limitDuration 不匹配
  225 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setLimitDuration(null)));
  226 + // 测试 createTime 不匹配
  227 + combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setCreateTime(null)));
  228 + // 准备参数
  229 + CombinationActivityExportReqVO reqVO = new CombinationActivityExportReqVO();
  230 + reqVO.setName(null);
  231 + reqVO.setSpuId(null);
  232 + reqVO.setTotalLimitCount(null);
  233 + reqVO.setSingleLimitCount(null);
  234 + reqVO.setStartTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  235 + reqVO.setEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  236 + reqVO.setUserSize(null);
  237 + reqVO.setTotalNum(null);
  238 + reqVO.setSuccessNum(null);
  239 + reqVO.setOrderUserCount(null);
  240 + reqVO.setVirtualGroup(null);
  241 + reqVO.setStatus(null);
  242 + reqVO.setLimitDuration(null);
  243 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  244 +
  245 + // 调用
  246 + List<CombinationActivityDO> list = combinationActivityService.getCombinationActivityList(reqVO);
  247 + // 断言
  248 + assertEquals(1, list.size());
  249 + assertPojoEquals(dbCombinationActivity, list.get(0));
  250 + }
  251 +
  252 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql
... ... @@ -5,3 +5,4 @@ DELETE FROM &quot;promotion_reward_activity&quot;;
5 5 DELETE FROM "promotion_discount_activity";
6 6 DELETE FROM "promotion_discount_product";
7 7 DELETE FROM "promotion_seckill_config";
  8 +DELETE FROM "promotion_combination_activity";
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql
1   -CREATE TABLE IF NOT EXISTS "market_activity" (
2   - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
3   - "title" varchar(50) NOT NULL,
4   - "activity_type" tinyint(4) NOT NULL,
5   - "status" tinyint(4) NOT NULL,
6   - "start_time" datetime NOT NULL,
7   - "end_time" datetime NOT NULL,
8   - "invalid_time" datetime,
9   - "delete_time" datetime,
  1 +CREATE TABLE IF NOT EXISTS "market_activity"
  2 +(
  3 + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  4 + "title" varchar(50) NOT NULL,
  5 + "activity_type" tinyint(4) NOT NULL,
  6 + "status" tinyint(4) NOT NULL,
  7 + "start_time" datetime NOT NULL,
  8 + "end_time" datetime NOT NULL,
  9 + "invalid_time" datetime,
  10 + "delete_time" datetime,
10 11 "time_limited_discount" varchar(2000),
11   - "full_privilege" varchar(2000),
12   - "creator" varchar(64) DEFAULT '',
13   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
14   - "updater" varchar(64) DEFAULT '',
15   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
16   - "deleted" bit NOT NULL DEFAULT FALSE,
17   - "tenant_id" bigint(20) NOT NULL,
  12 + "full_privilege" varchar(2000),
  13 + "creator" varchar(64) DEFAULT '',
  14 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  15 + "updater" varchar(64) DEFAULT '',
  16 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  17 + "deleted" bit NOT NULL DEFAULT FALSE,
  18 + "tenant_id" bigint(20) NOT NULL,
18 19 PRIMARY KEY ("id")
19   - ) COMMENT '促销活动';
  20 +) COMMENT '促销活动';
20 21  
21   -CREATE TABLE IF NOT EXISTS "promotion_coupon_template" (
22   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
23   - "name" varchar NOT NULL,
24   - "status" int NOT NULL,
25   - "total_count" int NOT NULL,
26   - "take_limit_count" int NOT NULL,
27   - "take_type" int NOT NULL,
28   - "use_price" int NOT NULL,
29   - "product_scope" int NOT NULL,
30   - "product_spu_ids" varchar,
31   - "validity_type" int NOT NULL,
32   - "valid_start_time" datetime,
33   - "valid_end_time" datetime,
34   - "fixed_start_term" int,
35   - "fixed_end_term" int,
36   - "discount_type" int NOT NULL,
37   - "discount_percent" int,
38   - "discount_price" int,
39   - "discount_limit_price" int,
40   - "take_count" int NOT NULL DEFAULT 0,
41   - "use_count" int NOT NULL DEFAULT 0,
42   - "creator" varchar DEFAULT '',
43   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
44   - "updater" varchar DEFAULT '',
45   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
46   - "deleted" bit NOT NULL DEFAULT FALSE,
47   - PRIMARY KEY ("id")
  22 +CREATE TABLE IF NOT EXISTS "promotion_coupon_template"
  23 +(
  24 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  25 + "name" varchar NOT NULL,
  26 + "status" int NOT NULL,
  27 + "total_count" int NOT NULL,
  28 + "take_limit_count" int NOT NULL,
  29 + "take_type" int NOT NULL,
  30 + "use_price" int NOT NULL,
  31 + "product_scope" int NOT NULL,
  32 + "product_spu_ids" varchar,
  33 + "validity_type" int NOT NULL,
  34 + "valid_start_time" datetime,
  35 + "valid_end_time" datetime,
  36 + "fixed_start_term" int,
  37 + "fixed_end_term" int,
  38 + "discount_type" int NOT NULL,
  39 + "discount_percent" int,
  40 + "discount_price" int,
  41 + "discount_limit_price" int,
  42 + "take_count" int NOT NULL DEFAULT 0,
  43 + "use_count" int NOT NULL DEFAULT 0,
  44 + "creator" varchar DEFAULT '',
  45 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  46 + "updater" varchar DEFAULT '',
  47 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  48 + "deleted" bit NOT NULL DEFAULT FALSE,
  49 + PRIMARY KEY ("id")
48 50 ) COMMENT '优惠劵模板';
49 51  
50   -CREATE TABLE IF NOT EXISTS "promotion_coupon" (
51   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
52   - "template_id" bigint NOT NULL,
53   - "name" varchar NOT NULL,
54   - "status" int NOT NULL,
55   - "user_id" bigint NOT NULL,
56   - "take_type" int NOT NULL,
57   - "useprice" int NOT NULL,
58   - "valid_start_time" datetime NOT NULL,
59   - "valid_end_time" datetime NOT NULL,
60   - "product_scope" int NOT NULL,
61   - "product_spu_ids" varchar,
62   - "discount_type" int NOT NULL,
63   - "discount_percent" int,
64   - "discount_price" int,
  52 +CREATE TABLE IF NOT EXISTS "promotion_coupon"
  53 +(
  54 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  55 + "template_id" bigint NOT NULL,
  56 + "name" varchar NOT NULL,
  57 + "status" int NOT NULL,
  58 + "user_id" bigint NOT NULL,
  59 + "take_type" int NOT NULL,
  60 + "useprice" int NOT NULL,
  61 + "valid_start_time" datetime NOT NULL,
  62 + "valid_end_time" datetime NOT NULL,
  63 + "product_scope" int NOT NULL,
  64 + "product_spu_ids" varchar,
  65 + "discount_type" int NOT NULL,
  66 + "discount_percent" int,
  67 + "discount_price" int,
65 68 "discount_limit_price" int,
66   - "use_order_id" bigint,
67   - "use_time" datetime,
68   - "creator" varchar DEFAULT '',
69   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
70   - "updater" varchar DEFAULT '',
71   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
72   - "deleted" bit NOT NULL DEFAULT FALSE,
  69 + "use_order_id" bigint,
  70 + "use_time" datetime,
  71 + "creator" varchar DEFAULT '',
  72 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  73 + "updater" varchar DEFAULT '',
  74 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  75 + "deleted" bit NOT NULL DEFAULT FALSE,
73 76 PRIMARY KEY ("id")
74 77 ) COMMENT '优惠劵';
75 78  
76   -CREATE TABLE IF NOT EXISTS "promotion_reward_activity" (
77   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
78   - "name" varchar NOT NULL,
79   - "status" int NOT NULL,
80   - "start_time" datetime NOT NULL,
81   - "end_time" datetime NOT NULL,
82   - "remark" varchar,
83   - "condition_type" int NOT NULL,
84   - "product_scope" int NOT NULL,
85   - "product_spu_ids" varchar,
86   - "rules" varchar,
87   - "creator" varchar DEFAULT '',
88   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
89   - "updater" varchar DEFAULT '',
90   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
91   - "deleted" bit NOT NULL DEFAULT FALSE,
92   - PRIMARY KEY ("id")
  79 +CREATE TABLE IF NOT EXISTS "promotion_reward_activity"
  80 +(
  81 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  82 + "name" varchar NOT NULL,
  83 + "status" int NOT NULL,
  84 + "start_time" datetime NOT NULL,
  85 + "end_time" datetime NOT NULL,
  86 + "remark" varchar,
  87 + "condition_type" int NOT NULL,
  88 + "product_scope" int NOT NULL,
  89 + "product_spu_ids" varchar,
  90 + "rules" varchar,
  91 + "creator" varchar DEFAULT '',
  92 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  93 + "updater" varchar DEFAULT '',
  94 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  95 + "deleted" bit NOT NULL DEFAULT FALSE,
  96 + PRIMARY KEY ("id")
93 97 ) COMMENT '满减送活动';
94 98  
95   -CREATE TABLE IF NOT EXISTS "promotion_discount_activity" (
96   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
97   - "name" varchar NOT NULL,
98   - "status" int NOT NULL,
99   - "start_time" datetime NOT NULL,
100   - "end_time" datetime NOT NULL,
101   - "remark" varchar,
102   - "creator" varchar DEFAULT '',
103   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
104   - "updater" varchar DEFAULT '',
105   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
106   - "deleted" bit NOT NULL DEFAULT FALSE,
107   - PRIMARY KEY ("id")
  99 +CREATE TABLE IF NOT EXISTS "promotion_discount_activity"
  100 +(
  101 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  102 + "name" varchar NOT NULL,
  103 + "status" int NOT NULL,
  104 + "start_time" datetime NOT NULL,
  105 + "end_time" datetime NOT NULL,
  106 + "remark" varchar,
  107 + "creator" varchar DEFAULT '',
  108 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  109 + "updater" varchar DEFAULT '',
  110 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  111 + "deleted" bit NOT NULL DEFAULT FALSE,
  112 + PRIMARY KEY ("id")
108 113 ) COMMENT '限时折扣活动';
109 114  
110 115 -- 将该建表 SQL 语句,添加到 yudao-module-promotion-biz 模块的 test/resources/sql/create_tables.sql 文件里
111   -CREATE TABLE IF NOT EXISTS "promotion_seckill_activity" (
112   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
113   - "spu_id" bigint NOT NULL,
114   - "name" varchar NOT NULL,
115   - "status" int NOT NULL,
116   - "remark" varchar,
117   - "start_time" varchar NOT NULL,
118   - "end_time" varchar NOT NULL,
119   - "sort" int NOT NULL,
120   - "config_ids" varchar NOT NULL,
121   - "order_count" int NOT NULL,
122   - "user_count" int NOT NULL,
123   - "total_price" int NOT NULL,
124   - "total_limit_count" int,
  116 +CREATE TABLE IF NOT EXISTS "promotion_seckill_activity"
  117 +(
  118 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  119 + "spu_id" bigint NOT NULL,
  120 + "name" varchar NOT NULL,
  121 + "status" int NOT NULL,
  122 + "remark" varchar,
  123 + "start_time" varchar NOT NULL,
  124 + "end_time" varchar NOT NULL,
  125 + "sort" int NOT NULL,
  126 + "config_ids" varchar NOT NULL,
  127 + "order_count" int NOT NULL,
  128 + "user_count" int NOT NULL,
  129 + "total_price" int NOT NULL,
  130 + "total_limit_count" int,
125 131 "single_limit_count" int,
126   - "stock" int,
127   - "total_stock" int,
128   - "creator" varchar DEFAULT '',
129   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
130   - "updater" varchar DEFAULT '',
131   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
132   - "deleted" bit NOT NULL DEFAULT FALSE,
133   - "tenant_id" bigint NOT NULL,
  132 + "stock" int,
  133 + "total_stock" int,
  134 + "creator" varchar DEFAULT '',
  135 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  136 + "updater" varchar DEFAULT '',
  137 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  138 + "deleted" bit NOT NULL DEFAULT FALSE,
  139 + "tenant_id" bigint NOT NULL,
134 140 PRIMARY KEY ("id")
135 141 ) COMMENT '秒杀活动';
136 142  
137   -CREATE TABLE IF NOT EXISTS "promotion_seckill_config" (
138   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
139   - "name" varchar NOT NULL,
140   - "start_time" varchar NOT NULL,
141   - "end_time" varchar NOT NULL,
142   - "pic_url" varchar NOT NULL,
143   - "status" int NOT NULL,
144   - "creator" varchar DEFAULT '',
  143 +CREATE TABLE IF NOT EXISTS "promotion_seckill_config"
  144 +(
  145 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  146 + "name" varchar NOT NULL,
  147 + "start_time" varchar NOT NULL,
  148 + "end_time" varchar NOT NULL,
  149 + "pic_url" varchar NOT NULL,
  150 + "status" int NOT NULL,
  151 + "creator" varchar DEFAULT '',
145 152 "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
146   - "updater" varchar DEFAULT '',
  153 + "updater" varchar DEFAULT '',
147 154 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
148   - "deleted" bit NOT NULL DEFAULT FALSE,
149   - "tenant_id" bigint NOT NULL,
  155 + "deleted" bit NOT NULL DEFAULT FALSE,
  156 + "tenant_id" bigint NOT NULL,
150 157 PRIMARY KEY ("id")
151 158 ) COMMENT '秒杀时段配置';
  159 +
  160 +CREATE TABLE IF NOT EXISTS "promotion_combination_activity"
  161 +(
  162 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  163 + "name" varchar NOT NULL,
  164 + "spu_id" bigint,
  165 + "total_limit_count" int NOT NULL,
  166 + "single_limit_count" int NOT NULL,
  167 + "start_time" varchar NOT NULL,
  168 + "end_time" varchar NOT NULL,
  169 + "user_size" int NOT NULL,
  170 + "total_num" int NOT NULL,
  171 + "success_num" int NOT NULL,
  172 + "order_user_count" int NOT NULL,
  173 + "virtual_group" int NOT NULL,
  174 + "status" int NOT NULL,
  175 + "limit_duration" int NOT NULL,
  176 + "creator" varchar DEFAULT '',
  177 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  178 + "updater" varchar DEFAULT '',
  179 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  180 + "deleted" bit NOT NULL DEFAULT FALSE,
  181 + "tenant_id" bigint NOT NULL,
  182 + PRIMARY KEY ("id")
  183 +) COMMENT '拼团活动';
152 184 \ No newline at end of file
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
... ... @@ -27,6 +27,10 @@ public interface ErrorCodeConstants {
27 27 ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配");
28 28 ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态");
29 29 ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态");
  30 + ErrorCode ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单不是【已完成】状态");
  31 + ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000020, "创建交易订单项的评价失败,订单已评价");
  32 + ErrorCode ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE = new ErrorCode(1011000021, "交易订单发货失败,订单已退款或部分退款");
  33 + ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功");
30 34  
31 35 // ========== After Sale 模块 1011000100 ==========
32 36 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");
... ... @@ -63,8 +67,12 @@ public interface ErrorCodeConstants {
63 67 ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在");
64 68  
65 69 // ========== 物流 PICK_UP 模块 1011006000 ==========
66   -
67 70 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在");
68 71  
  72 + // ========== 物流 PICK_UP 模块 1011007000 ==========
  73 + // TODO @puhui999:这几个错误码,应该属于订单哈
  74 + ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011007000, "订单发货失败,请选择发货商品");
  75 + ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011007001, "订单发货失败,所选发货商品不存在");
  76 + ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007002, "订单发货失败,所选商品已发货");
69 77  
70 78 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java
1 1 package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
2 2  
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
3 5 import io.swagger.v3.oas.annotations.media.Schema;
4 6 import lombok.Data;
5 7  
6   -import javax.validation.constraints.NotEmpty;
7 8 import javax.validation.constraints.NotNull;
  9 +import java.util.List;
8 10  
9 11 @Schema(description = "管理后台 - 订单发货 Request VO")
10 12 @Data
... ... @@ -14,12 +16,26 @@ public class TradeOrderDeliveryReqVO {
14 16 @NotNull(message = "订单编号不能为空")
15 17 private Long id;
16 18  
17   - @Schema(description = "发货物流公司编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
18   - @NotNull(message = "发货物流公司编号不能为空")
  19 + @Schema(description = "发货类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  20 + @InEnum(DeliveryTypeEnum.class)
  21 + @NotNull(message = "发货类型不能为空")
  22 + private Integer type;
  23 +
  24 + // TODO @puhui999:还是要校验下
  25 +
  26 + @Schema(description = "发货物流公司编号", example = "1")
19 27 private Long logisticsId;
20 28  
21   - @Schema(description = "发货物流单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "SF123456789")
22   - @NotEmpty(message = "发货物流单号不能为空")
  29 + @Schema(description = "发货物流单号", example = "SF123456789")
23 30 private String logisticsNo;
24 31  
  32 + // TODO 订单项商品单独发货;不做单独发
  33 +
  34 + @Schema(description = "发货订单项", example = "[1,2,3]")
  35 + @NotNull(message = "发货订单项不能为空")
  36 + private List<Long> orderItemIds;
  37 +
  38 + // =============== 同城配送 ================
  39 + // TODO
  40 +
25 41 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
... ... @@ -4,8 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
6 6 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
7   -import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
8   -import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
9 7 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
10 8 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
11 9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
... ... @@ -30,13 +28,10 @@ import javax.validation.Valid;
30 28 import java.util.List;
31 29 import java.util.Map;
32 30  
33   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
34 31 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
35 32 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
36 33 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
37 34 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
38   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
39   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
40 35  
41 36 @Tag(name = "用户 App - 交易订单")
42 37 @RestController
... ... @@ -47,13 +42,9 @@ public class AppTradeOrderController {
47 42  
48 43 @Resource
49 44 private TradeOrderService tradeOrderService;
50   -
51 45 @Resource
52 46 private ProductPropertyValueApi productPropertyValueApi;
53 47 @Resource
54   - private ProductCommentApi productCommentApi;
55   -
56   - @Resource
57 48 private TradeOrderProperties tradeOrderProperties;
58 49  
59 50 @GetMapping("/settlement")
... ... @@ -117,13 +108,17 @@ public class AppTradeOrderController {
117 108 // 全部
118 109 orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null));
119 110 // 待付款(未支付)
120   - orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNPAID.getStatus(), null));
  111 + orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(),
  112 + TradeOrderStatusEnum.UNPAID.getStatus(), null));
121 113 // 待发货
122   - orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
  114 + orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
  115 + TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
123 116 // 待收货
124   - orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null));
  117 + orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
  118 + TradeOrderStatusEnum.DELIVERED.getStatus(), null));
125 119 // 待评价
126   - orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false));
  120 + orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(),
  121 + TradeOrderStatusEnum.COMPLETED.getStatus(), false));
127 122 return success(orderCount);
128 123 }
129 124  
... ... @@ -164,22 +159,7 @@ public class AppTradeOrderController {
164 159 @PostMapping("/item/create-comment")
165 160 @Operation(summary = "创建交易订单项的评价")
166 161 public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
167   - // TODO @puhui999:这个逻辑,最好写到 service 哈;
168   - Long loginUserId = getLoginUserId();
169   - // 先通过订单项 ID 查询订单项是否存在
170   - TradeOrderItemDO orderItemDO = tradeOrderService.getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
171   - if (orderItemDO == null) {
172   - throw exception(ORDER_ITEM_NOT_FOUND);
173   - }
174   - // 校验订单
175   - TradeOrderDO orderDO = tradeOrderService.getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
176   - if (orderDO == null) {
177   - throw exception(ORDER_NOT_FOUND);
178   - }
179   - // TODO @puhui999:要校验订单已完成,但是未评价;
180   -
181   - ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
182   - return success(productCommentApi.createComment(productCommentCreateReqDTO));
  162 + return success(tradeOrderService.createOrderItemComment(createReqVO));
183 163 }
184 164  
185 165 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo;
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 4 import cn.iocoder.yudao.framework.common.validation.Mobile;
5 5 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
6   -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
7 6 import com.fasterxml.jackson.annotation.JsonIgnore;
8 7 import io.swagger.v3.oas.annotations.media.Schema;
9 8 import lombok.Data;
... ... @@ -19,11 +18,6 @@ import java.util.List;
19 18 @Data
20 19 public class AppTradeOrderSettlementReqVO {
21 20  
22   - @NotNull(message = "交易类型不能为空")
23   - @InEnum(value = TradeOrderTypeEnum.class, message = "交易类型必须是 {value}")
24   - @Deprecated // TODO 芋艿:后续干掉这个字段,对于前端不需要关注这个
25   - private Integer type = 1;
26   -
27 21 @Schema(description = "商品项数组", requiredMode = Schema.RequiredMode.REQUIRED)
28 22 @NotEmpty(message = "商品不能为空")
29 23 private List<Item> items;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java
... ... @@ -19,11 +19,6 @@ public class AppTradeOrderItemCommentCreateReqVO {
19 19 @NotNull(message = "交易订单项编号不能为空")
20 20 private Long orderItemId;
21 21  
22   - // TODO @puhui999:貌似不用这个字段哈;
23   - @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
24   - @NotNull(message = "评分星级 1-5 分不能为空")
25   - private Integer scores;
26   -
27 22 @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
28 23 @NotNull(message = "描述星级 1-5 分不能为空")
29 24 private Integer descriptionScores;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
... ... @@ -13,10 +13,12 @@ import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
13 13 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
14 14 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
15 15 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
  16 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
16 17 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
17 18 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
18 19 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
19 20 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
  21 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
20 22 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
21 23 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
22 24 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
... ... @@ -25,6 +27,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
25 27 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
26 28 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
27 29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  30 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
28 31 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
29 32 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
30 33 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
... ... @@ -52,7 +55,6 @@ public interface TradeOrderConvert {
52 55 @Mapping(source = "createReqVO.couponId", target = "couponId"),
53 56 @Mapping(target = "remark", ignore = true),
54 57 @Mapping(source = "createReqVO.remark", target = "userRemark"),
55   - @Mapping(source = "createReqVO.type", target = "type"),
56 58 @Mapping(source = "calculateRespBO.price.totalPrice", target = "totalPrice"),
57 59 @Mapping(source = "calculateRespBO.price.discountPrice", target = "discountPrice"),
58 60 @Mapping(source = "calculateRespBO.price.deliveryPrice", target = "deliveryPrice"),
... ... @@ -123,7 +125,7 @@ public interface TradeOrderConvert {
123 125 // TODO 芋艿:可简化
124 126 default PageResult<TradeOrderPageItemRespVO> convertPage(PageResult<TradeOrderDO> pageResult, List<TradeOrderItemDO> orderItems,
125 127 List<ProductPropertyValueDetailRespDTO> propertyValueDetails,
126   - Map<Long,MemberUserRespDTO> memberUserRespDTOMap) {
  128 + Map<Long, MemberUserRespDTO> memberUserRespDTOMap) {
127 129 Map<Long, List<TradeOrderItemDO>> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId);
128 130 Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId);
129 131 // 转化 List
... ... @@ -267,23 +269,23 @@ public interface TradeOrderConvert {
267 269  
268 270 AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
269 271  
270   - @Mapping(target = "skuId", source = "tradeOrderItemDO.skuId")
271   - @Mapping(target = "orderId", source = "tradeOrderItemDO.orderId")
272   - @Mapping(target = "orderItemId", source = "tradeOrderItemDO.id")
273   - @Mapping(target = "scores", source = "createReqVO.scores")
274   - @Mapping(target = "descriptionScores", source = "createReqVO.descriptionScores")
275   - @Mapping(target = "benefitScores", source = "createReqVO.benefitScores")
276   - @Mapping(target = "content", source = "createReqVO.content")
277   - @Mapping(target = "picUrls", source = "createReqVO.picUrls")
278   - @Mapping(target = "anonymous", source = "createReqVO.anonymous")
279   - @Mapping(target = "userId", source = "tradeOrderItemDO.userId")
  272 + @Mappings({
  273 + @Mapping(target = "skuId", source = "tradeOrderItemDO.skuId"),
  274 + @Mapping(target = "orderId", source = "tradeOrderItemDO.orderId"),
  275 + @Mapping(target = "orderItemId", source = "tradeOrderItemDO.id"),
  276 + @Mapping(target = "descriptionScores", source = "createReqVO.descriptionScores"),
  277 + @Mapping(target = "benefitScores", source = "createReqVO.benefitScores"),
  278 + @Mapping(target = "content", source = "createReqVO.content"),
  279 + @Mapping(target = "picUrls", source = "createReqVO.picUrls"),
  280 + @Mapping(target = "anonymous", source = "createReqVO.anonymous"),
  281 + @Mapping(target = "userId", source = "tradeOrderItemDO.userId")
  282 + })
280 283 ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItemDO);
281 284  
282 285 default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
283 286 List<TradeCartDO> cartList) {
284 287 TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO();
285   - reqBO.setUserId(userId).setType(settlementReqVO.getType())
286   - .setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId())
  288 + reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId())
287 289 .setItems(new ArrayList<>(settlementReqVO.getItems().size()));
288 290 // 商品项的构建
289 291 Map<Long, TradeCartDO> cartMap = convertMap(cartList, TradeCartDO::getId);
... ... @@ -318,4 +320,31 @@ public interface TradeOrderConvert {
318 320  
319 321 AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
320 322  
  323 + @Mappings({
  324 + @Mapping(target = "activityId", source = "createReqVO.combinationActivityId"),
  325 + @Mapping(target = "spuId", source = "orderItem.spuId"),
  326 + @Mapping(target = "skuId", source = "orderItem.skuId"),
  327 + @Mapping(target = "userId", source = "order.userId"),
  328 + @Mapping(target = "orderId", source = "order.id"),
  329 + @Mapping(target = "headId", source = "createReqVO.combinationHeadId"),
  330 + @Mapping(target = "spuName", source = "orderItem.spuName"),
  331 + @Mapping(target = "picUrl", source = "orderItem.picUrl"),
  332 + @Mapping(target = "combinationPrice", source = "orderItem.payPrice"),
  333 + @Mapping(target = "nickname", source = "user.nickname"),
  334 + @Mapping(target = "avatar", source = "user.avatar"),
  335 + @Mapping(target = "status", ignore = true)
  336 + })
  337 + CombinationRecordReqDTO convert(TradeOrderDO order, TradeOrderItemDO orderItem, AppTradeOrderCreateReqVO createReqVO, MemberUserRespDTO user);
  338 +
  339 + TradeOrderDeliveryDO covert(Long orderId, Long orderItemId, Long userId, Integer deliveryType, Long logisticsId, String logisticsNo);
  340 +
  341 + default List<TradeOrderDeliveryDO> covert(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  342 + ArrayList<TradeOrderDeliveryDO> arrayList = new ArrayList<>();
  343 + deliveryReqVO.getOrderItemIds().forEach(item -> {
  344 + arrayList.add(covert(order.getId(), item, order.getUserId(), deliveryReqVO.getType(),
  345 + deliveryReqVO.getLogisticsId(), deliveryReqVO.getLogisticsNo()));
  346 + });
  347 + return arrayList;
  348 + }
  349 +
321 350 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDeliveryDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.dataobject.order;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +// TODO @puhui999:
  10 +/**
  11 + * 交易订单发货记录 DO
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@TableName("trade_order_delivery")
  16 +@KeySequence("trade_order_delivery_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class TradeOrderDeliveryDO extends BaseDO {
  24 +
  25 + /**
  26 + * 订单发货记录 id
  27 + */
  28 + private Long id;
  29 + /**
  30 + * 订单 id
  31 + */
  32 + private Long orderId;
  33 + /**
  34 + * 订单项 id TODO 要不要一个发货记录可对应多个订单项?
  35 + */
  36 + private Long orderItemId;
  37 + /**
  38 + * 用户编号
  39 + *
  40 + * 关联 MemberUserDO 的 id 编号
  41 + */
  42 + private Long userId;
  43 + /**
  44 + * 配送方式
  45 + *
  46 + * 枚举 {@link DeliveryTypeEnum}
  47 + */
  48 + private Integer deliveryType;
  49 + /**
  50 + * 发货物流公司编号
  51 + */
  52 + private Long logisticsId;
  53 + /**
  54 + * 发货物流单号
  55 + */
  56 + private String logisticsNo;
  57 +
  58 + // TODO 同城配送
  59 +
  60 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderDeliveryMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.order;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +// TODO @puhui999:应该去掉啦
  11 +/**
  12 + * 交易订单发货记录 Mapper
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Mapper
  17 +public interface TradeOrderDeliveryMapper extends BaseMapperX<TradeOrderDeliveryDO> {
  18 +
  19 + default List<TradeOrderDeliveryDO> selsectListByOrderIdAndItemIds(Long orderId, List<Long> orderItemIds) {
  20 + return selectList(new LambdaQueryWrapperX<TradeOrderDeliveryDO>()
  21 + .eq(TradeOrderDeliveryDO::getOrderId, orderId).in(TradeOrderDeliveryDO::getOrderItemId, orderItemIds));
  22 + }
  23 +
  24 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreate
7 7 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
8 8 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
9 9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
  10 +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
10 11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
11 12 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
12 13  
... ... @@ -177,4 +178,13 @@ public interface TradeOrderService {
177 178 * @return 得到订单
178 179 */
179 180 TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId);
  181 +
  182 + /**
  183 + * 创建订单项的评论
  184 + *
  185 + * @param createReqVO 创建请求
  186 + * @return 得到评价 id
  187 + */
  188 + Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO);
  189 +
180 190 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
... ... @@ -17,24 +17,30 @@ import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
17 17 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
18 18 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
19 19 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
  20 +import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
  21 +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
20 22 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
21 23 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
  24 +import cn.iocoder.yudao.module.promotion.api.combination.CombinationApi;
22 25 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
23 26 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
  27 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
24 28 import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
25 29 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
26   -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
27 30 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
28 31 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
29 32 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
30 33 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
31 34 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
32 35 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
  36 +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
33 37 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
34 38 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
35 39 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
36 40 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  41 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDeliveryDO;
37 42 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
  43 +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderDeliveryMapper;
38 44 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
39 45 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
40 46 import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
... ... @@ -57,6 +63,7 @@ import java.util.*;
57 63 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
58 64 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
59 65 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
  66 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
60 67 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
61 68 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
62 69  
... ... @@ -93,13 +100,17 @@ public class TradeOrderServiceImpl implements TradeOrderService {
93 100 @Resource
94 101 private MemberUserApi memberUserApi;
95 102 @Resource
96   - private AdminUserApi adminUserApi;
  103 + private ProductCommentApi productCommentApi;
97 104 @Resource
98 105 private NotifyMessageSendApi notifyMessageSendApi;
99 106  
100 107 @Resource
101 108 private TradeOrderProperties tradeOrderProperties;
102 109  
  110 + @Resource
  111 + private CombinationApi combinationApi;
  112 + @Resource
  113 + private TradeOrderDeliveryMapper orderDeliveryMapper;
103 114 // =================== Order ===================
104 115  
105 116 @Override
... ... @@ -153,19 +164,27 @@ public class TradeOrderServiceImpl implements TradeOrderService {
153 164 @Override
154 165 @Transactional(rollbackFor = Exception.class)
155 166 public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
156   - // 1. 用户收件地址的校验
157   - AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId());
158   -
159 167 // 2. 价格计算
160 168 TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
161   -
162 169 // 3.1 插入 TradeOrderDO 订单
163   - TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO, address);
  170 + TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
164 171 // 3.2 插入 TradeOrderItemDO 订单项
165 172 List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
166   -
167 173 // 订单创建完后的逻辑
168 174 afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
  175 + // 3.3 校验订单类型
  176 + // 拼团
  177 + if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  178 + MemberUserRespDTO user = memberUserApi.getUser(userId);
  179 + // TODO 拼团一次应该只能选择一种规格的商品
  180 + combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
  181 + .setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
  182 + }
  183 + // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
  184 + if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
  185 +
  186 + }
  187 +
169 188 // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
170 189 return order;
171 190 }
... ... @@ -186,24 +205,47 @@ public class TradeOrderServiceImpl implements TradeOrderService {
186 205 }
187 206  
188 207 private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
189   - TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address) {
  208 + TradePriceCalculateRespBO calculateRespBO) {
  209 + // 用户选择物流配送的时候才需要填写收货地址
  210 + AddressRespDTO address = new AddressRespDTO();
  211 + if (ObjectUtil.equal(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  212 + // 用户收件地址的校验
  213 + address = validateAddress(userId, createReqVO.getAddressId());
  214 + }
190 215 TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address);
  216 + order.setType(validateActivity(createReqVO));
191 217 order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的;
192 218 order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
193   - order.setType(TradeOrderTypeEnum.NORMAL.getType());
194 219 order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
195 220 order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
196 221 order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源?
197 222 // 支付信息
198 223 order.setAdjustPrice(0).setPayStatus(false);
199 224 // 物流信息 TODO 芋艿:暂时写死物流方式;应该是前端选择的
200   - order.setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus());
  225 + order.setDeliveryType(createReqVO.getDeliveryType()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus());
201 226 // 退款信息
202 227 order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
203 228 tradeOrderMapper.insert(order);
204 229 return order;
205 230 }
206 231  
  232 + /**
  233 + * 校验活动,并返回订单类型
  234 + *
  235 + * @param createReqVO 请求参数
  236 + * @return 订单类型
  237 + */
  238 + private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {
  239 + if (createReqVO.getSeckillActivityId() != null) {
  240 + return TradeOrderTypeEnum.SECKILL.getType();
  241 + }
  242 + if (createReqVO.getCombinationActivityId() != null) {
  243 + return TradeOrderTypeEnum.COMBINATION.getType();
  244 + }
  245 + // TODO 砍价敬请期待
  246 + return TradeOrderTypeEnum.NORMAL.getType();
  247 + }
  248 +
207 249 private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) {
208 250 List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
209 251 tradeOrderItemMapper.insertBatch(orderItems);
... ... @@ -212,7 +254,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
212 254  
213 255 /**
214 256 * 执行创建完创建完订单后的逻辑
215   - * <p>
  257 + *
216 258 * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
217 259 *
218 260 * @param userId 用户编号
... ... @@ -254,6 +296,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
254 296 }
255 297  
256 298 @Override
  299 + @Transactional(rollbackFor = Exception.class)
257 300 public void updateOrderPaid(Long id, Long payOrderId) {
258 301 // 校验并获得交易订单(可支付)
259 302 KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);
... ... @@ -267,7 +310,12 @@ public class TradeOrderServiceImpl implements TradeOrderService {
267 310 if (updateCount == 0) {
268 311 throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
269 312 }
270   -
  313 + // 校验活动
  314 + // 1、拼团活动
  315 + if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  316 + // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
  317 + combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
  318 + }
271 319 // TODO 芋艿:发送订单变化的消息
272 320  
273 321 // TODO 芋艿:发送站内信
... ... @@ -277,7 +325,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
277 325  
278 326 /**
279 327 * 校验交易订单满足被支付的条件
280   - * <p>
  328 + *
281 329 * 1. 交易订单未支付
282 330 * 2. 支付单已支付
283 331 *
... ... @@ -308,7 +356,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
308 356 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
309 357 if (payOrder == null) {
310 358 log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId);
311   - throw exception(cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND);
  359 + throw exception(ORDER_NOT_FOUND);
312 360 }
313 361 // 校验支付单已支付
314 362 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
... ... @@ -331,29 +379,51 @@ public class TradeOrderServiceImpl implements TradeOrderService {
331 379 return new KeyValue<>(order, payOrder);
332 380 }
333 381  
334   - // TODO 芋艿:如果无需发货,需要怎么存储?
335 382 @Override
  383 + @Transactional(rollbackFor = Exception.class)
336 384 public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) {
337 385 // 校验并获得交易订单(可发货)
338 386 TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId());
339   - // TODO 芋艿:logisticsId 校验存在 发货物流公司 fix
340   - DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
341   - if (deliveryExpress == null) {
342   - throw exception(EXPRESS_NOT_EXISTS);
  387 +
  388 + TradeOrderDO tradeOrderDO = new TradeOrderDO();
  389 + List<TradeOrderDeliveryDO> deliveryDOs = new ArrayList<>();
  390 + /* TODO
  391 + * fix: 首先需要店铺设置配送方式如: 自提 、配送、物流-配送、物流-配送-自提、商家配送
  392 + * 1.如果店铺有设置配送方式用户只填写收货地址的情况下店家后台自己选择配送方式
  393 + * 2.如果店铺只支持到店自提那么下单后默认发货不需要物流
  394 + * 3.如果店铺支持 物流-配送-自提 的情况下后台不需要选择配送方式按前端用户选择的配送方式发货即可
  395 + */
  396 + // 判断发货类型
  397 + // 快递发货
  398 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  399 + deliveryDOs = express(order, deliveryReqVO);
  400 + tradeOrderDO.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
  401 + }
  402 + // 用户自提
  403 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
  404 + deliveryDOs = pickUp(order, deliveryReqVO);
  405 + // 重置一下确保快递公司和快递单号为空
  406 + tradeOrderDO.setLogisticsId(null).setLogisticsNo("");
  407 + }
  408 + // TODO 芋艿:如果无需发货,需要怎么存储?
  409 + if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
  410 + // TODO 情况一:正常走发货逻辑和用户自提有点像 不同点:不需要自提门店只需要用户确认收货
  411 + // TODO 情况二:用户下单付款后直接确认收货或等待用户确认收货
343 412 }
344 413  
345 414 // 更新 TradeOrderDO 状态为已发货,等待收货
346   - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),
347   - new TradeOrderDO().setStatus(TradeOrderStatusEnum.DELIVERED.getStatus())
348   - .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo())
349   - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now()));
  415 + tradeOrderDO.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus())
  416 + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now());
  417 + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), tradeOrderDO);
350 418 if (updateCount == 0) {
351 419 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
352 420 }
353   -
  421 + // 发货成功记录发货表
  422 + orderDeliveryMapper.insertBatch(deliveryDOs);
354 423 // TODO 芋艿:发送订单变化的消息
355 424  
356   - // TODO 芋艿:发送站内信 fix
  425 + // TODO @puhui999:可以抽个 message 包,里面是 Order 所有的 message;类似工作流的
  426 + // 发送站内信
357 427 // 1、构造消息
358 428 Map<String, Object> msgMap = new HashMap<>();
359 429 msgMap.put("orderId", deliveryReqVO.getId());
... ... @@ -364,16 +434,59 @@ public class TradeOrderServiceImpl implements TradeOrderService {
364 434 .setUserId(userId)
365 435 .setTemplateCode("order_delivery")
366 436 .setTemplateParams(msgMap));
367   - // TODO 芋艿:OrderLog
368 437  
369   - // TODO 设计:like:是否要单独一个 delivery 发货单表???
370   - // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞
  438 + // TODO 芋艿:OrderLog
371 439 // TODO 设计:lili:是不是发货后,才支持售后?
372 440 }
373 441  
  442 + private List<TradeOrderDeliveryDO> express(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  443 + // 校验快递公司
  444 + DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
  445 + if (deliveryExpress == null) {
  446 + throw exception(EXPRESS_NOT_EXISTS);
  447 + }
  448 + // 校验发货商品
  449 + validateDeliveryOrderItem(order, deliveryReqVO);
  450 + // 创建发货记录
  451 + return TradeOrderConvert.INSTANCE.covert(order, deliveryReqVO);
  452 + }
  453 +
  454 + private List<TradeOrderDeliveryDO> pickUp(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  455 + // TODO 校验自提门店是否存在
  456 + // 重置一下确保快递公司和快递单号为空
  457 + deliveryReqVO.setLogisticsId(null);
  458 + deliveryReqVO.setLogisticsNo("");
  459 + // 校验发货商品
  460 + validateDeliveryOrderItem(order, deliveryReqVO);
  461 + // 创建发货记录
  462 + return TradeOrderConvert.INSTANCE.covert(order, deliveryReqVO);
  463 + }
  464 +
  465 + private void validateDeliveryOrderItem(TradeOrderDO order, TradeOrderDeliveryReqVO deliveryReqVO) {
  466 + // TODO 设计:like:是否要单独一个 delivery 发货单表??? fix: 多商品可分开单独发货,添加 trade_order_delivery 交易订单发货日志表关联发货所选订单项设置物流单号
  467 + // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 fix
  468 + // 校验发货商品
  469 + if (CollUtil.isEmpty(deliveryReqVO.getOrderItemIds())) {
  470 + throw exception(ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY);
  471 + }
  472 + // 校验发货商品是否存在
  473 + List<TradeOrderItemDO> orderItemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId());
  474 + Set<Long> itemIds = convertSet(orderItemDOs, TradeOrderItemDO::getId);
  475 + if (!itemIds.containsAll(deliveryReqVO.getOrderItemIds())) {
  476 + throw exception(ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS);
  477 + }
  478 + // 校验所选订单项是否存在有已发货的
  479 + List<TradeOrderDeliveryDO> deliveryDOList = orderDeliveryMapper.selsectListByOrderIdAndItemIds(order.getId(), deliveryReqVO.getOrderItemIds());
  480 + if (CollUtil.isNotEmpty(deliveryDOList)) {
  481 + HashSet<Long> hashSet = CollUtil.newHashSet(deliveryReqVO.getOrderItemIds());
  482 + hashSet.retainAll(convertSet(deliveryDOList, TradeOrderDeliveryDO::getOrderItemId));
  483 + throw exception(ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY);
  484 + }
  485 + }
  486 +
374 487 /**
375 488 * 校验交易订单满足被发货的条件
376   - * <p>
  489 + *
377 490 * 1. 交易订单未发货
378 491 *
379 492 * @param id 交易订单编号
... ... @@ -390,6 +503,19 @@ public class TradeOrderServiceImpl implements TradeOrderService {
390 503 || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
391 504 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
392 505 }
  506 + // 校验订单是否退款
  507 + if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
  508 + throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
  509 + }
  510 + // 订单类型:拼团
  511 + if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  512 + // 校验订单拼团是否成功
  513 + // TODO 用户 ID 使用当前登录用户的还是订单保存的?
  514 + if (combinationApi.validateRecordStatusIsSuccess(order.getUserId(), order.getId())) {
  515 + throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
  516 + }
  517 + }
  518 + // TODO puhui999: 校验订单砍价是否成功
393 519 return order;
394 520 }
395 521  
... ... @@ -421,7 +547,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
421 547  
422 548 /**
423 549 * 校验交易订单满足可售货的条件
424   - * <p>
  550 + *
425 551 * 1. 交易订单待收货
426 552 *
427 553 * @param userId 用户编号
... ... @@ -556,6 +682,32 @@ public class TradeOrderServiceImpl implements TradeOrderService {
556 682 return tradeOrderMapper.selectOrderByIdAndUserId(orderId, loginUserId);
557 683 }
558 684  
  685 + @Override
  686 + public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) {
  687 + Long loginUserId = getLoginUserId();
  688 + // 先通过订单项 ID,查询订单项是否存在
  689 + TradeOrderItemDO orderItem = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
  690 + if (orderItem == null) {
  691 + throw exception(ORDER_ITEM_NOT_FOUND);
  692 + }
  693 + // 校验订单
  694 + TradeOrderDO order = getOrderByIdAndUserId(orderItem.getOrderId(), loginUserId);
  695 + if (order == null) {
  696 + throw exception(ORDER_NOT_FOUND);
  697 + }
  698 + if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
  699 + throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
  700 + }
  701 + if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) {
  702 + throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
  703 + }
  704 + // TODO @puhui999:是不是评论完,要更新 status、commentStatus;另外,是不是上面 order 可以不校验,直接只判断 orderItem 就够;
  705 + // 对于 order 来说,就是评论完,把 order 更新完合理的 status 等字段。
  706 +
  707 + ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
  708 + return productCommentApi.createComment(productCommentCreateReqDTO);
  709 + }
  710 +
559 711 /**
560 712 * 判断指定订单的所有订单项,是不是都售后成功
561 713 *
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java
... ... @@ -21,7 +21,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
21 21 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
22 22 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
23 23 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
24   -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
  24 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
25 25  
26 26 /**
27 27 * 价格计算 Service 实现类
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java
... ... @@ -33,7 +33,7 @@ public class AppAuthLoginReqVO {
33 33  
34 34 // ========== 绑定社交登录时,需要传递如下参数 ==========
35 35  
36   - @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  36 + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
37 37 @InEnum(SocialTypeEnum.class)
38 38 private Integer socialType;
39 39  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java
... ... @@ -35,7 +35,7 @@ public class AppAuthSmsLoginReqVO {
35 35  
36 36 // ========== 绑定社交登录时,需要传递如下参数 ==========
37 37  
38   - @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  38 + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
39 39 @InEnum(SocialTypeEnum.class)
40 40 private Integer socialType;
41 41  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class AppAuthSocialLoginReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class AppSocialUserBindReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class AppSocialUserUnbindReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java
... ... @@ -19,10 +19,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
19 19 import static org.junit.jupiter.api.Assertions.assertNull;
20 20  
21 21 /**
22   -* {@link AddressServiceImpl} 的单元测试类
23   -*
24   -* @author 芋道源码
25   -*/
  22 + * {@link AddressServiceImpl} 的单元测试类
  23 + *
  24 + * @author 芋道源码
  25 + */
26 26 @Import(AddressServiceImpl.class)
27 27 public class AddressServiceImplTest extends BaseDbUnitTest {
28 28  
... ... @@ -82,8 +82,8 @@ public class AddressServiceImplTest extends BaseDbUnitTest {
82 82  
83 83 // 调用
84 84 addressService.deleteAddress(dbAddress.getUserId(), id);
85   - // 校验数据不存在了
86   - assertNull(addressMapper.selectById(id));
  85 + // 校验数据不存在了
  86 + assertNull(addressMapper.selectById(id));
87 87 }
88 88  
89 89 @Test
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagPageReqVO.java
... ... @@ -18,7 +18,7 @@ public class MpTagPageReqVO extends PageParam {
18 18 @NotEmpty(message = "公众号账号的编号不能为空")
19 19 private Long accountId;
20 20  
21   - @Schema(description = "标签名 模糊匹配", example = "哈哈")
  21 + @Schema(description = "标签名,模糊匹配", example = "哈哈")
22 22 private String name;
23 23  
24 24 }
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java
... ... @@ -18,10 +18,10 @@ public class MpUserPageReqVO extends PageParam {
18 18 @NotNull(message = "公众号账号的编号不能为空")
19 19 private Long accountId;
20 20  
21   - @Schema(description = "公众号粉丝标识 模糊匹配", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M")
  21 + @Schema(description = "公众号粉丝标识,模糊匹配", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M")
22 22 private String openid;
23 23  
24   - @Schema(description = "公众号粉丝昵称 模糊匹配", example = "芋艿")
  24 + @Schema(description = "公众号粉丝昵称,模糊匹配", example = "芋艿")
25 25 private String nickname;
26 26  
27 27 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
... ... @@ -55,6 +55,7 @@ public class AuthController {
55 55 private PermissionService permissionService;
56 56 @Resource
57 57 private SocialUserService socialUserService;
  58 +
58 59 @Resource
59 60 private SecurityProperties securityProperties;
60 61  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class AuthSocialLoginReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java
... ... @@ -7,10 +7,10 @@ import lombok.Data;
7 7 @Data
8 8 public class DeptListReqVO {
9 9  
10   - @Schema(description = "部门名称,模糊匹配", example = "芋道")
  10 + @Schema(description = "部门名称,模糊匹配", example = "芋道")
11 11 private String name;
12 12  
13   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  13 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
14 14 private Integer status;
15 15  
16 16 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java
... ... @@ -14,7 +14,7 @@ public class DeptRespVO extends DeptBaseVO {
14 14 @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
15 15 private Long id;
16 16  
17   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
18 18 private Integer status;
19 19  
20 20 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java
... ... @@ -27,7 +27,7 @@ public class PostBaseVO {
27 27 @NotNull(message = "显示顺序不能为空")
28 28 private Integer sort;
29 29  
30   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  30 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
31 31 private Integer status;
32 32  
33 33 @Schema(description = "备注", example = "快乐的备注")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java
... ... @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post;
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6   -@Schema(description = "管理后台 - 岗位导出 Request VO,参数和 PostExcelVO 是一致的")
  6 +@Schema(description = "管理后台 - 岗位导出 Request VO,参数和 PostExcelVO 是一致的")
7 7 @Data
8 8 public class PostExportReqVO {
9 9  
10   - @Schema(description = "岗位编码,模糊匹配", example = "yudao")
  10 + @Schema(description = "岗位编码,模糊匹配", example = "yudao")
11 11 private String code;
12 12  
13   - @Schema(description = "岗位名称,模糊匹配", example = "芋道")
  13 + @Schema(description = "岗位名称,模糊匹配", example = "芋道")
14 14 private String name;
15 15  
16   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  16 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
17 17 private Integer status;
18 18  
19 19 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java
... ... @@ -9,10 +9,10 @@ import lombok.EqualsAndHashCode;
9 9 @EqualsAndHashCode(callSuper = true)
10 10 public class PostListReqVO extends PostBaseVO {
11 11  
12   - @Schema(description = "岗位名称,模糊匹配", example = "芋道")
  12 + @Schema(description = "岗位名称,模糊匹配", example = "芋道")
13 13 private String name;
14 14  
15   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  15 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
16 16 private Integer status;
17 17  
18 18 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java
... ... @@ -10,13 +10,13 @@ import lombok.EqualsAndHashCode;
10 10 @EqualsAndHashCode(callSuper = true)
11 11 public class PostPageReqVO extends PageParam {
12 12  
13   - @Schema(description = "岗位编码,模糊匹配", example = "yudao")
  13 + @Schema(description = "岗位编码,模糊匹配", example = "yudao")
14 14 private String code;
15 15  
16   - @Schema(description = "岗位名称,模糊匹配", example = "芋道")
  16 + @Schema(description = "岗位名称,模糊匹配", example = "芋道")
17 17 private String name;
18 18  
19   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  19 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
20 20 private Integer status;
21 21  
22 22 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java
... ... @@ -13,11 +13,11 @@ public class DictDataExportReqVO {
13 13 @Size(max = 100, message = "字典标签长度不能超过100个字符")
14 14 private String label;
15 15  
16   - @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
  16 + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
17 17 @Size(max = 100, message = "字典类型类型长度不能超过100个字符")
18 18 private String dictType;
19 19  
20   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  20 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
21 21 private Integer status;
22 22  
23 23 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java
... ... @@ -16,11 +16,11 @@ public class DictDataPageReqVO extends PageParam {
16 16 @Size(max = 100, message = "字典标签长度不能超过100个字符")
17 17 private String label;
18 18  
19   - @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
  19 + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
20 20 @Size(max = 100, message = "字典类型类型长度不能超过100个字符")
21 21 private String dictType;
22 22  
23   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  23 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
24 24 private Integer status;
25 25  
26 26 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java
... ... @@ -16,8 +16,9 @@ public class DictDataSimpleRespVO {
16 16 @Schema(description = "字典标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "男")
17 17 private String label;
18 18  
19   - @Schema(description = "颜色类型,default、primary、success、info、warning、danger", example = "default")
  19 + @Schema(description = "颜色类型,default、primary、success、info、warning、danger", example = "default")
20 20 private String colorType;
  21 +
21 22 @Schema(description = "css 样式", example = "btn-visible")
22 23 private String cssClass;
23 24  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java
... ... @@ -19,7 +19,7 @@ public class DictTypeBaseVO {
19 19 @Size(max = 100, message = "字典类型名称长度不能超过100个字符")
20 20 private String name;
21 21  
22   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
23 23 @NotNull(message = "状态不能为空")
24 24 private Integer status;
25 25  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java
... ... @@ -12,13 +12,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
12 12 @Data
13 13 public class DictTypeExportReqVO {
14 14  
15   - @Schema(description = "字典类型名称,模糊匹配", example = "芋道")
  15 + @Schema(description = "字典类型名称,模糊匹配", example = "芋道")
16 16 private String name;
17 17  
18   - @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
  18 + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
19 19 private String type;
20 20  
21   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  21 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
22 22 private Integer status;
23 23  
24 24 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java
... ... @@ -16,14 +16,14 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
16 16 @EqualsAndHashCode(callSuper = true)
17 17 public class DictTypePageReqVO extends PageParam {
18 18  
19   - @Schema(description = "字典类型名称,模糊匹配", example = "芋道")
  19 + @Schema(description = "字典类型名称,模糊匹配", example = "芋道")
20 20 private String name;
21 21  
22   - @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
  22 + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
23 23 @Size(max = 100, message = "字典类型类型长度不能超过100个字符")
24 24 private String type;
25 25  
26   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  26 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
27 27 private Integer status;
28 28  
29 29 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 错误码 Excel 导出 Request VO,参数和 InfErrorCodePageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 错误码 Excel 导出 Request VO,参数和 InfErrorCodePageReqVO 是一致的")
12 12 @Data
13 13 public class ErrorCodeExportReqVO {
14 14  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java
... ... @@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class ErrorCodePageReqVO extends PageParam {
19 19  
20   - @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", example = "1")
  20 + @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", example = "1")
21 21 private Integer type;
22 22  
23 23 @Schema(description = "应用名", example = "dashboard")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java
... ... @@ -16,7 +16,7 @@ public class ErrorCodeRespVO extends ErrorCodeBaseVO {
16 16 @Schema(description = "错误码编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17 17 private Long id;
18 18  
19   - @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 20 private Integer type;
21 21  
22 22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java
... ... @@ -15,7 +15,7 @@ import javax.validation.constraints.Size;
15 15 @Data
16 16 public class LoginLogBaseVO {
17 17  
18   - @Schema(description = "日志类型,参见 LoginLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @Schema(description = "日志类型,参见 LoginLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 19 @NotNull(message = "日志类型不能为空")
20 20 private Integer logType;
21 21  
... ... @@ -28,7 +28,7 @@ public class LoginLogBaseVO {
28 28 @Size(max = 30, message = "用户账号长度不能超过30个字符")
29 29 private String username;
30 30  
31   - @Schema(description = "登录结果,参见 LoginResultEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  31 + @Schema(description = "登录结果,参见 LoginResultEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
32 32 @NotNull(message = "登录结果不能为空")
33 33 private Integer result;
34 34  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java
... ... @@ -12,10 +12,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
12 12 @Data
13 13 public class LoginLogExportReqVO {
14 14  
15   - @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1")
  15 + @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1")
16 16 private String userIp;
17 17  
18   - @Schema(description = "用户账号,模拟匹配", example = "芋道")
  18 + @Schema(description = "用户账号,模拟匹配", example = "芋道")
19 19 private String username;
20 20  
21 21 @Schema(description = "操作状态", example = "true")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java
... ... @@ -15,10 +15,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 @EqualsAndHashCode(callSuper = true)
16 16 public class LoginLogPageReqVO extends PageParam {
17 17  
18   - @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1")
  18 + @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1")
19 19 private String userIp;
20 20  
21   - @Schema(description = "用户账号,模拟匹配", example = "芋道")
  21 + @Schema(description = "用户账号,模拟匹配", example = "芋道")
22 22 private String username;
23 23  
24 24 @Schema(description = "操作状态", example = "true")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java
... ... @@ -20,7 +20,7 @@ public class LoginLogRespVO extends LoginLogBaseVO {
20 20 @Schema(description = "用户编号", example = "666")
21 21 private Long userId;
22 22  
23   - @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  23 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
24 24 @NotNull(message = "用户类型不能为空")
25 25 private Integer userType;
26 26  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java
... ... @@ -31,7 +31,7 @@ public class OperateLogBaseVO {
31 31 @NotEmpty(message = "操作名")
32 32 private String name;
33 33  
34   - @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  34 + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
35 35 @NotNull(message = "操作分类不能为空")
36 36 private Integer type;
37 37  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java
... ... @@ -12,13 +12,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
12 12 @Data
13 13 public class OperateLogExportReqVO {
14 14  
15   - @Schema(description = "操作模块,模拟匹配", example = "订单")
  15 + @Schema(description = "操作模块,模拟匹配", example = "订单")
16 16 private String module;
17 17  
18   - @Schema(description = "用户昵称,模拟匹配", example = "芋道")
  18 + @Schema(description = "用户昵称,模拟匹配", example = "芋道")
19 19 private String userNickname;
20 20  
21   - @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1")
  21 + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1")
22 22 private Integer type;
23 23  
24 24 @Schema(description = "操作状态", example = "true")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java
... ... @@ -13,13 +13,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
13 13 @Data
14 14 public class OperateLogPageReqVO extends PageParam {
15 15  
16   - @Schema(description = "操作模块,模拟匹配", example = "订单")
  16 + @Schema(description = "操作模块,模拟匹配", example = "订单")
17 17 private String module;
18 18  
19   - @Schema(description = "用户昵称,模拟匹配", example = "芋道")
  19 + @Schema(description = "用户昵称,模拟匹配", example = "芋道")
20 20 private String userNickname;
21 21  
22   - @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1")
  22 + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1")
23 23 private Integer type;
24 24  
25 25 @Schema(description = "操作状态", example = "true")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java
... ... @@ -8,7 +8,7 @@ import lombok.ToString;
8 8 import javax.validation.constraints.NotNull;
9 9 import java.time.LocalDateTime;
10 10  
11   -@Schema(description ="管理后台 - 邮箱账号 Response VO")
  11 +@Schema(description = "管理后台 - 邮箱账号 Response VO")
12 12 @Data
13 13 @EqualsAndHashCode(callSuper = true)
14 14 @ToString(callSuper = true)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogBaseVO.java
... ... @@ -20,7 +20,7 @@ public class MailLogBaseVO {
20 20 @Schema(description = "用户编号", example = "30883")
21 21 private Long userId;
22 22  
23   - @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", example = "2")
  23 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", example = "2")
24 24 private Byte userType;
25 25  
26 26 @Schema(description = "接收邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "76854@qq.com")
... ... @@ -58,7 +58,7 @@ public class MailLogBaseVO {
58 58 @NotNull(message = "邮件参数不能为空")
59 59 private Map<String, Object> templateParams;
60 60  
61   - @Schema(description = "发送状态 - 参见 MailSendStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  61 + @Schema(description = "发送状态,参见 MailSendStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
62 62 @NotNull(message = "发送状态不能为空")
63 63 private Byte sendStatus;
64 64  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogPageReqVO.java
... ... @@ -20,10 +20,10 @@ public class MailLogPageReqVO extends PageParam {
20 20 @Schema(description = "用户编号", example = "30883")
21 21 private Long userId;
22 22  
23   - @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", example = "2")
  23 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", example = "2")
24 24 private Integer userType;
25 25  
26   - @Schema(description = "接收邮箱地址 模糊匹配", example = "76854@qq.com")
  26 + @Schema(description = "接收邮箱地址,模糊匹配", example = "76854@qq.com")
27 27 private String toMail;
28 28  
29 29 @Schema(description = "邮箱账号编号", example = "18107")
... ... @@ -32,7 +32,7 @@ public class MailLogPageReqVO extends PageParam {
32 32 @Schema(description = "模板编号", example = "5678")
33 33 private Long templateId;
34 34  
35   - @Schema(description = "发送状态 - 参见 MailSendStatusEnum 枚举", example = "1")
  35 + @Schema(description = "发送状态,参见 MailSendStatusEnum 枚举", example = "1")
36 36 private Integer sendStatus;
37 37  
38 38 @Schema(description = "发送时间")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateBaseVO.java
... ... @@ -36,7 +36,7 @@ public class MailTemplateBaseVO {
36 36 @NotEmpty(message = "内容不能为空")
37 37 private String content;
38 38  
39   - @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  39 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
40 40 @NotNull(message = "状态不能为空")
41 41 private Integer status;
42 42  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplatePageReqVO.java
... ... @@ -17,13 +17,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class MailTemplatePageReqVO extends PageParam {
19 19  
20   - @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", example = "1")
  20 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", example = "1")
21 21 private Integer status;
22 22  
23   - @Schema(description = "标识 - 模糊匹配", example = "code_1024")
  23 + @Schema(description = "标识,模糊匹配", example = "code_1024")
24 24 private String code;
25 25  
26   - @Schema(description = "名称 - 模糊匹配", example = "芋头")
  26 + @Schema(description = "名称,模糊匹配", example = "芋头")
27 27 private String name;
28 28  
29 29 @Schema(description = "账号编号", example = "2048")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java
... ... @@ -26,7 +26,7 @@ public class NoticeBaseVO {
26 26 @Schema(description = "公告内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "半生编码")
27 27 private String content;
28 28  
29   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  29 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
30 30 private Integer status;
31 31  
32 32 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java
... ... @@ -10,10 +10,10 @@ import lombok.EqualsAndHashCode;
10 10 @EqualsAndHashCode(callSuper = true)
11 11 public class NoticePageReqVO extends PageParam {
12 12  
13   - @Schema(description = "通知公告名称,模糊匹配", example = "芋道")
  13 + @Schema(description = "通知公告名称,模糊匹配", example = "芋道")
14 14 private String title;
15 15  
16   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  16 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
17 17 private Integer status;
18 18  
19 19 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageBaseVO.java
... ... @@ -21,7 +21,7 @@ public class NotifyMessageBaseVO {
21 21 @NotNull(message = "用户编号不能为空")
22 22 private Long userId;
23 23  
24   - @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  24 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 25 @NotNull(message = "用户类型不能为空")
26 26 private Byte userType;
27 27  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateBaseVO.java
... ... @@ -9,9 +9,9 @@ import javax.validation.constraints.NotEmpty;
9 9 import javax.validation.constraints.NotNull;
10 10  
11 11 /**
12   -* 站内信模版 Base VO,提供给添加、修改、详细的子 VO 使用
13   -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
14   -*/
  12 + * 站内信模版 Base VO,提供给添加、修改、详细的子 VO 使用
  13 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  14 + */
15 15 @Data
16 16 public class NotifyTemplateBaseVO {
17 17  
... ... @@ -23,7 +23,7 @@ public class NotifyTemplateBaseVO {
23 23 @NotNull(message = "模版编码不能为空")
24 24 private String code;
25 25  
26   - @Schema(description = "模版类型 - 对应 system_notify_template_type 字典", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + @Schema(description = "模版类型,对应 system_notify_template_type 字典", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
27 27 @NotNull(message = "模版类型不能为空")
28 28 private Integer type;
29 29  
... ... @@ -35,7 +35,7 @@ public class NotifyTemplateBaseVO {
35 35 @NotEmpty(message = "模版内容不能为空")
36 36 private String content;
37 37  
38   - @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  38 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
39 39 @NotNull(message = "状态不能为空")
40 40 @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
41 41 private Integer status;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplatePageReqVO.java
1 1 package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 4 import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.*;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
5 9  
6 10 import java.time.LocalDateTime;
7   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
8   -import org.springframework.format.annotation.DateTimeFormat;
9 11  
10 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
11 13  
... ... @@ -21,7 +23,7 @@ public class NotifyTemplatePageReqVO extends PageParam {
21 23 @Schema(description = "模版名称", example = "我是名称")
22 24 private String name;
23 25  
24   - @Schema(description = "状态 - 参见 CommonStatusEnum 枚举类", example = "1")
  26 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
25 27 private Integer status;
26 28  
27 29 @Schema(description = "创建时间")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java
... ... @@ -38,7 +38,7 @@ public class OAuth2ClientBaseVO {
38 38 @Schema(description = "应用描述", example = "我是一个应用")
39 39 private String description;
40 40  
41   - @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  41 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
42 42 @NotNull(message = "状态不能为空")
43 43 private Integer status;
44 44  
... ... @@ -55,7 +55,7 @@ public class OAuth2ClientBaseVO {
55 55 private List<@NotEmpty(message = "重定向的 URI 不能为空")
56 56 @URL(message = "重定向的 URI 格式不正确") String> redirectUris;
57 57  
58   - @Schema(description = "授权类型,参见 OAuth2GrantTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "password")
  58 + @Schema(description = "授权类型,参见 OAuth2GrantTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "password")
59 59 @NotNull(message = "授权类型不能为空")
60 60 private List<String> authorizedGrantTypes;
61 61  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java
... ... @@ -10,10 +10,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
10 10 @ToString(callSuper = true)
11 11 public class OAuth2ClientPageReqVO extends PageParam {
12 12  
13   - @Schema(description = "应用名,模糊匹配", example = "土豆")
  13 + @Schema(description = "应用名,模糊匹配", example = "土豆")
14 14 private String name;
15 15  
16   - @Schema(description = "状态,参见 CommonStatusEnum 枚举", example = "1")
  16 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", example = "1")
17 17 private Integer status;
18 18  
19 19 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java
... ... @@ -17,7 +17,7 @@ public class OAuth2OpenCheckTokenRespVO {
17 17 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
18 18 @JsonProperty("user_id")
19 19 private Long userId;
20   - @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  20 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
21 21 @JsonProperty("user_type")
22 22 private Integer userType;
23 23 @Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
... ... @@ -34,7 +34,7 @@ public class OAuth2OpenCheckTokenRespVO {
34 34 @JsonProperty("access_token")
35 35 private String accessToken;
36 36  
37   - @Schema(description = "过期时间,时间戳 / 1000,即单位:秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1593092157")
  37 + @Schema(description = "过期时间,时间戳 / 1000,即单位:秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1593092157")
38 38 private Long exp;
39 39  
40 40 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java
... ... @@ -13,7 +13,7 @@ public class OAuth2AccessTokenPageReqVO extends PageParam {
13 13 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
14 14 private Long userId;
15 15  
16   - @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  16 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
17 17 private Integer userType;
18 18  
19 19 @Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java
... ... @@ -25,7 +25,7 @@ public class OAuth2AccessTokenRespVO {
25 25 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
26 26 private Long userId;
27 27  
28   - @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  28 + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
29 29 private Integer userType;
30 30  
31 31 @Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java
... ... @@ -27,7 +27,7 @@ public class OAuth2UserInfoRespVO {
27 27 @Schema(description = "手机号码", example = "15601691300")
28 28 private String mobile;
29 29  
30   - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
  30 + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
31 31 private Integer sex;
32 32  
33 33 @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java
... ... @@ -28,7 +28,7 @@ public class OAuth2UserUpdateReqVO {
28 28 @Length(min = 11, max = 11, message = "手机号长度必须 11 位")
29 29 private String mobile;
30 30  
31   - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
  31 + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
32 32 private Integer sex;
33 33  
34 34 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java
... ... @@ -23,7 +23,7 @@ public class MenuBaseVO {
23 23 @Size(max = 100)
24 24 private String permission;
25 25  
26   - @Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + @Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
27 27 @NotNull(message = "菜单类型不能为空")
28 28 private Integer type;
29 29  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java
... ... @@ -7,10 +7,10 @@ import lombok.Data;
7 7 @Data
8 8 public class MenuListReqVO {
9 9  
10   - @Schema(description = "菜单名称,模糊匹配", example = "芋道")
  10 + @Schema(description = "菜单名称,模糊匹配", example = "芋道")
11 11 private String name;
12 12  
13   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  13 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
14 14 private Integer status;
15 15  
16 16 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java
... ... @@ -18,7 +18,7 @@ public class MenuRespVO extends MenuBaseVO {
18 18 @Schema(description = "菜单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
19 19 private Long id;
20 20  
21   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
22 22 private Integer status;
23 23  
24 24 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java
... ... @@ -22,7 +22,7 @@ public class MenuSimpleRespVO {
22 22 @Schema(description = "父菜单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
23 23 private Long parentId;
24 24  
25   - @Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + @Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
26 26 private Integer type;
27 27  
28 28 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java
... ... @@ -15,7 +15,7 @@ public class PermissionAssignRoleDataScopeReqVO {
15 15 @NotNull(message = "角色编号不能为空")
16 16 private Long roleId;
17 17  
18   - @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 19 @NotNull(message = "数据范围不能为空")
20 20 // TODO 这里要多一个枚举校验
21 21 private Integer dataScope;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java
... ... @@ -12,13 +12,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
12 12 @Data
13 13 public class RoleExportReqVO {
14 14  
15   - @Schema(description = "角色名称,模糊匹配", example = "芋道")
  15 + @Schema(description = "角色名称,模糊匹配", example = "芋道")
16 16 private String name;
17 17  
18   - @Schema(description = "角色标识,模糊匹配", example = "yudao")
  18 + @Schema(description = "角色标识,模糊匹配", example = "yudao")
19 19 private String code;
20 20  
21   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  21 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
22 22 private Integer status;
23 23  
24 24 @Schema(description = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java
... ... @@ -15,13 +15,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 @EqualsAndHashCode(callSuper = true)
16 16 public class RolePageReqVO extends PageParam {
17 17  
18   - @Schema(description = "角色名称,模糊匹配", example = "芋道")
  18 + @Schema(description = "角色名称,模糊匹配", example = "芋道")
19 19 private String name;
20 20  
21   - @Schema(description = "角色标识,模糊匹配", example = "yudao")
  21 + @Schema(description = "角色标识,模糊匹配", example = "yudao")
22 22 private String code;
23 23  
24   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  24 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
25 25 private Integer status;
26 26  
27 27 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java
... ... @@ -19,16 +19,16 @@ public class RoleRespVO extends RoleBaseVO {
19 19 @Schema(description = "角色编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 20 private Long id;
21 21  
22   - @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
23 23 private Integer dataScope;
24 24  
25 25 @Schema(description = "数据范围(指定部门数组)", example = "1")
26 26 private Set<Long> dataScopeDeptIds;
27 27  
28   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
29 29 private Integer status;
30 30  
31   - @Schema(description = "角色类型,参见 RoleTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  31 + @Schema(description = "角色类型,参见 RoleTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
32 32 private Integer type;
33 33  
34 34 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java
... ... @@ -21,7 +21,7 @@ public class SensitiveWordBaseVO {
21 21 @NotNull(message = "标签不能为空")
22 22 private List<String> tags;
23 23  
24   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  24 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 25 @NotNull(message = "状态不能为空")
26 26 private Integer status;
27 27  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 敏感词 Excel 导出 Request VO,参数和 SensitiveWordPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 敏感词 Excel 导出 Request VO,参数和 SensitiveWordPageReqVO 是一致的")
12 12 @Data
13 13 public class SensitiveWordExportReqVO {
14 14  
... ... @@ -18,7 +18,7 @@ public class SensitiveWordExportReqVO {
18 18 @Schema(description = "标签", example = "短信,评论")
19 19 private String tag;
20 20  
21   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
  21 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
22 22 private Integer status;
23 23  
24 24 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java
... ... @@ -23,7 +23,7 @@ public class SensitiveWordPageReqVO extends PageParam {
23 23 @Schema(description = "标签", example = "短信,评论")
24 24 private String tag;
25 25  
26   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
  26 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
27 27 private Integer status;
28 28  
29 29 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java
... ... @@ -13,7 +13,7 @@ import javax.validation.constraints.NotNull;
13 13 @ToString(callSuper = true)
14 14 public class SmsChannelCreateReqVO extends SmsChannelBaseVO {
15 15  
16   - @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
  16 + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
17 17 @NotNull(message = "渠道编码不能为空")
18 18 private String code;
19 19  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java
... ... @@ -20,7 +20,7 @@ public class SmsChannelPageReqVO extends PageParam {
20 20 @Schema(description = "任务状态", example = "1")
21 21 private Integer status;
22 22  
23   - @Schema(description = "短信签名,模糊匹配", example = "芋道源码")
  23 + @Schema(description = "短信签名,模糊匹配", example = "芋道源码")
24 24 private String signature;
25 25  
26 26 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java
... ... @@ -16,7 +16,7 @@ public class SmsChannelRespVO extends SmsChannelBaseVO {
16 16 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17 17 private Long id;
18 18  
19   - @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
  19 + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
20 20 private String code;
21 21  
22 22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java
... ... @@ -17,7 +17,7 @@ public class SmsChannelSimpleRespVO {
17 17 @NotNull(message = "短信签名不能为空")
18 18 private String signature;
19 19  
20   - @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
  20 + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "YUN_PIAN")
21 21 private String code;
22 22  
23 23 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 短信日志 Excel 导出 Request VO,参数和 SmsLogPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 短信日志 Excel 导出 Request VO,参数和 SmsLogPageReqVO 是一致的")
12 12 @Data
13 13 public class SmsLogExportReqVO {
14 14  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java
... ... @@ -26,14 +26,14 @@ public class SmsLogPageReqVO extends PageParam {
26 26 @Schema(description = "手机号", example = "15601691300")
27 27 private String mobile;
28 28  
29   - @Schema(description = "发送状态,参见 SmsSendStatusEnum 枚举类", example = "1")
  29 + @Schema(description = "发送状态,参见 SmsSendStatusEnum 枚举类", example = "1")
30 30 private Integer sendStatus;
31 31  
32 32 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
33 33 @Schema(description = "发送时间")
34 34 private LocalDateTime[] sendTime;
35 35  
36   - @Schema(description = "接收状态,参见 SmsReceiveStatusEnum 枚举类", example = "0")
  36 + @Schema(description = "接收状态,参见 SmsReceiveStatusEnum 枚举类", example = "0")
37 37 private Integer receiveStatus;
38 38  
39 39 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java
... ... @@ -11,11 +11,11 @@ import javax.validation.constraints.NotNull;
11 11 @Data
12 12 public class SmsTemplateBaseVO {
13 13  
14   - @Schema(description = "短信类型,参见 SmsTemplateTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + @Schema(description = "短信类型,参见 SmsTemplateTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
15 15 @NotNull(message = "短信类型不能为空")
16 16 private Integer type;
17 17  
18   - @Schema(description = "开启状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @Schema(description = "开启状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 19 @NotNull(message = "开启状态不能为空")
20 20 private Integer status;
21 21  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 短信模板 Excel 导出 Request VO,参数和 SmsTemplatePageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 短信模板 Excel 导出 Request VO,参数和 SmsTemplatePageReqVO 是一致的")
12 12 @Data
13 13 public class SmsTemplateExportReqVO {
14 14  
... ... @@ -18,13 +18,13 @@ public class SmsTemplateExportReqVO {
18 18 @Schema(description = "开启状态", example = "1")
19 19 private Integer status;
20 20  
21   - @Schema(description = "模板编码,模糊匹配", example = "test_01")
  21 + @Schema(description = "模板编码,模糊匹配", example = "test_01")
22 22 private String code;
23 23  
24   - @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!")
  24 + @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!")
25 25 private String content;
26 26  
27   - @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920")
  27 + @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920")
28 28 private String apiTemplateId;
29 29  
30 30 @Schema(description = "短信渠道编号", example = "10")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java
... ... @@ -23,13 +23,13 @@ public class SmsTemplatePageReqVO extends PageParam {
23 23 @Schema(description = "开启状态", example = "1")
24 24 private Integer status;
25 25  
26   - @Schema(description = "模板编码,模糊匹配", example = "test_01")
  26 + @Schema(description = "模板编码,模糊匹配", example = "test_01")
27 27 private String code;
28 28  
29   - @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!")
  29 + @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!")
30 30 private String content;
31 31  
32   - @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920")
  32 + @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920")
33 33 private String apiTemplateId;
34 34  
35 35 @Schema(description = "短信渠道编号", example = "10")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class SocialUserBindReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java
... ... @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull;
18 18 @Builder
19 19 public class SocialUserUnbindReqVO {
20 20  
21   - @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  21 + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22 22 @InEnum(SocialTypeEnum.class)
23 23 @NotNull(message = "社交平台的类型不能为空")
24 24 private Integer type;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java
... ... @@ -7,9 +7,9 @@ import javax.validation.constraints.NotNull;
7 7 import java.util.Set;
8 8  
9 9 /**
10   -* 租户套餐 Base VO,提供给添加、修改、详细的子 VO 使用
11   -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
12   -*/
  10 + * 租户套餐 Base VO,提供给添加、修改、详细的子 VO 使用
  11 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 + */
13 13 @Data
14 14 public class TenantPackageBaseVO {
15 15  
... ... @@ -17,7 +17,7 @@ public class TenantPackageBaseVO {
17 17 @NotNull(message = "套餐名不能为空")
18 18 private String name;
19 19  
20   - @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  20 + @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
21 21 @NotNull(message = "状态不能为空")
22 22 private Integer status;
23 23  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java
... ... @@ -8,7 +8,7 @@ import java.time.LocalDateTime;
8 8  
9 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10  
11   -@Schema(description = "管理后台 - 租户 Excel 导出 Request VO,参数和 TenantPageReqVO 是一致的")
  11 +@Schema(description = "管理后台 - 租户 Excel 导出 Request VO,参数和 TenantPageReqVO 是一致的")
12 12 @Data
13 13 public class TenantExportReqVO {
14 14  
... ... @@ -24,8 +24,8 @@ public class TenantExportReqVO {
24 24 @Schema(description = "租户状态(0正常 1停用)", example = "1")
25 25 private Integer status;
26 26  
27   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
28 27 @Schema(description = "创建时间")
  28 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
29 29 private LocalDateTime[] createTime;
30 30  
31 31 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java
... ... @@ -21,7 +21,7 @@ public class UserProfileRespVO extends UserBaseVO {
21 21 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
22 22 private Long id;
23 23  
24   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  24 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 25 private Integer status;
26 26  
27 27 @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1")
... ... @@ -92,7 +92,7 @@ public class UserProfileRespVO extends UserBaseVO {
92 92 @Data
93 93 public static class SocialUser {
94 94  
95   - @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  95 + @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
96 96 private Integer type;
97 97  
98 98 @Schema(description = "社交用户的 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
  5 +import org.hibernate.validator.constraints.Length;
5 6  
6 7 import javax.validation.constraints.Email;
7 8 import javax.validation.constraints.Size;
... ... @@ -21,6 +22,7 @@ public class UserProfileUpdateReqVO {
21 22 private String email;
22 23  
23 24 @Schema(description = "手机号码", example = "15601691300")
  25 + @Length(min = 11, max = 11, message = "手机号长度必须 11 位")
24 26 private String mobile;
25 27  
26 28 @Schema(description = "用户性别-参见 SexEnum 枚举类", example = "1")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java
... ... @@ -45,7 +45,7 @@ public class UserBaseVO {
45 45 @Mobile
46 46 private String mobile;
47 47  
48   - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
  48 + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
49 49 private Integer sex;
50 50  
51 51 @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java
... ... @@ -10,19 +10,19 @@ import java.time.LocalDateTime;
10 10  
11 11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 12  
13   -@Schema(description = "管理后台 - 用户导出 Request VO,参数和 UserPageReqVO 是一致的")
  13 +@Schema(description = "管理后台 - 用户导出 Request VO,参数和 UserPageReqVO 是一致的")
14 14 @Data
15 15 @NoArgsConstructor
16 16 @AllArgsConstructor
17 17 public class UserExportReqVO {
18 18  
19   - @Schema(description = "用户账号,模糊匹配", example = "yudao")
  19 + @Schema(description = "用户账号,模糊匹配", example = "yudao")
20 20 private String username;
21 21  
22   - @Schema(description = "手机号码,模糊匹配", example = "yudao")
  22 + @Schema(description = "手机号码,模糊匹配", example = "yudao")
23 23 private String mobile;
24 24  
25   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  25 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
26 26 private Integer status;
27 27  
28 28 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java
... ... @@ -18,7 +18,7 @@ public class UserImportRespVO {
18 18 @Schema(description = "更新成功的用户名数组", requiredMode = Schema.RequiredMode.REQUIRED)
19 19 private List<String> updateUsernames;
20 20  
21   - @Schema(description = "导入失败的用户集合,key 为用户名,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + @Schema(description = "导入失败的用户集合,key 为用户名,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
22 22 private Map<String, String> failureUsernames;
23 23  
24 24 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java
... ... @@ -19,20 +19,20 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
19 19 @EqualsAndHashCode(callSuper = true)
20 20 public class UserPageReqVO extends PageParam {
21 21  
22   - @Schema(description = "用户账号,模糊匹配", example = "yudao")
  22 + @Schema(description = "用户账号,模糊匹配", example = "yudao")
23 23 private String username;
24 24  
25   - @Schema(description = "手机号码,模糊匹配", example = "yudao")
  25 + @Schema(description = "手机号码,模糊匹配", example = "yudao")
26 26 private String mobile;
27 27  
28   - @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
  28 + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
29 29 private Integer status;
30 30  
31   - @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
  31 + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
32 32 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
33 33 private LocalDateTime[] createTime;
34 34  
35   - @Schema(description = "部门编号,同时筛选子部门", example = "1024")
  35 + @Schema(description = "部门编号,同时筛选子部门", example = "1024")
36 36 private Long deptId;
37 37  
38 38 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java
... ... @@ -16,7 +16,7 @@ public class UserRespVO extends UserBaseVO {
16 16 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
17 17 private Long id;
18 18  
19   - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 20 private Integer status;
21 21  
22 22 @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
1 1 package cn.iocoder.yudao.module.system.convert.auth;
2 2  
3   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 3 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
5 4 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
6 5 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
... ... @@ -15,6 +14,7 @@ import org.slf4j.LoggerFactory;
15 14  
16 15 import java.util.*;
17 16  
  17 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
18 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
19 19 import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
20 20  
... ... @@ -28,8 +28,8 @@ public interface AuthConvert {
28 28 default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
29 29 return AuthPermissionInfoRespVO.builder()
30 30 .user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build())
31   - .roles(CollectionUtils.convertSet(roleList, RoleDO::getCode))
32   - .permissions(CollectionUtils.convertSet(menuList, MenuDO::getPermission))
  31 + .roles(convertSet(roleList, RoleDO::getCode))
  32 + .permissions(convertSet(menuList, MenuDO::getPermission))
33 33 .build();
34 34 }
35 35  
... ...