1.优化链接配置
2.关闭套票发放任务【支付成功回调取代】 3.优化定时解冻水票业务,每月1号即可释放本月水票
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
package com.gxwebsoft.glt.controller;
|
||||
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.BatchParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketReleaseService;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketRelease;
|
||||
import com.gxwebsoft.glt.param.GltUserTicketReleaseParam;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.BatchParam;
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketReleaseService;
|
||||
import com.gxwebsoft.glt.service.impl.GltUserTicketAutoReleaseServiceImpl;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@@ -31,6 +31,9 @@ public class GltUserTicketReleaseController extends BaseController {
|
||||
@Resource
|
||||
private GltUserTicketReleaseService gltUserTicketReleaseService;
|
||||
|
||||
@Resource
|
||||
private GltUserTicketAutoReleaseServiceImpl gltUserTicketAutoReleaseService;
|
||||
|
||||
@PreAuthorize("hasAuthority('glt:gltUserTicketRelease:list')")
|
||||
@Operation(summary = "分页查询水票释放")
|
||||
@GetMapping("/page")
|
||||
@@ -126,4 +129,11 @@ public class GltUserTicketReleaseController extends BaseController {
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "水票释放测试")
|
||||
@PostMapping("/releaseTask")
|
||||
public ApiResult<?> releaseTask() {
|
||||
gltUserTicketAutoReleaseService.releaseTask();
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class GltUserTicketRelease implements Serializable {
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "水票ID")
|
||||
private Long userTicketId;
|
||||
private Integer userTicketId;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private Integer userId;
|
||||
@@ -56,6 +56,9 @@ public class GltUserTicketRelease implements Serializable {
|
||||
@Schema(description = "状态")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
|
||||
@@ -37,6 +37,13 @@ public interface GltUserTicketReleaseMapper extends BaseMapper<GltUserTicketRele
|
||||
*/
|
||||
List<GltUserTicketRelease> selectListRel(@Param("param") GltUserTicketReleaseParam param);
|
||||
|
||||
/**
|
||||
* 查询当月待释放水票数据
|
||||
* @param limitNum 查询数量
|
||||
* @return List<User>
|
||||
*/
|
||||
List<GltUserTicketRelease> getThisMonthReleaseList(@Param("limitNum") Integer limitNum);
|
||||
|
||||
/**
|
||||
* 查询待释放且到期的记录(加行锁,防止多实例重复处理)
|
||||
*
|
||||
|
||||
@@ -58,5 +58,23 @@
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.glt.entity.GltUserTicketRelease">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
<select id="getThisMonthReleaseList" resultType="com.gxwebsoft.glt.entity.GltUserTicketRelease">
|
||||
SELECT
|
||||
id,
|
||||
user_ticket_id,
|
||||
user_id,
|
||||
release_qty,
|
||||
tenant_id
|
||||
FROM
|
||||
glt_user_ticket_release
|
||||
WHERE
|
||||
STATUS = 0
|
||||
AND deleted = 0
|
||||
AND release_qty > 0
|
||||
AND DATE_FORMAT(release_time, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m')
|
||||
ORDER BY
|
||||
release_time ASC
|
||||
LIMIT #{limitNum}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -501,7 +501,7 @@ public class GltTicketIssueService {
|
||||
LocalDateTime releaseTime,
|
||||
LocalDateTime now) {
|
||||
GltUserTicketRelease r = new GltUserTicketRelease();
|
||||
r.setUserTicketId(userTicket.getId() != null ? userTicket.getId().longValue() : null);
|
||||
r.setUserTicketId(userTicket.getId() != null ? userTicket.getId() : null);
|
||||
r.setUserId(userTicket.getUserId());
|
||||
r.setPeriodNo(periodNo);
|
||||
r.setReleaseQty(releaseQty);
|
||||
|
||||
@@ -133,7 +133,7 @@ public class GltTicketRevokeService {
|
||||
LambdaUpdateWrapper<GltUserTicketRelease> uw = new LambdaUpdateWrapper<GltUserTicketRelease>()
|
||||
.eq(GltUserTicketRelease::getTenantId, tenantId)
|
||||
.eq(GltUserTicketRelease::getDeleted, 0)
|
||||
.eq(GltUserTicketRelease::getUserTicketId, userTicketId.longValue())
|
||||
.eq(GltUserTicketRelease::getUserTicketId, userTicketId)
|
||||
// status 为空时也视为“未完成”
|
||||
.and(w -> w.ne(GltUserTicketRelease::getStatus, RELEASE_STATUS_DONE)
|
||||
.or().isNull(GltUserTicketRelease::getStatus))
|
||||
|
||||
@@ -17,10 +17,8 @@ public interface GltUserTicketAutoReleaseService {
|
||||
int releaseDue(LocalDateTime now, int batchSize);
|
||||
|
||||
/**
|
||||
* 释放到期的冻结水票(使用系统当前时间)
|
||||
* 释放到期的冻结水票【当次执行1000条】
|
||||
*/
|
||||
default int releaseDue(int batchSize) {
|
||||
return releaseDue(LocalDateTime.now(), batchSize);
|
||||
}
|
||||
void releaseTask();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gxwebsoft.glt.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicket;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketLog;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketRelease;
|
||||
@@ -7,13 +8,20 @@ import com.gxwebsoft.glt.mapper.GltUserTicketLogMapper;
|
||||
import com.gxwebsoft.glt.mapper.GltUserTicketMapper;
|
||||
import com.gxwebsoft.glt.mapper.GltUserTicketReleaseMapper;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketAutoReleaseService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketLogService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketReleaseService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 冻结水票自动释放实现:
|
||||
@@ -23,7 +31,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GltUserTicketAutoReleaseServiceImpl implements GltUserTicketAutoReleaseService {
|
||||
|
||||
/**
|
||||
@@ -44,6 +52,13 @@ public class GltUserTicketAutoReleaseServiceImpl implements GltUserTicketAutoRel
|
||||
private final GltUserTicketMapper userTicketMapper;
|
||||
private final GltUserTicketLogMapper userTicketLogMapper;
|
||||
|
||||
private GltUserTicketReleaseService gltUserTicketReleaseService;
|
||||
|
||||
private GltUserTicketService gltUserTicketService;
|
||||
|
||||
private GltUserTicketLogService gltUserTicketLogService;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int releaseDue(LocalDateTime now, int batchSize) {
|
||||
@@ -71,12 +86,7 @@ public class GltUserTicketAutoReleaseServiceImpl implements GltUserTicketAutoRel
|
||||
continue;
|
||||
}
|
||||
|
||||
long userTicketIdLong = rel.getUserTicketId();
|
||||
if (userTicketIdLong > Integer.MAX_VALUE || userTicketIdLong < 1) {
|
||||
markFailed(rel.getId(), now, "userTicketId超范围");
|
||||
continue;
|
||||
}
|
||||
Integer userTicketId = (int) userTicketIdLong;
|
||||
Integer userTicketId = rel.getUserTicketId();
|
||||
|
||||
// 先释放冻结数量(条件更新,确保 frozen_qty >= qty)
|
||||
int updated = userTicketMapper.releaseFrozenQty(
|
||||
@@ -129,4 +139,96 @@ public class GltUserTicketAutoReleaseServiceImpl implements GltUserTicketAutoRel
|
||||
releaseMapper.updateStatus(releaseId, RELEASE_STATUS_FAILED, now);
|
||||
log.warn("冻结水票释放标记失败 - releaseId={}, reason={}", releaseId, reason);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void releaseTask() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
log.info("***执行水票释放任务***-执行时间:{}", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
long start = System.currentTimeMillis();
|
||||
List<GltUserTicketRelease> releaseList = releaseMapper.getThisMonthReleaseList(1000);
|
||||
if(CollectionUtils.isEmpty(releaseList)){
|
||||
log.info("***本轮任务无待释放水票数据***");
|
||||
return;
|
||||
}
|
||||
|
||||
//查询用户水票信息
|
||||
List<Integer> userTickIdList = releaseList.stream().map(GltUserTicketRelease::getUserTicketId).distinct().collect(Collectors.toList());
|
||||
LambdaQueryWrapper<GltUserTicket> userTicketLambdaQueryWrapper = new LambdaQueryWrapper<GltUserTicket>().select(GltUserTicket::getId, GltUserTicket::getAvailableQty,
|
||||
GltUserTicket::getFrozenQty, GltUserTicket::getReleasedQty).in(GltUserTicket::getId, userTickIdList);
|
||||
List<GltUserTicket> userTicketList = userTicketMapper.selectList(userTicketLambdaQueryWrapper);
|
||||
|
||||
//创建修改用户水票集合、水票释放计划记录集合
|
||||
List<GltUserTicket> updateUserTicketList = new ArrayList<>();
|
||||
List<GltUserTicketLog> userTicketLogList = new ArrayList<>();
|
||||
|
||||
//遍历水票释放数据执行释放任务
|
||||
releaseList.forEach(release ->{
|
||||
//1.缺少水票ID、用户ID、租户ID记录错误记录
|
||||
if(release.getUserTicketId() == null || release.getUserId() == null || release.getTenantId() == null){
|
||||
release.setRemark("缺少userTicketId/userId/tenantId");
|
||||
release.setStatus(2);
|
||||
release.setUpdateTime(now);
|
||||
}
|
||||
|
||||
GltUserTicket userTicket = userTicketList.stream().filter(gltUserTicket -> release.getUserTicketId().equals(gltUserTicket.getId())).findFirst().orElse(null);
|
||||
if(userTicket != null){
|
||||
Integer releaseQty = release.getReleaseQty();
|
||||
if(userTicket.getFrozenQty() > releaseQty){
|
||||
//更改用户水票可用数量、冻结数量、已释放数量
|
||||
userTicket.setAvailableQty(userTicket.getAvailableQty() + releaseQty);
|
||||
userTicket.setFrozenQty(userTicket.getFrozenQty() - releaseQty);
|
||||
userTicket.setReleasedQty(userTicket.getReleasedQty() + releaseQty);
|
||||
userTicket.setUpdateTime(now);
|
||||
updateUserTicketList.add(userTicket);
|
||||
|
||||
//记录水票释放计划为成功释放状态
|
||||
release.setStatus(1);
|
||||
release.setRemark("success");
|
||||
release.setUpdateTime(now);
|
||||
|
||||
//生成水票释放记录
|
||||
GltUserTicketLog ticketLog = new GltUserTicketLog();
|
||||
ticketLog.setUserTicketId(release.getUserTicketId());
|
||||
ticketLog.setChangeType(CHANGE_TYPE_RELEASE);
|
||||
ticketLog.setChangeAvailable(releaseQty);
|
||||
ticketLog.setChangeFrozen(-releaseQty);
|
||||
ticketLog.setChangeUsed(0);
|
||||
ticketLog.setAvailableAfter(userTicket.getAvailableQty());
|
||||
ticketLog.setFrozenAfter(userTicket.getFrozenQty());
|
||||
ticketLog.setUsedAfter(userTicket.getUsedQty());
|
||||
ticketLog.setOrderId(Integer.valueOf(String.valueOf(release.getId())));
|
||||
ticketLog.setUserId(release.getUserId());
|
||||
ticketLog.setComments("冻结水票到期释放");
|
||||
ticketLog.setTenantId(release.getTenantId());
|
||||
ticketLog.setCreateTime(now);
|
||||
ticketLog.setUpdateTime(now);
|
||||
userTicketLogList.add(ticketLog);
|
||||
}else {
|
||||
release.setRemark("释放数量大于冻结数量,释放:" + releaseQty + ",冻结:" + userTicket.getFrozenQty());
|
||||
release.setStatus(2);
|
||||
release.setUpdateTime(LocalDateTime.now());
|
||||
}
|
||||
}else {
|
||||
release.setRemark("查询不到水票数据");
|
||||
release.setStatus(2);
|
||||
release.setUpdateTime(LocalDateTime.now());
|
||||
}
|
||||
});
|
||||
|
||||
if(CollectionUtils.isNotEmpty(releaseList)){
|
||||
gltUserTicketReleaseService.updateBatchById(releaseList);
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(updateUserTicketList)){
|
||||
gltUserTicketService.updateBatchById(updateUserTicketList);
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(userTicketLogList)){
|
||||
gltUserTicketLogService.saveBatch(userTicketLogList);
|
||||
}
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
long costMs = end - start;
|
||||
log.info("***执行水票释放任务完成*** 执行耗时:{} ms", costMs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class GltTicketIssue10584Task {
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
@Scheduled(cron = "${glt.ticket.issue10584.cron:0/15 * * * * ?}")
|
||||
// @Scheduled(cron = "${glt.ticket.issue10584.cron:0/15 * * * * ?}")
|
||||
@IgnoreTenant("定时任务无登录态,需忽略租户隔离;内部使用 tenantId=10584 精确过滤")
|
||||
public void run() {
|
||||
if (!running.compareAndSet(false, true)) {
|
||||
|
||||
@@ -25,25 +25,17 @@ public class GltUserTicketAutoReleaseTask {
|
||||
|
||||
private final GltUserTicketAutoReleaseService autoReleaseService;
|
||||
|
||||
@Value("${glt.ticket.auto-release.batch-size:200}")
|
||||
private int batchSize;
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
@Scheduled(cron = "${glt.ticket.auto-release.cron:0 */10 * * * ?}")
|
||||
@Scheduled(cron = "${glt.ticket.auto-release.cron:0 */2 1-3 1 * ?}")
|
||||
@IgnoreTenant("定时任务无登录态,需忽略租户隔离;释放记录自带 tenantId,更新时会校验 tenantId")
|
||||
public void run() {
|
||||
if (!running.compareAndSet(false, true)) {
|
||||
log.warn("冻结水票自动释放任务仍在执行中,本轮跳过");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
int released = autoReleaseService.releaseDue(now, Math.max(batchSize, 1));
|
||||
if (released > 0) {
|
||||
log.info("冻结水票自动释放完成 - released={}, now={}", released, now);
|
||||
}
|
||||
autoReleaseService.releaseTask();
|
||||
} finally {
|
||||
running.set(false);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ spring:
|
||||
|
||||
redis:
|
||||
database: 0
|
||||
host: 1Panel-redis-GmNr
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
password: redis_t74P8C
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@ spring:
|
||||
|
||||
redis:
|
||||
database: 0
|
||||
host: 47.107.249.41
|
||||
port: 16379
|
||||
password: redis_t74P8C
|
||||
host: localhost
|
||||
port: 6379
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
|
||||
@@ -5,6 +5,8 @@ server:
|
||||
spring:
|
||||
profiles:
|
||||
active: local
|
||||
# active: dev
|
||||
# active: prod
|
||||
|
||||
application:
|
||||
name: server
|
||||
|
||||
Reference in New Issue
Block a user