mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
This commit is contained in:
commit
3c5917a6cd
@ -1,12 +1,9 @@
|
||||
package cn.iocoder.yudao.framework.quartz.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.quartz.core.job.JobLogJobHandler;
|
||||
import cn.iocoder.yudao.framework.quartz.core.job.LogJobProperties;
|
||||
import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Scheduler;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@ -18,7 +15,6 @@ import java.util.Optional;
|
||||
@AutoConfiguration
|
||||
@EnableScheduling // 开启 Spring 自带的定时任务
|
||||
@Slf4j
|
||||
@EnableConfigurationProperties(LogJobProperties.class)
|
||||
public class YudaoQuartzAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ -30,10 +26,4 @@ public class YudaoQuartzAutoConfiguration {
|
||||
return new SchedulerManager(scheduler.get());
|
||||
}
|
||||
|
||||
// TODO @j-sentinel:这个 job,先拿到 infra biz 里面实现哈;
|
||||
@Bean
|
||||
public JobLogJobHandler jobLogJobHandler(LogJobProperties logJobProperties){
|
||||
return new JobLogJobHandler(logJobProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.quartz.core.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.quartz.core.service.JobLogFrameworkService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
// TODO @j-sentinel:名字和项目里其它保持统一,可以叫 JobLogCleanJob,不用带 handler 哈
|
||||
/**
|
||||
* // TODO @j-sentinel:要写下类注释噢,就是这个类要干啥;然后下面两个应该是 @author 和 @since
|
||||
* @Author: j-sentinel
|
||||
* @Date: 2023/9/30 20:40
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class JobLogJobHandler implements JobHandler {
|
||||
|
||||
private LogJobProperties logJobProperties;
|
||||
|
||||
public JobLogJobHandler(LogJobProperties logJobProperties) {
|
||||
this.logJobProperties = logJobProperties;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private JobLogFrameworkService jobLogFrameworkService;
|
||||
|
||||
@Override
|
||||
public String execute(String param) throws Exception {
|
||||
Integer integer = jobLogFrameworkService.timingJobCleanLog(logJobProperties.getJobCleanRetainDay());
|
||||
log.info("定时执行清理定时任务日志数量({})个",integer);
|
||||
return String.format("定时执行清理定时任务日志数量 %s 个", integer);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.quartz.core.job;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
// TODO @j-sentinel:这个配置类,先暂时不做,每个 Job 里面定一个静态类。其实不是所有的变量,都需要配置化,因为它本身基本也不会改动。
|
||||
/**
|
||||
* @Author: j-sentinel
|
||||
* @Date: 2023/9/30 16:17
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "yudao.clean-job")
|
||||
public class LogJobProperties {
|
||||
|
||||
private int accessRetainDay = 7;
|
||||
|
||||
private int errorRetainDay = 8;
|
||||
|
||||
private int jobCleanRetainDay = 7;
|
||||
|
||||
}
|
@ -40,11 +40,4 @@ public interface JobLogFrameworkService {
|
||||
@NotNull(message = "结束时间不能为空") LocalDateTime endTime,
|
||||
@NotNull(message = "运行时长不能为空") Integer duration,
|
||||
boolean success, String result);
|
||||
|
||||
/**
|
||||
* 清理 @param jobCleanRetainDay 天的访问日志
|
||||
*
|
||||
* @param jobCleanRetainDay 超过多少天就进行清理
|
||||
*/
|
||||
Integer timingJobCleanLog(Integer jobCleanRetainDay);
|
||||
}
|
||||
|
@ -61,12 +61,6 @@
|
||||
<artifactId>jsoup</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<!-- TODO @j-sentinel:去掉这个依赖哈; -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-job</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,14 +1,11 @@
|
||||
package cn.iocoder.yudao.framework.apilog.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.filter.ApiAccessLogFilter;
|
||||
import cn.iocoder.yudao.framework.apilog.core.job.ApiAccessLogJobHandler;
|
||||
import cn.iocoder.yudao.framework.apilog.core.job.ApiErrorLogJobHandler;
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkServiceImpl;
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkServiceImpl;
|
||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||
import cn.iocoder.yudao.framework.quartz.core.job.LogJobProperties;
|
||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||
import cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration;
|
||||
import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
|
||||
@ -34,16 +31,6 @@ public class YudaoApiLogAutoConfiguration {
|
||||
return new ApiErrorLogFrameworkServiceImpl(apiErrorLogApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApiAccessLogJobHandler apiAccessLogJobHandler(LogJobProperties logJobProperties) {
|
||||
return new ApiAccessLogJobHandler(logJobProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApiErrorLogJobHandler apiErrorLogJobHandler(LogJobProperties logJobProperties) {
|
||||
return new ApiErrorLogJobHandler(logJobProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 ApiAccessLogFilter Bean,记录 API 请求日志
|
||||
*/
|
||||
|
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.apilog.core.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.quartz.core.job.LogJobProperties;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
// TODO @j-sentinel:同 JobLogJobHandler
|
||||
/**
|
||||
* @Author: j-sentinel
|
||||
* @Date: 2023/9/30 16:13
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class ApiAccessLogJobHandler implements JobHandler {
|
||||
|
||||
private LogJobProperties logJobProperties;
|
||||
|
||||
public ApiAccessLogJobHandler(LogJobProperties logJobProperties) {
|
||||
this.logJobProperties = logJobProperties;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ApiAccessLogFrameworkService apiAccessLogFrameworkService;
|
||||
|
||||
@Override
|
||||
public String execute(String param) throws Exception {
|
||||
apiAccessLogFrameworkService.jobCleanAccessLog(logJobProperties.getAccessRetainDay());
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.apilog.core.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.quartz.core.job.LogJobProperties;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
// TODO @j-sentinel:同 JobLogJobHandler
|
||||
/**
|
||||
* @Author: j-sentinel
|
||||
* @Date: 2023/9/30 16:13
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class ApiErrorLogJobHandler implements JobHandler {
|
||||
|
||||
private LogJobProperties logJobProperties;
|
||||
|
||||
public ApiErrorLogJobHandler(LogJobProperties logJobProperties) {
|
||||
this.logJobProperties = logJobProperties;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ApiErrorLogFrameworkService apiErrorLogFrameworkService;
|
||||
|
||||
@Override
|
||||
public String execute(String param) throws Exception {
|
||||
apiErrorLogFrameworkService.jobCleanErrorLog(logJobProperties.getErrorRetainDay());
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -13,11 +13,4 @@ public interface ApiAccessLogFrameworkService {
|
||||
* @param apiAccessLog API 访问日志
|
||||
*/
|
||||
void createApiAccessLog(ApiAccessLog apiAccessLog);
|
||||
|
||||
/**
|
||||
* 清理 @param accessLogJobDay 天的访问日志
|
||||
*
|
||||
* @param accessLogJobDay 超过多少天就进行清理
|
||||
*/
|
||||
void jobCleanAccessLog(Integer accessLogJobDay);
|
||||
}
|
||||
|
@ -25,9 +25,4 @@ public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkSe
|
||||
apiAccessLogApi.createApiAccessLog(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobCleanAccessLog(Integer accessLogJobDay) {
|
||||
apiAccessLogApi.jobCleanAccessLog(accessLogJobDay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,11 +13,4 @@ public interface ApiErrorLogFrameworkService {
|
||||
* @param apiErrorLog API 错误日志
|
||||
*/
|
||||
void createApiErrorLog(ApiErrorLog apiErrorLog);
|
||||
|
||||
/**
|
||||
* 清理 @param errorLogJobDay 天的访问日志
|
||||
*
|
||||
* @param errorLogJobDay 超过多少天就进行清理
|
||||
*/
|
||||
void jobCleanErrorLog(Integer errorLogJobDay);
|
||||
}
|
||||
|
@ -25,9 +25,4 @@ public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkServ
|
||||
apiErrorLogApi.createApiErrorLog(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobCleanErrorLog(Integer errorLogJobDay) {
|
||||
apiErrorLogApi.jobCleanErrorLog(errorLogJobDay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,12 +18,4 @@ public interface ApiAccessLogApi {
|
||||
*/
|
||||
void createApiAccessLog(@Valid ApiAccessLogCreateReqDTO createDTO);
|
||||
|
||||
// TODO @j-sentinel:这个我们先提供接口在 API,而是 infra 模块自己清理先哈;
|
||||
/**
|
||||
* 清理 @param accessLogJobDay 天的访问日志
|
||||
*
|
||||
* @param accessLogJobDay 超过多少天就进行清理
|
||||
*/
|
||||
void jobCleanAccessLog(Integer accessLogJobDay);
|
||||
|
||||
}
|
||||
|
@ -18,12 +18,4 @@ public interface ApiErrorLogApi {
|
||||
*/
|
||||
void createApiErrorLog(@Valid ApiErrorLogCreateReqDTO createDTO);
|
||||
|
||||
// TODO @j-sentinel:这个我们先提供接口在 API,而是 infra 模块自己清理先哈;
|
||||
/**
|
||||
* 清理 @param errorLogJobDay 天的访问日志
|
||||
*
|
||||
* @param errorLogJobDay 超过多少天就进行清理
|
||||
*/
|
||||
void jobCleanErrorLog(Integer errorLogJobDay);
|
||||
|
||||
}
|
||||
|
@ -24,9 +24,4 @@ public class ApiAccessLogApiImpl implements ApiAccessLogApi {
|
||||
apiAccessLogService.createApiAccessLog(createDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobCleanAccessLog(Integer accessLogJobDay) {
|
||||
apiAccessLogService.jobCleanAccessLog(accessLogJobDay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,9 +24,4 @@ public class ApiErrorLogApiImpl implements ApiErrorLogApi {
|
||||
apiErrorLogService.createApiErrorLog(createDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobCleanErrorLog(Integer errorLogJobDay) {
|
||||
apiErrorLogService.jobCleanErrorLog(errorLogJobDay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -41,12 +43,14 @@ public interface JobLogMapper extends BaseMapperX<JobLogDO> {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO @j-sentinel:一般来说,我们 mapper 只提供 crud 的操作,所以这个方法的命名,建议是 deleteByCreateTimeLt;
|
||||
// 然后,参数是 (crateTime, count),由 service 传入
|
||||
// 这里为什么有 lt 呢,这个其实是延续 spring data 的 method 描述的命名习惯,lt 表示小于;
|
||||
// 另外,timingJobCleanLog 的具体 sql 这么写,性能是比较差的;可以直接 delete * from job_log where create_time < xxx order by id limit 100;
|
||||
Integer timingJobCleanLog(@Param("jobCleanRetainDay") Integer jobCleanRetainDay);
|
||||
/**
|
||||
* 物理删除指定时间之前的日志
|
||||
*
|
||||
* @param createTime 最大时间
|
||||
* @param limit 删除条数,防止一次删除太多
|
||||
* @return 删除条数
|
||||
*/
|
||||
@Delete("DELETE FROM infra_job_log WHERE create_time < #{createTime} LIMIT #{limit}")
|
||||
Integer deleteByCreateTimeLt(@Param("createTime") LocalDateTime createTime, @Param("limit") Integer limit);
|
||||
|
||||
// TODO @j-serntinel:optimize table infra_job_log 就可以啦?
|
||||
void optimizeTable();
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -45,8 +47,14 @@ public interface ApiAccessLogMapper extends BaseMapperX<ApiAccessLogDO> {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO @j-sentinel:同 JobLogMapper 的一些优化点
|
||||
Integer jobCleanAccessLog(@Param("accessLogJobDay") Integer accessLogJobDay);
|
||||
/**
|
||||
* 物理删除指定时间之前的日志
|
||||
*
|
||||
* @param createTime 最大时间
|
||||
* @param limit 删除条数,防止一次删除太多
|
||||
* @return 删除条数
|
||||
*/
|
||||
@Delete("DELETE FROM infra_api_access_log WHERE create_time < #{createTime} LIMIT #{limit}")
|
||||
Integer deleteByCreateTimeLt(@Param("createTime") LocalDateTime createTime, @Param("limit") Integer limit);
|
||||
|
||||
void optimizeTable();
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -43,8 +45,14 @@ public interface ApiErrorLogMapper extends BaseMapperX<ApiErrorLogDO> {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO @j-sentinel:同 JobLogMapper 的一些优化点
|
||||
Integer jobCleanErrorLog(@Param("errorLogJobDay") Integer errorLogJobDay);
|
||||
/**
|
||||
* 物理删除指定时间之前的日志
|
||||
*
|
||||
* @param createTime 最大时间
|
||||
* @param limit 删除条数,防止一次删除太多
|
||||
* @return 删除条数
|
||||
*/
|
||||
@Delete("DELETE FROM infra_api_error_log WHERE create_time < #{createTime} LIMIT #{limit}")
|
||||
Integer deleteByCreateTimeLt(@Param("createTime") LocalDateTime createTime, @Param("limit")Integer limit);
|
||||
|
||||
void optimizeTable();
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.module.infra.job.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.infra.service.logger.ApiAccessLogService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 物理删除 N 天前的访问日志的 Job
|
||||
*
|
||||
* @author j-sentinel
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AccessLogCleanJob implements JobHandler {
|
||||
|
||||
@Resource
|
||||
private ApiAccessLogService apiAccessLogService;
|
||||
|
||||
/**
|
||||
* 清理超过(14)天的日志
|
||||
*/
|
||||
private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
|
||||
|
||||
/**
|
||||
* 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
|
||||
*/
|
||||
private static final Integer DELETE_LIMIT = 100;
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
public String execute(String param) {
|
||||
Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
|
||||
log.info("[count][定时执行清理访问日志数量 ({}) 个]", count);
|
||||
return String.format("定时执行清理错误日志数量 %s 个", count);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.module.infra.job.job;
|
||||
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.infra.service.logger.ApiErrorLogService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 物理删除 N 天前的错误日志的 Job
|
||||
*
|
||||
* @author j-sentinel
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ErrorLogCleanJob implements JobHandler {
|
||||
|
||||
@Resource
|
||||
private ApiErrorLogService apiErrorLogService;
|
||||
|
||||
/**
|
||||
* 清理超过(14)天的日志
|
||||
*/
|
||||
private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
|
||||
|
||||
/**
|
||||
* 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
|
||||
*/
|
||||
private static final Integer DELETE_LIMIT = 100;
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
public String execute(String param) {
|
||||
Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT);
|
||||
log.info("[count][定时执行清理错误日志数量 ({}) 个]", count);
|
||||
return String.format("定时执行清理错误日志数量 %s 个", count);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package cn.iocoder.yudao.module.infra.job.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.infra.service.job.JobLogService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 物理删除 N 天前的任务日志的 Job
|
||||
*
|
||||
* @author j-sentinel
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JobLogCleanJob implements JobHandler {
|
||||
|
||||
@Resource
|
||||
private JobLogService jobLogService;
|
||||
|
||||
/**
|
||||
* 清理超过(14)天的日志
|
||||
*/
|
||||
private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
|
||||
|
||||
/**
|
||||
* 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
|
||||
*/
|
||||
private static final Integer DELETE_LIMIT = 100;
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
public String execute(String param) {
|
||||
Integer count = jobLogService.cleanJobLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
|
||||
log.info("[count][定时执行清理定时任务日志数量 ({}) 个]", count);
|
||||
return String.format("定时执行清理定时任务日志数量 %s 个", count);
|
||||
}
|
||||
|
||||
}
|
@ -48,4 +48,12 @@ public interface JobLogService extends JobLogFrameworkService {
|
||||
*/
|
||||
List<JobLogDO> getJobLogList(JobLogExportReqVO exportReqVO);
|
||||
|
||||
/**
|
||||
* 清理 exceedDay 天前的任务日志
|
||||
*
|
||||
* @param exceedDay 超过多少天就进行清理
|
||||
* @param deleteLimit 清理的间隔条数
|
||||
*/
|
||||
Integer cleanJobLog(Integer exceedDay, Integer deleteLimit);
|
||||
|
||||
}
|
||||
|
@ -26,8 +26,6 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class JobLogServiceImpl implements JobLogService {
|
||||
|
||||
private static final Integer DELETE_LIMIT = 1;
|
||||
|
||||
@Resource
|
||||
private JobLogMapper jobLogMapper;
|
||||
|
||||
@ -52,21 +50,19 @@ public class JobLogServiceImpl implements JobLogService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @j-sentinel:这个 job,也可以忽略租户哈;可以直接使用 @TenantIgnore 注解;
|
||||
@Override
|
||||
public Integer timingJobCleanLog(Integer jobCleanRetainDay) {
|
||||
Integer result = null;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public Integer cleanJobLog(Integer exceedDay, Integer deleteLimit) {
|
||||
int count = 0;
|
||||
// TODO @j-sentinel:一般我们在写逻辑时,尽量避免用 while true 这种“死循环”,而是 for (int i = 0; i < Short.MAX) 类似这种;避免里面真的发生一些意外的情况,无限执行;
|
||||
// 然后 for 里面,可以有个 if count < 100 未到达删除的预期条数,说明已经到底,可以 break 了;
|
||||
while (result == null || DELETE_LIMIT.equals(result)){
|
||||
result = jobLogMapper.timingJobCleanLog(jobCleanRetainDay);
|
||||
count += result;
|
||||
}
|
||||
if(count > 0){
|
||||
// ALTER TABLE...FORCE 会导致表重建发生,这会根据主键索引对表空间中的物理页进行排序。
|
||||
// 它将行压缩到页面上并消除可用空间,同时确保数据处于主键查找的最佳顺序。
|
||||
jobLogMapper.optimizeTable();
|
||||
LocalDateTime expireDate = LocalDateTime.now().minusDays(exceedDay);
|
||||
// 循环删除,直到没有满足条件的数据
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
int deleteCount = jobLogMapper.deleteByCreateTimeLt(expireDate, deleteLimit);
|
||||
count += deleteCount;
|
||||
// 达到删除预期条数,说明到底了
|
||||
if (deleteCount < deleteLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@ -91,5 +87,4 @@ public class JobLogServiceImpl implements JobLogService {
|
||||
return jobLogMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
// TODO @小吉祥:每天 0 点的时候,清理超过 14 天的日志;
|
||||
}
|
||||
|
@ -39,9 +39,11 @@ public interface ApiAccessLogService {
|
||||
List<ApiAccessLogDO> getApiAccessLogList(ApiAccessLogExportReqVO exportReqVO);
|
||||
|
||||
/**
|
||||
* 清理 @param accessLogJobDay 天的访问日志
|
||||
* 清理 exceedDay 天前的访问日志
|
||||
*
|
||||
* @param accessLogJobDay 超过多少天就进行清理
|
||||
* @param exceedDay 超过多少天就进行清理
|
||||
* @param deleteLimit 清理的间隔条数
|
||||
*/
|
||||
void jobCleanAccessLog(Integer accessLogJobDay);
|
||||
Integer cleanAccessLog(Integer exceedDay, Integer deleteLimit);
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.infra.service.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
|
||||
@ -13,6 +12,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -25,8 +25,6 @@ import java.util.List;
|
||||
@Validated
|
||||
public class ApiAccessLogServiceImpl implements ApiAccessLogService {
|
||||
|
||||
private static final Integer DELETE_LIMIT = 100;
|
||||
|
||||
@Resource
|
||||
private ApiAccessLogMapper apiAccessLogMapper;
|
||||
|
||||
@ -47,22 +45,20 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService {
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO j-sentinel:类似 JobLogServiceImpl 的建议
|
||||
public void jobCleanAccessLog(Integer accessLogJobDay) {
|
||||
TenantUtils.executeIgnore(() -> {
|
||||
Integer result = null;
|
||||
int count = 0;
|
||||
while (result == null || DELETE_LIMIT.equals(result)) {
|
||||
result = apiAccessLogMapper.jobCleanAccessLog(accessLogJobDay);
|
||||
count += result;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public Integer cleanAccessLog(Integer exceedDay, Integer deleteLimit) {
|
||||
int count = 0;
|
||||
LocalDateTime expireDate = LocalDateTime.now().minusDays(exceedDay);
|
||||
// 循环删除,直到没有满足条件的数据
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
int deleteCount = apiAccessLogMapper.deleteByCreateTimeLt(expireDate, deleteLimit);
|
||||
count += deleteCount;
|
||||
// 达到删除预期条数,说明到底了
|
||||
if (deleteCount < deleteLimit) {
|
||||
break;
|
||||
}
|
||||
if (count > 0) {
|
||||
// ALTER TABLE...FORCE 会导致表重建发生,这会根据主键索引对表空间中的物理页进行排序。
|
||||
// 它将行压缩到页面上并消除可用空间,同时确保数据处于主键查找的最佳顺序。
|
||||
apiAccessLogMapper.optimizeTable();
|
||||
}
|
||||
log.info("定时执行清理访问日志数量({})个", count);
|
||||
});
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,9 +48,11 @@ public interface ApiErrorLogService {
|
||||
void updateApiErrorLogProcess(Long id, Integer processStatus, Long processUserId);
|
||||
|
||||
/**
|
||||
* 清理 @param errorLogJobDay 天的访问日志
|
||||
* 清理 exceedDay 天前的错误日志
|
||||
*
|
||||
* @param errorLogJobDay 超过多少天就进行清理
|
||||
* @param exceedDay 超过多少天就进行清理
|
||||
* @param deleteLimit 清理的间隔条数
|
||||
*/
|
||||
void jobCleanErrorLog(Integer errorLogJobDay);
|
||||
Integer cleanErrorLog(Integer exceedDay, Integer deleteLimit);
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.infra.service.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
|
||||
@ -31,8 +30,6 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_L
|
||||
@Validated
|
||||
public class ApiErrorLogServiceImpl implements ApiErrorLogService {
|
||||
|
||||
private static final Integer DELETE_LIMIT = 100;
|
||||
|
||||
@Resource
|
||||
private ApiErrorLogMapper apiErrorLogMapper;
|
||||
|
||||
@ -68,22 +65,20 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO j-sentinel:类似 JobLogServiceImpl 的建议
|
||||
public void jobCleanErrorLog(Integer errorLogJobDay) {
|
||||
TenantUtils.executeIgnore(() -> {
|
||||
Integer result = null;
|
||||
int count = 0;
|
||||
while (result == null || DELETE_LIMIT.equals(result)) {
|
||||
result = apiErrorLogMapper.jobCleanErrorLog(errorLogJobDay);
|
||||
count += result;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public Integer cleanErrorLog(Integer exceedDay, Integer deleteLimit) {
|
||||
int count = 0;
|
||||
LocalDateTime expireDate = LocalDateTime.now().minusDays(exceedDay);
|
||||
// 循环删除,直到没有满足条件的数据
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
int deleteCount = apiErrorLogMapper.deleteByCreateTimeLt(expireDate, deleteLimit);
|
||||
count += deleteCount;
|
||||
// 达到删除预期条数,说明到底了
|
||||
if (deleteCount < deleteLimit) {
|
||||
break;
|
||||
}
|
||||
if (count > 0) {
|
||||
// ALTER TABLE...FORCE 会导致表重建发生,这会根据主键索引对表空间中的物理页进行排序。
|
||||
// 它将行压缩到页面上并消除可用空间,同时确保数据处于主键查找的最佳顺序。
|
||||
apiErrorLogMapper.optimizeTable();
|
||||
}
|
||||
log.info("定时执行清理错误日志数量({})个",count);
|
||||
});
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiAccessLogMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
<delete id="jobCleanAccessLog" parameterType="integer">
|
||||
DELETE FROM infra_api_access_log
|
||||
WHERE id IN (
|
||||
SELECT * FROM (
|
||||
SELECT id FROM infra_api_access_log
|
||||
WHERE create_time < DATE_SUB(CURDATE(), INTERVAL #{accessLogJobDay} DAY)
|
||||
ORDER BY id ASC LIMIT 100
|
||||
) AS a
|
||||
)
|
||||
</delete>
|
||||
|
||||
<select id="optimizeTable">
|
||||
ALTER TABLE infra_job_log FORCE
|
||||
/*
|
||||
ALTER TABLE infra_job_log ENGINE = INNODB,
|
||||
ALGORITHM = INPLACE,
|
||||
LOCK = NONE
|
||||
*/
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
<delete id="jobCleanErrorLog" parameterType="integer">
|
||||
DELETE FROM infra_api_error_log
|
||||
WHERE id IN (
|
||||
SELECT * FROM (
|
||||
SELECT id FROM infra_api_error_log
|
||||
WHERE create_time < DATE_SUB(CURDATE(), INTERVAL #{errorLogJobDay} DAY)
|
||||
ORDER BY id ASC LIMIT 100
|
||||
) AS a
|
||||
)
|
||||
</delete>
|
||||
|
||||
<select id="optimizeTable">
|
||||
ALTER TABLE infra_api_error_log FORCE
|
||||
/*
|
||||
ALTER TABLE infra_api_error_log ENGINE = INNODB,
|
||||
ALGORITHM = INPLACE,
|
||||
LOCK = NONE
|
||||
*/
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
<delete id="timingJobCleanLog" parameterType="integer">
|
||||
DELETE FROM infra_job_log
|
||||
WHERE id IN (
|
||||
SELECT * FROM (
|
||||
SELECT id FROM infra_job_log
|
||||
WHERE create_time < DATE_SUB(CURDATE(), INTERVAL #{jobCleanRetainDay} DAY)
|
||||
ORDER BY id ASC LIMIT 100
|
||||
) AS a
|
||||
)
|
||||
</delete>
|
||||
|
||||
<select id="optimizeTable">
|
||||
ALTER TABLE infra_job_log FORCE
|
||||
/*
|
||||
ALTER TABLE infra_job_log ENGINE = INNODB,
|
||||
ALGORITHM = INPLACE,
|
||||
LOCK = NONE
|
||||
*/
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
|
@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
|
@ -15,15 +15,19 @@ import java.util.List;
|
||||
@ToString(callSuper = true)
|
||||
public class SeckillActivityRespVO extends SeckillActivityBaseVO {
|
||||
|
||||
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "秒杀活动 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
|
||||
example = "618大促")
|
||||
private String spuName;
|
||||
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
|
||||
example = "https://www.iocoder.cn/xx.png")
|
||||
private String picUrl;
|
||||
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
|
||||
example = "50")
|
||||
private Integer marketPrice;
|
||||
|
||||
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<SeckillProductRespVO> products;
|
||||
|
||||
|
@ -21,4 +21,10 @@ public class SeckillConfigSimpleRespVO {
|
||||
@NotNull(message = "秒杀时段名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:00:00")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:00:00")
|
||||
private String endTime;
|
||||
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppS
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
@ -16,13 +16,13 @@ public class AppSeckillActivityRespVO {
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
|
||||
// 从 SPU 的 picUrl 读取
|
||||
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
|
||||
example = "https://www.iocoder.cn/xx.png")
|
||||
private String picUrl;
|
||||
@Schema(description = "单位名", requiredMode = Schema.RequiredMode.REQUIRED, example = "个")
|
||||
private String unitName;
|
||||
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
// 从 SPU 的 marketPrice 读取
|
||||
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
|
||||
example = "50")
|
||||
private Integer marketPrice;
|
||||
|
||||
@Schema(description = "秒杀活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
|
@ -18,9 +18,9 @@ import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppS
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
@ -61,7 +61,7 @@ public interface SeckillActivityConvert {
|
||||
pageResult.getList().forEach(item -> {
|
||||
item.setProducts(convertList2(seckillProducts));
|
||||
MapUtils.findAndThen(spuMap, item.getSpuId(),
|
||||
spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()));
|
||||
spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()));
|
||||
});
|
||||
return pageResult;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig;
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
@ -1,9 +1,8 @@
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -5,8 +5,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
|
@ -14,8 +14,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper;
|
||||
import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
|
||||
|
@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
|
@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityServiceImpl;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.promotion.service.seckillconfig;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigServiceImpl;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
@ -26,7 +26,7 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO {
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
private String nickname;
|
||||
|
||||
// ========== 推广信息 ==========
|
||||
// ========== 推广信息 ========== 注意:是包括 1 + 2 级的数据
|
||||
|
||||
@Schema(description = "推广用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
|
||||
private Integer brokerageUserCount;
|
||||
|
@ -68,7 +68,7 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
|
||||
.in(BrokerageRecordDO::getUserId, userIds)
|
||||
.eq(BrokerageRecordDO::getBizId, bizType)
|
||||
.eq(BrokerageRecordDO::getStatus, status)
|
||||
.groupBy(BrokerageRecordDO::getUserId));
|
||||
.groupBy(BrokerageRecordDO::getUserId)); // 按照 userId 聚合
|
||||
return BeanUtil.copyToList(list, UserBrokerageSummaryRespBO.class);
|
||||
// selectJoinList有BUG,会与租户插件冲突:解析SQL时,发生异常 https://gitee.com/best_handsome/mybatis-plus-join/issues/I84GYW
|
||||
// return selectJoinList(UserBrokerageSummaryBO.class, MPJWrappers.lambdaJoin(BrokerageRecordDO.class)
|
||||
|
@ -329,26 +329,27 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||
if (bindUserId == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 先查第 1 级
|
||||
List<Long> bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(Collections.singleton(bindUserId));
|
||||
if (CollUtil.isEmpty(bindUserIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 情况一:level 为空,查询所有级别
|
||||
if (level == null) {
|
||||
// level 为空,再查第 2 级,并合并结果
|
||||
// 再查第 2 级,并合并结果
|
||||
bindUserIds.addAll(brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds));
|
||||
} else if (level == 2) {
|
||||
// 只查第 2 级
|
||||
bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds);
|
||||
} else if (level == 1) {
|
||||
// 只查第 1 级
|
||||
return bindUserIds;
|
||||
} else {
|
||||
throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT);
|
||||
}
|
||||
return bindUserIds;
|
||||
// 情况二:level 为 1,只查询第 1 级
|
||||
if (level == 1) {
|
||||
return bindUserIds;
|
||||
}
|
||||
// 情况三:level 为 1,只查询第 2 级
|
||||
if (level == 2) {
|
||||
return brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds);
|
||||
}
|
||||
throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -214,10 +214,6 @@ yudao:
|
||||
enable: false
|
||||
demo: false # 关闭演示模式
|
||||
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
|
||||
clean-job:
|
||||
access-retain-day: 7
|
||||
error-retain-day: 8
|
||||
job-clean-retain-day: 8
|
||||
|
||||
justauth:
|
||||
enabled: true
|
||||
|
Loading…
Reference in New Issue
Block a user