From 2d68d8d410190b71946d4d71e25baa8736771ae2 Mon Sep 17 00:00:00 2001 From: mashuai Date: Fri, 10 Jan 2025 17:54:09 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=80=E6=96=99=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../material/BonusMaterialApplication.java | 2 + .../purchase/domain/PurchaseCheckDetails.java | 12 ++ .../domain/vo/PurchaseCheckFormVo.java | 10 ++ .../impl/PurchaseCheckInfoServiceImpl.java | 19 ++- .../material/warning/ScheduledConfig.java | 33 +++++ .../material/warning/ScheduledTasks.java | 113 ++++++++++++++++++ .../purchase/PurchaseCheckDetailsMapper.xml | 8 +- 7 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledConfig.java create mode 100644 bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledTasks.java diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/BonusMaterialApplication.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/BonusMaterialApplication.java index 80d7d71a..a11ab80d 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/BonusMaterialApplication.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/BonusMaterialApplication.java @@ -6,6 +6,7 @@ import com.bonus.common.security.annotation.EnableCustomConfig; import com.bonus.common.security.annotation.EnableRyFeignClients; import com.bonus.common.swagger.annotation.EnableCustomSwagger2; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.scheduling.annotation.EnableScheduling; /** * 系统模块 @@ -16,6 +17,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @EnableCustomSwagger2 @EnableRyFeignClients @SpringBootApplication(scanBasePackages = {"com.bonus.common.biz.*", "com.bonus.material.*"}, exclude = { DataSourceAutoConfiguration.class }) +@EnableScheduling public class BonusMaterialApplication { public static void main(String[] args) diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/PurchaseCheckDetails.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/PurchaseCheckDetails.java index b4da4252..42d174c5 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/PurchaseCheckDetails.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/PurchaseCheckDetails.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import java.util.Date; import java.util.List; +import com.bonus.material.archives.domain.ElcSignatureInfo; import com.bonus.material.basic.domain.BmFileInfo; import com.fasterxml.jackson.annotation.JsonFormat; import com.bonus.common.core.annotation.Excel; @@ -34,6 +35,17 @@ public class PurchaseCheckDetails extends BaseEntity { @ApiModelProperty(value = "任务ID") private Long taskId; + @ApiModelProperty(value = "验收人ID") + private Long checkUser; + + /** 验收人信息 */ + @ApiModelProperty(value = "验收人信息") + private List infoList; + + private String signUrl; + + private String signType; + /** 规格id */ //@Excel(name = "规格id") @ApiModelProperty(value = "规格id") diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java index 1eb30397..7fce88c0 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java @@ -1,5 +1,6 @@ package com.bonus.material.purchase.domain.vo; +import com.bonus.material.archives.domain.ElcSignatureInfo; import com.bonus.material.purchase.domain.PurchaseCheckDetails; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -39,4 +40,13 @@ public class PurchaseCheckFormVo { @ApiModelProperty("物资列表") private List materialList = new ArrayList<>(); + /** 验收人信息 */ + @ApiModelProperty(value = "验收人信息") + private List infoList; + + private String signUrl; + + @ApiModelProperty(value = "签名类型 手写0 和 图片上传1") + private String signType; + } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java index 4835d970..0f928fcd 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java @@ -100,7 +100,7 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { break; case PURCHASE_TASK_STAGE_CHECK: purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o -> !PurchaseTaskStatusEnum.TO_NOTICE.getStatus().equals(o.getStatus())).collect(Collectors.toList()); - purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o -> !PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus().equals(o.getStatus())).collect(Collectors.toList()); + //purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o -> !PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus().equals(o.getStatus())).collect(Collectors.toList()); break; case PURCHASE_TASK_STAGE_BIND: purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o -> @@ -411,12 +411,14 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { if (!CollectionUtils.isEmpty(codeList)) { for (PurchaseCheckDetails details : codeList) { details.setStatus(PurchaseTaskStatusEnum.TO_BIND.getStatus()); + details.setCheckUser(SecurityUtils.getUserId()); updateCount += purchaseCheckDetailsMapper.updatePurchaseDetails4Check(details); } } if (!CollectionUtils.isEmpty(numList)) { for (PurchaseCheckDetails details : numList) { details.setStatus(PurchaseTaskStatusEnum.TO_STORE.getStatus()); + details.setCheckUser(SecurityUtils.getUserId()); updateCount += purchaseCheckDetailsMapper.updatePurchaseDetails4Check(details); } } @@ -441,6 +443,7 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { } else if (MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId().equals(details.getManageType())) { details.setStatus(PurchaseTaskStatusEnum.TO_STORE.getStatus()); } + details.setCheckUser(SecurityUtils.getUserId()); result = purchaseCheckDetailsMapper.updatePurchaseDetails4Check(details) > 0 ? AjaxResult.success("detail验证成功") : AjaxResult.error("details无验证信息"); extractedFile(details); } @@ -449,10 +452,10 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { for (PurchaseCheckDetails details : purchaseVerifyVo.getPurchaseCheckDetailsList()) { details.setStatus(PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus()); result = 0 < purchaseCheckDetailsMapper.updatePurchaseDetails4Check(details) ? AjaxResult.success("detail验证驳回成功") : AjaxResult.error("details无验证信息"); - tmTaskMapper.updateTmTask(new TmTask() + /*tmTaskMapper.updateTmTask(new TmTask() .setTaskId(details.getTaskId()) .setTaskType(TmTaskTypeEnum.TM_TASK_PURCHASE.getTaskTypeId()) - .setTaskStatus(PurchaseTaskStatusEnum.TASK_IN_PROGRESS.getStatus())); + .setTaskStatus(PurchaseTaskStatusEnum.TASK_IN_PROGRESS.getStatus()));*/ extractedFile(details); } } @@ -490,8 +493,16 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { public PurchaseCheckFormVo selectPurchaseCheckFormVoByTaskId(Long taskId) { // 执行SQL查询外层信息 final PurchaseCheckFormVo result = purchaseCheckInfoMapper.selectPurchaseCheckFormVoByTaskId(taskId); - if (null != result) { + PurchaseCheckInfo purchaseCheckInfo = new PurchaseCheckInfo(); + purchaseCheckInfo.setTaskId(taskId); + List list = purchaseCheckDetailsMapper.selectPurchaseCheckDetailsListFromInfo(purchaseCheckInfo); + if (!CollectionUtils.isEmpty(list)) { + for (PurchaseCheckDetails purchaseCheckDetails : list) { + result.setSignUrl(purchaseCheckDetails.getSignUrl() != null ? purchaseCheckDetails.getSignUrl() : ""); + result.setSignType(purchaseCheckDetails.getSignType() != null ? purchaseCheckDetails.getSignType() : ""); + } + } // 执行SQL查询内层信息 final List purchaseCheckDetails = purchaseCheckDetailsMapper.selectPurchaseCheckDetailsListByTaskId(taskId, null, SecurityUtils.getUserId()); // 过滤掉空数据 diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledConfig.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledConfig.java new file mode 100644 index 00000000..26e5f5f0 --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledConfig.java @@ -0,0 +1,33 @@ +package com.bonus.material.warning; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +/** + * @Author ma_sh + * @create 2025/1/10 12:00 + */ +@Configuration +@EnableScheduling +public class ScheduledConfig { + + @Bean + public ScheduledTaskRegistrar scheduledTaskRegistrar(TaskScheduler taskScheduler) { + ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); + registrar.setTaskScheduler(taskScheduler); + return registrar; + } + + @Bean + public TaskScheduler taskScheduler() { + ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + scheduler.setPoolSize(10); + scheduler.setThreadNamePrefix("ScheduledTask-"); + return scheduler; + } +} + diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledTasks.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledTasks.java new file mode 100644 index 00000000..34e7a277 --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/warning/ScheduledTasks.java @@ -0,0 +1,113 @@ +package com.bonus.material.warning; + +import com.alibaba.nacos.common.utils.CollectionUtils; +import com.bonus.common.core.utils.StringUtils; +import com.bonus.common.core.utils.sms.SmsUtils; +import com.bonus.material.back.domain.BackApplyInfo; +import com.bonus.material.back.service.IBackApplyInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +/** + * 任务定时推送相关人员任务控制器 + * @author ma_sh + */ +@Component +@Slf4j +public class ScheduledTasks { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Resource + private IBackApplyInfoService backApplyInfoService; + + @Resource + private ScheduledTaskRegistrar scheduledTaskRegistrar; + + /** + * 定时任务执行频率,每3天上午9点执行一次 + */ + private String cronExpression = "0 0 9 */3 * ?"; + + /** + * 初始化定时任务 + */ + @PostConstruct + public void init() { + cronExpression = getCronFromDatabase(); + updateCronTask(); + } + + /** + * 更新定时任务 + */ + private void updateCronTask() { + scheduledTaskRegistrar.getScheduler().schedule(() -> { + taskWithFixedRate(); + }, new CronTrigger(cronExpression)); + } + + /** + * 从数据库中获取 cron 表达式 + * @return + */ + private String getCronFromDatabase() { + // 这里假设从数据库中获取 cron 表达式 + return "0 0 9 */2 * ?"; + } + + /** + * 退料人未签字三天推送一次给李勇 + * 每三天的上午9点执行 + */ + public void taskWithFixedRate() { + log.info("开始执行退料人未签字任务"); + BackApplyInfo info = new BackApplyInfo(); + info.setIsExport(false); + List list = backApplyInfoService.selectBackApplyInfoList(info); + // 用于标记是否有 BackSignUrl 为 null 的记录 + boolean hasNullBackSignUrl = false; + if (CollectionUtils.isNotEmpty(list)) { + // 遍历列表,检查每个 BackApplyInfo 的 BackSignUrl 是否为空 + for (BackApplyInfo backApplyInfo : list) { + if (StringUtils.isBlank(backApplyInfo.getBackSignUrl())) { + hasNullBackSignUrl = true; + break; + } + } + } + if (hasNullBackSignUrl) { + // 统一发送一条短信 + String phoneNumber = "15527030643"; + String content = "您好,李勇!您还有退料单未签字,请及时登录系统查看处理,感谢配合!"; + // 发送短信 + try { + String sendResult = SmsUtils.smsToken(phoneNumber, content, ""); + if (sendResult != null && !sendResult.isEmpty()) { + log.info("短信发送成功: {}", sendResult); + System.out.println("短信发送成功: " + sendResult); + } else { + log.error("短信发送失败,发送结果为空!"); + System.out.println("短信发送失败,发送结果为空!"); + } + } catch (Exception e) { + log.error("短信发送过程中发生异常: {}", e.getMessage()); + System.out.println("短信发送过程中发生异常: " + e.getMessage()); + } + } else { + log.info("没有未签字的退料单"); + System.out.println("没有未签字的退料单"); + } + // 记录任务执行时间 + System.out.println("退料人未签字任务执行时间:" + LocalDateTime.now().format(FORMATTER)); + } + +} \ No newline at end of file diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseCheckDetailsMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseCheckDetailsMapper.xml index 88c76869..bee9f7dd 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseCheckDetailsMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseCheckDetailsMapper.xml @@ -49,10 +49,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pcd.supplier_id, pcd.status, pcd.create_by, pcd.production_time, pcd.create_time, pcd.update_by, pcd.update_time, pcd.remark, pcd.check_url_name, pcd.check_url, pcd.input_num, pcd.input_status, pcd.input_time, pcd.file_name, pcd.file_url, pcd.company_id, pcd.fix_code, mt.type_name, mt.unit_name, mt.unit_value,mtp.type_name as ma_type_name, mt.manage_type as manage_type, - pcd.warn_documents as warnDocuments, pcd.reason as reason, mt.rent_price as rentPrice + pcd.warn_documents as warnDocuments, pcd.reason as reason, mt.rent_price as rentPrice, su.sign_url as signUrl, su.sign_type as signType from purchase_check_details pcd left join ma_type mt on pcd.type_id = mt.type_id left join ma_type mtp on mt.parent_id = mtp.type_id + left join sys_user su on pcd.check_user = su.user_id