diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/exception/GlobalExceptionHandler.java b/common/service-utils/src/main/java/cn/bunny/common/service/exception/GlobalExceptionHandler.java index b8c1dd0..293b605 100644 --- a/common/service-utils/src/main/java/cn/bunny/common/service/exception/GlobalExceptionHandler.java +++ b/common/service-utils/src/main/java/cn/bunny/common/service/exception/GlobalExceptionHandler.java @@ -55,6 +55,13 @@ public class GlobalExceptionHandler { return Result.error(null, 500, "[" + primaryKeyErrorMatcher.group(1) + "]已存在"); } + // corn表达式错误 + String cronExpression = "CronExpression '(.*?)' is invalid"; + Matcher cronExpressionMatcher = Pattern.compile(cronExpression).matcher(message); + if (cronExpressionMatcher.find()) { + return Result.error(null, 500, "表达式 " + cronExpressionMatcher.group(1) + " 不合法"); + } + log.error("GlobalExceptionHandler===>运行时异常信息:{}", message); exception.printStackTrace(); return Result.error(null, 500, "服务器异常"); diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/utils/mail/MailSenderUtil.java b/common/service-utils/src/main/java/cn/bunny/common/service/utils/mail/MailSenderUtil.java index 5b8690f..9aed3d4 100644 --- a/common/service-utils/src/main/java/cn/bunny/common/service/utils/mail/MailSenderUtil.java +++ b/common/service-utils/src/main/java/cn/bunny/common/service/utils/mail/MailSenderUtil.java @@ -4,14 +4,38 @@ import cn.bunny.dao.pojo.common.EmailSend; import cn.bunny.dao.pojo.common.EmailSendInit; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; +import org.jetbrains.annotations.NotNull; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.web.multipart.MultipartFile; import java.util.Objects; +import java.util.Properties; public class MailSenderUtil { + /** + * 如果启用SSL需要配置以下 + * + * @param emailSendInit 邮件发送初始化 + */ + private static @NotNull Properties getProperties(EmailSendInit emailSendInit) { + Properties properties = new Properties(); + // 开启认证 + properties.setProperty("mail.smtp.auth", "true"); + // 启用调试 + properties.setProperty("mail.debug", "false"); + // 设置链接超时 + properties.setProperty("mail.smtp.timeout", "200000"); + // 设置端口 + properties.setProperty("mail.smtp.port", Integer.toString(25)); + // 设置ssl端口 + properties.setProperty("mail.smtp.socketFactory.port", Integer.toString(emailSendInit.getPort())); + properties.setProperty("mail.smtp.socketFactory.fallback", "false"); + properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + return properties; + } + /** * * 邮件发送初始化 * @@ -26,6 +50,12 @@ public class MailSenderUtil { javaMailSender.setProtocol(emailSendInit.getProtocol()); javaMailSender.setDefaultEncoding("UTF-8"); + // 如果开启SSL + if (emailSendInit.getOpenSSL()) { + Properties properties = getProperties(emailSendInit); + javaMailSender.setJavaMailProperties(properties); + } + return javaMailSender; } diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/utils/minio/MinioUtil.java b/common/service-utils/src/main/java/cn/bunny/common/service/utils/minio/MinioUtil.java index 018e218..3293eee 100644 --- a/common/service-utils/src/main/java/cn/bunny/common/service/utils/minio/MinioUtil.java +++ b/common/service-utils/src/main/java/cn/bunny/common/service/utils/minio/MinioUtil.java @@ -88,7 +88,7 @@ public class MinioUtil { return minioFile; } catch (Exception exception) { exception.printStackTrace(); - throw new AuthCustomerException(ResultCodeEnum.UPDATE_ERROR); + throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR); } } @@ -136,7 +136,7 @@ public class MinioUtil { minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(filename).stream(inputStream, size, -1).build()); } catch (Exception exception) { log.error("上传文件失败:{}", (Object) exception.getStackTrace()); - throw new AuthCustomerException(ResultCodeEnum.UPDATE_ERROR); + throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR); } } diff --git a/dao/src/main/java/cn/bunny/dao/dto/quartz/schedule/SchedulersUpdateDto.java b/dao/src/main/java/cn/bunny/dao/dto/quartz/schedule/SchedulersUpdateDto.java index 2ebb82e..560f7a7 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/quartz/schedule/SchedulersUpdateDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/quartz/schedule/SchedulersUpdateDto.java @@ -2,7 +2,6 @@ package cn.bunny.dao.dto.quartz.schedule; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -17,32 +16,19 @@ public class SchedulersUpdateDto { @Schema(name = "jobName", title = "任务名称") @NotBlank(message = "任务名称不能为空") - @NotNull(message = "任务名称不能为空") private String jobName; @Schema(name = "jobGroup", title = "任务分组") @NotBlank(message = "任务分组不能为空") - @NotNull(message = "任务分组不能为空") private String jobGroup; @Schema(name = "description", title = "任务详情") @NotBlank(message = "任务详情不能为空") - @NotNull(message = "任务详情不能为空") private String description; - @Schema(name = "jobClassName", title = "任务类名称") - @NotBlank(message = "corn表达式不能为空") - @NotNull(message = "corn表达式不能为空") - private String jobClassName; - @Schema(name = "cronExpression", title = "corn表达式") @NotBlank(message = "corn表达式不能为空") - @NotNull(message = "corn表达式不能为空") private String cronExpression; - @Schema(name = "jobMethodName", title = "执行方法") - @NotBlank(message = "执行方法不能为空") - @NotNull(message = "执行方法不能为空") - private String jobMethodName; } \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/pojo/common/EmailSendInit.java b/dao/src/main/java/cn/bunny/dao/pojo/common/EmailSendInit.java index d25bd58..d18b7fb 100644 --- a/dao/src/main/java/cn/bunny/dao/pojo/common/EmailSendInit.java +++ b/dao/src/main/java/cn/bunny/dao/pojo/common/EmailSendInit.java @@ -40,4 +40,7 @@ public class EmailSendInit { @NotNull(message = "密码不能为空") private String password; + @Schema(name = "openSSL", description = "启用SSL") + private Boolean openSSL; + } \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java b/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java index c078401..e78cad3 100644 --- a/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java +++ b/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java @@ -60,6 +60,7 @@ public enum ResultCodeEnum { THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"), // 提示错误 + UPDATE_ERROR(216, "修改失败"), URL_ENCODE_ERROR(216, "URL编码失败"), ILLEGAL_CALLBACK_REQUEST_ERROR(217, "非法回调请求"), FETCH_USERINFO_ERROR(219, "获取用户信息失败"), @@ -77,7 +78,7 @@ public enum ResultCodeEnum { // 系统错误 500 UNKNOWN_EXCEPTION(500, "服务异常"), SERVICE_ERROR(500, "服务异常"), - UPDATE_ERROR(500, "上传文件失败"), + UPLOAD_ERROR(500, "上传失败"), FAIL(500, "失败"), ; diff --git a/service/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java b/service/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java index f504c79..5c12982 100644 --- a/service/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java +++ b/service/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java @@ -3,6 +3,7 @@ package cn.bunny.services.controller.schedule; import cn.bunny.dao.dto.quartz.SchedulersOperationDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersAddDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersDto; +import cn.bunny.dao.dto.quartz.schedule.SchedulersUpdateDto; import cn.bunny.dao.entity.quartz.Schedulers; import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.pojo.result.Result; @@ -64,6 +65,13 @@ public class SchedulersController { return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS)); } + @Operation(summary = "更新任务", description = "更新任务") + @PutMapping("updateSchedulers") + public Result updateSchedulers(@Valid @RequestBody SchedulersUpdateDto dto) { + schedulersService.updateSchedulers(dto); + return Result.success(ResultCodeEnum.UPDATE_SUCCESS); + } + @Operation(summary = "暂停任务", description = "暂停任务") @PutMapping("/pauseSchedulers") public Result pause(@RequestBody SchedulersOperationDto dto) { diff --git a/service/src/main/java/cn/bunny/services/factory/BillFactory.java b/service/src/main/java/cn/bunny/services/factory/BillFactory.java index 5fee776..ba1c759 100644 --- a/service/src/main/java/cn/bunny/services/factory/BillFactory.java +++ b/service/src/main/java/cn/bunny/services/factory/BillFactory.java @@ -1,19 +1,24 @@ package cn.bunny.services.factory; import cn.bunny.common.service.exception.AuthCustomerException; +import cn.bunny.dao.dto.financial.bill.BillDto; import cn.bunny.dao.dto.financial.bill.IncomeExpenseQueryDto; import cn.bunny.dao.dto.financial.bill.excel.BillExportDto; import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.dao.entity.system.EmailTemplate; import cn.bunny.dao.excel.BillExportExcelByUser; import cn.bunny.dao.pojo.constant.LocalDateTimeConstant; +import cn.bunny.dao.pojo.enums.EmailTemplateEnums; import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.financial.admin.BillVo; import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome; +import cn.bunny.services.mapper.email.EmailTemplateMapper; import cn.bunny.services.mapper.financial.BillMapper; +import cn.bunny.services.mapper.system.UserMapper; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -42,6 +47,12 @@ public class BillFactory { @Autowired private EmailFactory emailFactory; + @Autowired + private EmailTemplateMapper emailTemplateMapper; + + @Autowired + private UserMapper userMapper; + public void exportBill(BillExportDto dto, HttpServletResponse response) { LocalDate startDate = dto.getStartDate(); LocalDate endDate = dto.getEndDate(); @@ -106,6 +117,39 @@ public class BillFactory { } } + /** + * 账单报告 + * + * @param startOfDay 开始日期 + * @param endOfDay 结束日期 + */ + public void billReport(LocalDate startOfDay, LocalDate endOfDay) { + // 查询验证码邮件模板 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(EmailTemplate::getIsDefault, true); + lambdaQueryWrapper.eq(EmailTemplate::getType, EmailTemplateEnums.BILL_WEEK_NOTIFICATION.getType()); + EmailTemplate emailTemplate = emailTemplateMapper.selectOne(lambdaQueryWrapper); + + // 查询需要发送邮件的用户 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(AdminUser::getWeekBillReport, true) + .eq(AdminUser::getStatus, false)// 没有被禁用的 + .isNotNull(AdminUser::getEmail);// 有邮箱的 + List userList = userMapper.selectList(queryWrapper); + + userList.forEach(user -> { + // 查询当前用户账单数据 + BillDto billDto = new BillDto(); + billDto.setUserId(user.getId()); + billDto.setStartDate(startOfDay); + billDto.setEndDate(endOfDay.plusDays(1)); + List billVoList = billMapper.selectListByBillNotification(billDto); + + // 发送邮件 + executeSendEmail(startOfDay, endOfDay, billVoList, user, emailTemplate); + }); + } + /** * 整理当前日期和参数并发送邮件 * diff --git a/service/src/main/java/cn/bunny/services/factory/EmailFactory.java b/service/src/main/java/cn/bunny/services/factory/EmailFactory.java index 5e7e4af..5d8b4ea 100644 --- a/service/src/main/java/cn/bunny/services/factory/EmailFactory.java +++ b/service/src/main/java/cn/bunny/services/factory/EmailFactory.java @@ -50,6 +50,7 @@ public class EmailFactory { BeanUtils.copyProperties(emailUsers, emailSendInit); emailSendInit.setUsername(emailUsers.getEmail()); emailSendInit.setProtocol(emailUsers.getSmtpAgreement()); + emailSendInit.setOpenSSL(true); // 邮件发送模板 EmailSend emailSend = new EmailSend(); diff --git a/service/src/main/java/cn/bunny/services/quartz/MailBillReportByMouth.java b/service/src/main/java/cn/bunny/services/quartz/MailBillReportByMouth.java new file mode 100644 index 0000000..290c280 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/quartz/MailBillReportByMouth.java @@ -0,0 +1,29 @@ +package cn.bunny.services.quartz; + +import cn.bunny.services.aop.annotation.QuartzSchedulers; +import cn.bunny.services.factory.BillFactory; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; + +@QuartzSchedulers(type = "email-bill-mouth-report", description = "账单邮件任务-月") +@Component +public class MailBillReportByMouth implements Job { + + @Autowired + private BillFactory billFactory; + + @Override + public void execute(JobExecutionContext jobExecutionContext) { + LocalDate today = LocalDate.now(); + + // 这个日期的开始月份和结束月份 + LocalDate startOfMouth = today.withDayOfMonth(1); + LocalDate endOfMouth = today.withDayOfMonth(today.lengthOfMonth()); + + billFactory.billReport(startOfMouth, endOfMouth); + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/quartz/MailBillReportByWeek.java b/service/src/main/java/cn/bunny/services/quartz/MailBillReportByWeek.java new file mode 100644 index 0000000..1657e5d --- /dev/null +++ b/service/src/main/java/cn/bunny/services/quartz/MailBillReportByWeek.java @@ -0,0 +1,31 @@ +package cn.bunny.services.quartz; + +import cn.bunny.services.aop.annotation.QuartzSchedulers; +import cn.bunny.services.factory.BillFactory; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; + +@QuartzSchedulers(type = "email-bill-week-report", description = "账单邮件任务-周") +@Component +public class MailBillReportByWeek implements Job { + + @Autowired + private BillFactory billFactory; + + @Override + public void execute(JobExecutionContext jobExecutionContext) { + LocalDate today = LocalDate.now(); + + // 这周的开始日期和结束日期 + LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); + + billFactory.billReport(startOfWeek, endOfWeek); + } +} diff --git a/service/src/main/java/cn/bunny/services/quartz/MailingJob.java b/service/src/main/java/cn/bunny/services/quartz/MailingJob.java deleted file mode 100644 index 39bcf39..0000000 --- a/service/src/main/java/cn/bunny/services/quartz/MailingJob.java +++ /dev/null @@ -1,73 +0,0 @@ -package cn.bunny.services.quartz; - -import cn.bunny.dao.dto.financial.bill.BillDto; -import cn.bunny.dao.entity.system.AdminUser; -import cn.bunny.dao.entity.system.EmailTemplate; -import cn.bunny.dao.pojo.enums.EmailTemplateEnums; -import cn.bunny.dao.vo.financial.admin.BillVo; -import cn.bunny.services.aop.annotation.QuartzSchedulers; -import cn.bunny.services.factory.BillFactory; -import cn.bunny.services.mapper.email.EmailTemplateMapper; -import cn.bunny.services.mapper.financial.BillMapper; -import cn.bunny.services.mapper.system.UserMapper; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.time.DayOfWeek; -import java.time.LocalDate; -import java.time.temporal.TemporalAdjusters; -import java.util.List; - -@QuartzSchedulers(type = "email-bill-week-report", description = "账单邮件任务-周") -@Component -public class MailingJob implements Job { - - @Autowired - private EmailTemplateMapper emailTemplateMapper; - - @Autowired - private BillMapper billMapper; - - @Autowired - private UserMapper userMapper; - - @Autowired - private BillFactory billFactory; - - @Override - public void execute(JobExecutionContext jobExecutionContext) { - LocalDate today = LocalDate.now(); - LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); - LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); - - // 查询验证码邮件模板 - LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); - lambdaQueryWrapper.eq(EmailTemplate::getIsDefault, true); - lambdaQueryWrapper.eq(EmailTemplate::getType, EmailTemplateEnums.BILL_WEEK_NOTIFICATION.getType()); - EmailTemplate emailTemplate = emailTemplateMapper.selectOne(lambdaQueryWrapper); - - // 查询需要发送邮件的用户 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(AdminUser::getWeekBillReport, true) - .eq(AdminUser::getStatus, false)// 没有被禁用的 - .isNotNull(AdminUser::getEmail);// 有邮箱的 - List userList = userMapper.selectList(queryWrapper); - - userList.forEach(user -> { - Long userId = user.getId(); - String email = user.getEmail(); - - // 查询当前用户账单数据 - BillDto billDto = new BillDto(); - billDto.setUserId(userId); - billDto.setStartDate(startOfWeek); - billDto.setEndDate(endOfWeek.plusDays(1)); - List billVoList = billMapper.selectListByBillNotification(billDto); - - billFactory.executeSendEmail(startOfWeek, endOfWeek, billVoList, user, emailTemplate); - }); - } -} diff --git a/service/src/main/java/cn/bunny/services/service/financial/impl/BillServiceImpl.java b/service/src/main/java/cn/bunny/services/service/financial/impl/BillServiceImpl.java index 9bb141f..1dcc53a 100644 --- a/service/src/main/java/cn/bunny/services/service/financial/impl/BillServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/financial/impl/BillServiceImpl.java @@ -278,7 +278,7 @@ public class BillServiceImpl extends ServiceImpl implements Bi try { EasyExcel.read(file.getInputStream(), BillImportByUserDto.class, new BillAddUserListener(categoryMapper, messageMapper, messageReceivedMapper, this)).sheet().doRead(); } catch (IOException e) { - throw new AuthCustomerException(ResultCodeEnum.UPDATE_ERROR); + throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR); } } diff --git a/service/src/main/java/cn/bunny/services/service/schedule/SchedulersService.java b/service/src/main/java/cn/bunny/services/service/schedule/SchedulersService.java index 663a415..b906574 100644 --- a/service/src/main/java/cn/bunny/services/service/schedule/SchedulersService.java +++ b/service/src/main/java/cn/bunny/services/service/schedule/SchedulersService.java @@ -3,6 +3,7 @@ package cn.bunny.services.service.schedule; import cn.bunny.dao.dto.quartz.SchedulersOperationDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersAddDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersDto; +import cn.bunny.dao.dto.quartz.schedule.SchedulersUpdateDto; import cn.bunny.dao.entity.quartz.Schedulers; import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.vo.quartz.SchedulersVo; @@ -64,4 +65,11 @@ public interface SchedulersService extends IService { * @return 所有调度任务内容 */ List> getAllScheduleJobList(); + + /** + * 更新任务 + * + * @param dto 更新任务表单 + */ + void updateSchedulers(SchedulersUpdateDto dto); } diff --git a/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java b/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java index c09e90a..d33a94e 100644 --- a/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java @@ -4,8 +4,10 @@ import cn.bunny.common.service.exception.AuthCustomerException; import cn.bunny.dao.dto.quartz.SchedulersOperationDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersAddDto; import cn.bunny.dao.dto.quartz.schedule.SchedulersDto; +import cn.bunny.dao.dto.quartz.schedule.SchedulersUpdateDto; import cn.bunny.dao.entity.quartz.Schedulers; import cn.bunny.dao.pojo.result.PageResult; +import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.quartz.SchedulersVo; import cn.bunny.services.aop.AnnotationScanner; import cn.bunny.services.aop.annotation.QuartzSchedulers; @@ -20,10 +22,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** *

@@ -92,6 +91,36 @@ public class SchedulersServiceImpl extends ServiceImpl