fix: 增加催促功能
This commit is contained in:
parent
b7d47f2268
commit
83038f6fbe
@ -46,7 +46,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -162,7 +161,6 @@ public class FishDraftDataController {
|
|||||||
|
|
||||||
@PostMapping("/batchSaveDraft")
|
@PostMapping("/batchSaveDraft")
|
||||||
@Operation(summary = "批量保存草稿")
|
@Operation(summary = "批量保存草稿")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public ResponseResult saveDraft(@RequestBody FishImportRowRequest request) {
|
public ResponseResult saveDraft(@RequestBody FishImportRowRequest request) {
|
||||||
String taskId = request.getTaskId();
|
String taskId = request.getTaskId();
|
||||||
ImportTask importTask = importTaskService.getById(taskId);
|
ImportTask importTask = importTaskService.getById(taskId);
|
||||||
@ -185,8 +183,8 @@ public class FishDraftDataController {
|
|||||||
data.setPicpthList(row.getPicpthList());
|
data.setPicpthList(row.getPicpthList());
|
||||||
fishDraftDataList.add(data);
|
fishDraftDataList.add(data);
|
||||||
}
|
}
|
||||||
boolean result = fishDraftDataService.saveBatch(fishDraftDataList);
|
boolean result = fishDraftDataService.batchSaveDraft(fishDraftDataList);
|
||||||
fishImportService.processAttachmentsAsync(fishDraftDataList,importTask.getTempDir());
|
fishImportService.processAttachmentsAsync(fishDraftDataList, importTask.getTempDir());
|
||||||
importTaskService.markSuccess(taskId);
|
importTaskService.markSuccess(taskId);
|
||||||
return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
|
return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,4 +33,6 @@ public class FishStatisticsVO implements Serializable {
|
|||||||
private Date maxEnddt;
|
private Date maxEnddt;
|
||||||
|
|
||||||
private Integer totalFcnt;
|
private Integer totalFcnt;
|
||||||
|
|
||||||
|
private Integer hasData;
|
||||||
}
|
}
|
||||||
@ -96,4 +96,9 @@ public interface IFishDraftDataService extends IService<FishDraftData> {
|
|||||||
* 审批人修改数据并记录变更日志
|
* 审批人修改数据并记录变更日志
|
||||||
*/
|
*/
|
||||||
boolean updateByIdWithLog(FishDraftData fishDraftData);
|
boolean updateByIdWithLog(FishDraftData fishDraftData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存草稿(带事务,仅包裹 INSERT)
|
||||||
|
*/
|
||||||
|
boolean batchSaveDraft(List<FishDraftData> fishDraftDataList);
|
||||||
}
|
}
|
||||||
@ -657,5 +657,15 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean batchSaveDraft(List<FishDraftData> fishDraftDataList) {
|
||||||
|
if (fishDraftDataList == null || fishDraftDataList.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean result = this.saveBatch(fishDraftDataList, 500);
|
||||||
|
log.info("批量保存草稿完成, 共{}条, 耗时{}ms", fishDraftDataList.size(), System.currentTimeMillis() - start);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@ -41,6 +42,7 @@ import java.util.stream.Collectors;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sms")
|
@RequestMapping("/sms")
|
||||||
@Tag(name = "短信验证码管理")
|
@Tag(name = "短信验证码管理")
|
||||||
|
@Slf4j
|
||||||
public class SmsVerifyCodeController {
|
public class SmsVerifyCodeController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -69,6 +71,7 @@ public class SmsVerifyCodeController {
|
|||||||
|
|
||||||
@Value("${rsa.private_key}")
|
@Value("${rsa.private_key}")
|
||||||
private String privateKey;
|
private String privateKey;
|
||||||
|
private static final String URGE_CONTENT ="根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送验证码
|
* 发送验证码
|
||||||
@ -125,10 +128,10 @@ public class SmsVerifyCodeController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送验证码
|
* 批量发送短信
|
||||||
*/
|
*/
|
||||||
@PostMapping("/batchSendContent")
|
@PostMapping("/batchSendContent")
|
||||||
@Operation(summary = "发送验证码")
|
@Operation(summary = "批量发送短信")
|
||||||
public ResponseResult batchSendContent(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
public ResponseResult batchSendContent(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||||
|
|
||||||
List<String> phoneList = smsVerifyCodeRequest.getPhoneList();
|
List<String> phoneList = smsVerifyCodeRequest.getPhoneList();
|
||||||
@ -140,6 +143,35 @@ public class SmsVerifyCodeController {
|
|||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量催促
|
||||||
|
*/
|
||||||
|
@PostMapping("/batchUrgeContent")
|
||||||
|
@Operation(summary = "催促")
|
||||||
|
public ResponseResult batchUrgeContent(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||||
|
List<String> userIds = smsVerifyCodeRequest.getUserIds();
|
||||||
|
String content = smsVerifyCodeRequest.getContent();
|
||||||
|
|
||||||
|
if ((userIds == null || userIds.isEmpty())) {
|
||||||
|
return ResponseResult.error("用户ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content == null || content.isEmpty()) {
|
||||||
|
content = URGE_CONTENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int successCount = smsVerifyCodeService.urgeByUserIds(userIds, content);
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
// result.put("successCount", successCount);
|
||||||
|
result.put("totalCount", userIds.size());
|
||||||
|
return ResponseResult.successData(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量催促短信发送失败", e);
|
||||||
|
return ResponseResult.error("短信发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -67,5 +67,10 @@ public class SmsVerifyCodeRequest {
|
|||||||
|
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private List<String> userIds;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,4 +50,5 @@ public interface ISmsVerifyCodeService extends IService<SmsVerifyCode> {
|
|||||||
boolean sendAuditNotify(String phone, String auditStatus, String reason);
|
boolean sendAuditNotify(String phone, String auditStatus, String reason);
|
||||||
|
|
||||||
void batchSendContent(List<String> phoneList, String content);
|
void batchSendContent(List<String> phoneList, String content);
|
||||||
|
int urgeByUserIds(List<String> userIds, String content);
|
||||||
}
|
}
|
||||||
@ -1,18 +1,24 @@
|
|||||||
package com.yfd.platform.system.service.impl;
|
package com.yfd.platform.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.yfd.platform.system.domain.SmsVerifyCode;
|
import com.yfd.platform.system.domain.SmsVerifyCode;
|
||||||
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
import com.yfd.platform.system.mapper.SmsVerifyCodeMapper;
|
import com.yfd.platform.system.mapper.SmsVerifyCodeMapper;
|
||||||
|
import com.yfd.platform.system.mapper.SysUserMapper;
|
||||||
import com.yfd.platform.system.service.ISmsVerifyCodeService;
|
import com.yfd.platform.system.service.ISmsVerifyCodeService;
|
||||||
import com.yfd.platform.utils.SmsSender;
|
import com.yfd.platform.utils.SmsSender;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -20,14 +26,19 @@ import java.util.Random;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, SmsVerifyCode> implements ISmsVerifyCodeService {
|
public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, SmsVerifyCode> implements ISmsVerifyCodeService {
|
||||||
|
|
||||||
private static final int CODE_VALID_MINUTES = 5;
|
private static final int CODE_VALID_MINUTES = 5;
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
|
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SmsSender smsSender;
|
private SmsSender smsSender;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public String sendVerifyCode(String phone, Integer type) {
|
public String sendVerifyCode(String phone, Integer type) {
|
||||||
@ -124,13 +135,66 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void batchSendContent(List<String> phoneList, String content) {
|
public void batchSendContent(List<String> phoneList, String content) {
|
||||||
for (String phone : phoneList) {
|
// for (String phone : phoneList) {
|
||||||
try {
|
//
|
||||||
smsSender.send(phone, content);
|
// }
|
||||||
} catch (Exception e) {
|
String phone = StrUtil.join(",", phoneList);
|
||||||
log.debug("批量发送短信失败"+phone);
|
try {
|
||||||
}
|
smsSender.send(phone, content);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("批量发送短信失败"+phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int urgeByUserIds(List<String> userIds, String content) {
|
||||||
|
if (userIds == null || userIds.isEmpty()) {
|
||||||
|
log.warn("催促短信发送失败:用户ID列表为空");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
List<String> ids = userIds.stream().distinct().toList();
|
||||||
|
List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, ids)
|
||||||
|
.eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getStatus,1).select(SysUser::getPhone));
|
||||||
|
|
||||||
|
if (sysUsers.isEmpty()) {
|
||||||
|
log.warn("催促短信发送失败:未找到有效的手机号,userIds: {}", ids);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
List<String> validPhones = sysUsers.stream().map(SysUser::getPhone).filter(this::isValidPhone).toList();
|
||||||
|
|
||||||
|
if (validPhones.isEmpty()) {
|
||||||
|
log.warn("催促短信发送失败:没有合规的手机号");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int successCount = 0;
|
||||||
|
// for (String phone : validPhones) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
String phone = StrUtil.join(",", validPhones);
|
||||||
|
try {
|
||||||
|
boolean sent = smsSender.send(phone, content);
|
||||||
|
if (sent) {
|
||||||
|
successCount++;
|
||||||
|
log.info("催促短信发送成功: {}", phone);
|
||||||
|
} else {
|
||||||
|
log.warn("催促短信发送失败: {}", phone);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("催促短信发送异常: {}", phone, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.info("催促短信发送完成,总数: {}, 成功: {}", validPhones.size(), successCount);
|
||||||
|
return successCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidPhone(String phone) {
|
||||||
|
if (StrUtil.isBlank(phone)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return PHONE_PATTERN.matcher(phone).matches();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<result column="MIN_STRDT" property="minStrdt"/>
|
<result column="MIN_STRDT" property="minStrdt"/>
|
||||||
<result column="MAX_ENDDT" property="maxEnddt"/>
|
<result column="MAX_ENDDT" property="maxEnddt"/>
|
||||||
<result column="TOTAL_FCNT" property="totalFcnt"/>
|
<result column="TOTAL_FCNT" property="totalFcnt"/>
|
||||||
|
<result column="HAS_DATA" property="hasData"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="statisticsQuery">
|
<sql id="statisticsQuery">
|
||||||
@ -146,7 +147,8 @@
|
|||||||
fm.REPORT_MONTH,
|
fm.REPORT_MONTH,
|
||||||
fm.MIN_STRDT,
|
fm.MIN_STRDT,
|
||||||
fm.MAX_ENDDT,
|
fm.MAX_ENDDT,
|
||||||
fm.TOTAL_FCNT
|
fm.TOTAL_FCNT,
|
||||||
|
CASE WHEN fm.CREATED_BY IS NOT NULL THEN 1 ELSE 0 END AS HAS_DATA
|
||||||
FROM all_users u
|
FROM all_users u
|
||||||
JOIN QGC_REFA.SYS_USER su
|
JOIN QGC_REFA.SYS_USER su
|
||||||
ON u.USER_ID = su.ID
|
ON u.USER_ID = su.ID
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user