记得上下班打卡 | git大法好,push需谨慎

Commit 8b1bec4f authored by 姜秀龙's avatar 姜秀龙

订单处理

parent 914a6421
......@@ -176,4 +176,308 @@ public class JxlDataKylinOrderController {
return ResponseDto.success();
}
@GetMapping("KO003")
@ApiOperation("修复订单支付状态 - 系统故障导致用户支付成功但订单状态未更新")
public ResponseDto KO003() {
try {
log.info("开始批量修复订单支付状态");
// 第一步:查询所有需要修复的订单(支付成功但订单状态未更新的)
log.info("第一步:查询所有需要修复的订单");
String findOrdersSql = "SELECT kot.order_tickets_id, kot.pay_code, kot.order_code, kts.status, kot.user_id " +
"FROM kylin_order_tickets as kot " +
"JOIN dragon_orders as do ON do.code = kot.pay_code " +
"JOIN kylin_order_ticket_status as kts ON kts.order_id = kot.order_tickets_id " +
"WHERE 1 = 1 " +
// "AND kts.status = 0 " +
// "AND kts.status = 2 " +
"AND kts.status = 1 " +
"AND kot.order_code = '572738923375898624308034090' " +
"AND kot.performance_title = '2025珠海草莓音乐节' " +
"AND do.status = 1";
Connection connection = DriverManager.getConnection(SQL_URL, SQL_USER, SQL_PWD);
PreparedStatement stmt = connection.prepareStatement(findOrdersSql);
ResultSetImpl rs = (ResultSetImpl) stmt.executeQuery();
int totalCount = 0;
int successCount = 0;
int failCount = 0;
// 第二步:逐个修复订单
log.info("第二步:开始逐个修复订单");
while (rs.next()) {
totalCount++;
String orderTicketsId = rs.getString("order_tickets_id");
String orderCode = rs.getString("order_code");
String userId = rs.getString("user_id");
try {
log.info("正在修复订单 {} - orderCode: {}, orderTicketsId: {}", totalCount, orderCode, orderTicketsId);
// 第二步补充:检查是否有退款申请记录,有退款申请的不处理
String checkRefundSql = "SELECT COUNT(1) as refund_count FROM kylin_order_refunds WHERE order_tickets_id = ?";
PreparedStatement refundStmt = connection.prepareStatement(checkRefundSql);
refundStmt.setString(1, orderTicketsId);
ResultSetImpl refundRs = (ResultSetImpl) refundStmt.executeQuery();
int refundCount = 0;
if (refundRs.next()) {
refundCount = refundRs.getInt("refund_count");
}
if (refundCount > 0) {
log.warn("订单存在退款申请记录,跳过修复 - orderCode: {}, 退款记录数: {}", orderCode, refundCount);
continue;
}
// 获取支付信息
String verifySql = "SELECT do.payment_id, do.payment_type, do.payment_at " +
"FROM kylin_order_tickets as kot " +
"JOIN dragon_orders as do ON do.code = kot.pay_code " +
"WHERE kot.order_code = ? AND do.status = 1";
PreparedStatement payStmt = connection.prepareStatement(verifySql);
payStmt.setString(1, orderCode);
ResultSetImpl payRs = (ResultSetImpl) payStmt.executeQuery();
String paymentId = null;
String paymentType = null;
String paymentAt = null;
if (payRs.next()) {
paymentId = payRs.getString("payment_id");
paymentType = payRs.getString("payment_type");
paymentAt = payRs.getString("payment_at");
}
// 第三步:更新MySQL中的订单相关表
// 更新订单主表 kylin_order_tickets
KylinOrderTickets orderUpdate = KylinOrderTickets.getNew();
orderUpdate.setPaymentType(paymentType);
orderUpdate.setPaymentId(paymentId);
orderUpdate.setTimePay(paymentAt);
kylinOrderTicketsMapper.update(orderUpdate,
Wrappers.lambdaUpdate(KylinOrderTickets.class)
.eq(KylinOrderTickets::getOrderTicketsId, orderTicketsId)
);
// 更新订单状态表 kylin_order_ticket_status
String updateStatusSql = "UPDATE kylin_order_ticket_status SET status = 1, pay_status = 1 WHERE order_id = ?";
PreparedStatement statusStmt = connection.prepareStatement(updateStatusSql);
statusStmt.setString(1, orderTicketsId);
statusStmt.executeUpdate();
// 更新订单票实体表 kylin_order_ticket_entities
String updateEntitiesSql = "UPDATE kylin_order_ticket_entities SET is_payment = 1 WHERE order_id = ?";
PreparedStatement entitiesStmt = connection.prepareStatement(updateEntitiesSql);
entitiesStmt.setString(1, orderTicketsId);
entitiesStmt.executeUpdate();
// 第四步:更新MongoDB中的订单相关集合
// 更新订单主视图 KylinOrderTicketVo
Document orderUpdateDoc = new Document("$set", new Document()
.append("paymentType", paymentType)
.append("paymentId", paymentId)
.append("timePay", paymentAt)
.append("status", 1)
.append("payStatus", 1)
);
mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
Query.query(Criteria.where("orderTicketsId").is(orderTicketsId)).getQueryObject(),
orderUpdateDoc
);
// 更新订单票实体视图 KylinOrderTicketEntitiesVo
Document entitiesUpdateDoc = new Document("$set", new Document("isPayment", 1));
mongoTemplate.getCollection("KylinOrderTicketEntitiesVo").updateMany(
Query.query(Criteria.where("orderId").is(orderTicketsId)).getQueryObject(),
entitiesUpdateDoc
);
// 第五步:清理Redis缓存
redisDataSourceUtil.getRedisKylinUtil().del(KylinRedisConst.ORDER + orderTicketsId);
redisDataSourceUtil.getRedisKylinUtil().del(KylinRedisConst.ORDER_LIST + userId);
successCount++;
log.info("订单修复成功 - orderCode: {}", orderCode);
} catch (Exception e) {
failCount++;
log.error("订单修复失败 - orderCode: {}, error: ", orderCode, e);
}
}
connection.close();
log.info("批量修复完成 - 总数: {}, 成功: {}, 失败: {}", totalCount, successCount, failCount);
return ResponseDto.success(String.format("批量修复完成!总数: %d, 成功: %d, 失败: %d", totalCount, successCount, failCount));
} catch (Exception e) {
log.error("批量修复订单支付状态失败, error: ", e);
return ResponseDto.failure("批量修复失败: " + e.getMessage());
}
}
@GetMapping("KO004")
@ApiOperation("恢复订单功能(未测试) - 将已退款的订单恢复为待付款状态,延长支付时间到24小时")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", dataType = "String", name = "orderCode", value = "订单编号", required = true)
})
public ResponseDto KO004(@RequestParam("orderCode") String orderCode) {
try {
log.info("开始恢复订单 - orderCode: {}", orderCode);
// 第一步:查询订单信息并验证
log.info("第一步:查询订单信息并验证");
KylinOrderTickets orderTickets = kylinOrderTicketsMapper.selectOne(
Wrappers.lambdaQuery(KylinOrderTickets.class)
.eq(KylinOrderTickets::getOrderCode, orderCode)
);
if (orderTickets == null) {
log.error("订单不存在 - orderCode: {}", orderCode);
return ResponseDto.failure("订单不存在");
}
String orderTicketsId = orderTickets.getOrderTicketsId();
String userId = orderTickets.getUserId();
log.info("找到订单 - orderTicketsId: {}", orderTicketsId);
// 第二步:检查订单当前状态,只有已退款的订单才能恢复
String checkStatusSql = "SELECT status, pay_status FROM kylin_order_ticket_status WHERE order_id = ?";
Connection connection = DriverManager.getConnection(SQL_URL, SQL_USER, SQL_PWD);
PreparedStatement checkStmt = connection.prepareStatement(checkStatusSql);
checkStmt.setString(1, orderTicketsId);
ResultSetImpl statusRs = (ResultSetImpl) checkStmt.executeQuery();
Integer currentStatus = null;
Integer currentPayStatus = null;
if (statusRs.next()) {
currentStatus = statusRs.getInt("status");
currentPayStatus = statusRs.getInt("pay_status");
}
log.info("找到订单状态 - orderTicketsId: {}, 当前status: {}, 当前pay_status: {}",
orderTicketsId, currentStatus, currentPayStatus);
// 检查订单状态,只有已退款的订单(status=4)才能恢复
if (currentStatus == null || currentStatus != 4) {
log.warn("订单状态不是已退款,无法恢复 - orderCode: {}, status: {}", orderCode, currentStatus);
connection.close();
return ResponseDto.failure("只有已退款的订单才能恢复,当前订单状态: " + currentStatus);
}
// 第三步:检查是否有退款记录
log.info("第三步:检查退款记录");
String checkRefundSql = "SELECT COUNT(1) as refund_count FROM kylin_order_refunds WHERE order_tickets_id = ?";
PreparedStatement refundStmt = connection.prepareStatement(checkRefundSql);
refundStmt.setString(1, orderTicketsId);
ResultSetImpl refundRs = (ResultSetImpl) refundStmt.executeQuery();
int refundCount = 0;
if (refundRs.next()) {
refundCount = refundRs.getInt("refund_count");
}
if (refundCount == 0) {
log.error("订单没有退款记录,无法恢复 - orderCode: {}", orderCode);
connection.close();
return ResponseDto.failure("订单没有退款记录,无法恢复");
}
// 第四步:恢复订单状态为待付款
log.info("第四步:恢复订单状态为待付款");
// 更新订单主表 - 清空支付相关信息,重新设置创建时间和支付倒计时
java.time.LocalDateTime now = java.time.LocalDateTime.now();
KylinOrderTickets orderUpdate = KylinOrderTickets.getNew();
orderUpdate.setPaymentType(null);
orderUpdate.setPaymentId(null);
orderUpdate.setTimePay(null);
orderUpdate.setPayCode(""); // 清空支付码,需要重新生成
orderUpdate.setPayCountdownMinute(1440); // 24小时 = 1440分钟
orderUpdate.setCreatedAt(now); // 重新设置创建时间
orderUpdate.setUpdatedAt(now);
kylinOrderTicketsMapper.update(orderUpdate,
Wrappers.lambdaUpdate(KylinOrderTickets.class)
.eq(KylinOrderTickets::getOrderTicketsId, orderTicketsId)
);
// 更新订单状态表 - 改为待付款状态
String updateStatusSql = "UPDATE kylin_order_ticket_status SET status = 0, pay_status = 0, updated_at = ? WHERE order_id = ?";
PreparedStatement statusStmt = connection.prepareStatement(updateStatusSql);
statusStmt.setObject(1, now);
statusStmt.setString(2, orderTicketsId);
statusStmt.executeUpdate();
// 更新订单票实体表 - 改为未支付状态
String updateEntitiesSql = "UPDATE kylin_order_ticket_entities SET is_payment = 0, updated_at = ? WHERE order_id = ?";
PreparedStatement entitiesStmt = connection.prepareStatement(updateEntitiesSql);
entitiesStmt.setObject(1, now);
entitiesStmt.setString(2, orderTicketsId);
entitiesStmt.executeUpdate();
connection.close();
// 第五步:更新MongoDB中的订单相关集合
log.info("第五步:更新MongoDB中的订单相关集合");
// 计算新的过期时间(24小时后)
String overdueAt = now.plusMinutes(1440).format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String createdAtStr = now.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 更新订单主视图 KylinOrderTicketVo
Document orderUpdateDoc = new Document("$set", new Document()
.append("paymentType", null)
.append("paymentId", null)
.append("timePay", null)
.append("payCode", "")
.append("status", 0)
.append("payStatus", 0)
.append("payCountdownMinute", 1440)
.append("overdueAt", overdueAt)
.append("createdAt", createdAtStr)
.append("updatedAt", createdAtStr)
.append("changeDate", now)
);
mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
Query.query(Criteria.where("orderTicketsId").is(orderTicketsId)).getQueryObject(),
orderUpdateDoc
);
// 更新订单票实体视图 KylinOrderTicketEntitiesVo
Document entitiesUpdateDoc = new Document("$set", new Document()
.append("isPayment", 0)
.append("updatedAt", createdAtStr)
.append("changeDate", now)
);
mongoTemplate.getCollection("KylinOrderTicketEntitiesVo").updateMany(
Query.query(Criteria.where("orderId").is(orderTicketsId)).getQueryObject(),
entitiesUpdateDoc
);
// 第六步:清理Redis缓存
log.info("第六步:清理Redis缓存");
redisDataSourceUtil.getRedisKylinUtil().del(KylinRedisConst.ORDER + orderTicketsId);
redisDataSourceUtil.getRedisKylinUtil().del(KylinRedisConst.ORDER_LIST + userId);
// 第七步:重新发送支付倒计时队列(24小时)
log.info("第七步:重新发送支付倒计时队列");
// 注意:这里需要调用QueueUtils的sendMsgByRedisGoblinStock方法
// queueUtils.sendMsgByRedisGoblinStock(orderTicketsId, now, "TICKET", 1440);
// 由于没有直接注入QueueUtils,这里先记录日志,实际使用时需要注入
log.info("需要重新发送支付倒计时队列 - orderTicketsId: {}, 倒计时: 1440分钟", orderTicketsId);
log.info("订单恢复完成 - orderCode: {}, 新的支付时间: 24小时", orderCode);
return ResponseDto.success(String.format("订单恢复成功!订单编号: %s, 支付时间已延长至24小时", orderCode));
} catch (Exception e) {
log.error("恢复订单失败 - orderCode: {}, error: ", orderCode, e);
return ResponseDto.failure("恢复订单失败: " + e.getMessage());
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment