From 69138ddcf4936098cb3b67688412badfc8f503a0 Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期二, 18 八月 2026 17:13:53 +0800
Subject: [PATCH] 又又又更新

---
 talent-card-server/src/main/java/com/talentcard/server/business/order/OrderService.java |   71 ++++++++++++++++++++++-------------
 1 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/order/OrderService.java b/talent-card-server/src/main/java/com/talentcard/server/business/order/OrderService.java
index 379711e..285a92f 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/order/OrderService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/order/OrderService.java
@@ -20,6 +20,9 @@
 @Service
 public class OrderService {
 
+	private static final String ORDER_CARD_LEVEL_SQL =
+			"coalesce(nullif(o.card_level_snapshot, ''), tc.card_level, tu.talent_level)";
+
 	private final JdbcTemplate jdbcTemplate;
 	private final HuifuRefundService refundService;
 
@@ -35,14 +38,16 @@
 		long subsidyAmount = MoneyUtils.yuanToCent(request.subsidyAmount());
 		long payAmount = MoneyUtils.yuanToCent(request.payAmount());
 		LocalDateTime expiresAt = payAmount == 0 ? null : LocalDateTime.now().plusMinutes(15);
+		String cardLevel = jdbcTemplate.query("select card_level from talent_card where id = ? and deleted = 0", rs -> rs.next() ? rs.getString(1) : null, request.cardId());
 		jdbcTemplate.update("""
-				insert into benefit_order(order_no, talent_id, card_id, benefit_id, merchant_id, store_id,
+				insert into benefit_order(order_no, talent_id, card_id, card_level_snapshot, benefit_id, merchant_id, store_id,
 				                          order_type, order_amount, subsidy_amount, base_pay_amount, pay_amount, expires_at, order_status, verify_status)
-				values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
+				values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
 				""",
 				orderNo,
 				request.talentId(),
 				request.cardId(),
+				cardLevel,
 				request.benefitId(),
 				request.merchantId(),
 				request.storeId(),
@@ -110,7 +115,7 @@
 	public Map<String, Object> detail(String orderNo) {
 		List<Map<String, Object>> rows = query("""
 				select o.id, o.order_no, o.talent_id, tu.name as talent_name, tu.mobile as talent_mobile,
-				       o.card_id, tc.card_no, coalesce(tc.card_level, tu.talent_level) as talent_level, o.benefit_id, b.benefit_name,
+				       o.card_id, tc.card_no, %s as talent_level, o.benefit_id, b.benefit_name,
 				       o.product_id, o.product_name_snapshot, o.product_cover_url_snapshot,
 				       p.product_name, p.cover_url as product_cover_url,
 				       o.merchant_id, m.merchant_name, m.merchant_type, m.contact_mobile,
@@ -126,7 +131,7 @@
 				left join merchant_coupon mc on mc.id = o.coupon_id and mc.deleted = 0
 				left join merchant m on m.id = o.merchant_id
 				where o.deleted = 0 and o.order_no = ?
-				""", orderNo);
+				""".formatted(ORDER_CARD_LEVEL_SQL), orderNo);
 		if (rows.isEmpty()) {
 			throw new BusinessException(ErrorCode.NOT_FOUND, "订单不存在");
 		}
@@ -137,7 +142,21 @@
 				where order_id = ?
 				order by id desc limit 1
 				""", detail.get("id"));
-		detail.put("verifyTime", verificationRows.isEmpty() ? null : verificationRows.get(0).get("verifyTime"));
+		Object verifyTime = verificationRows.isEmpty() ? null : verificationRows.get(0).get("verifyTime");
+		// 到店消费在支付成功后即自动核销,历史数据未必有人工核销记录;此时以成功支付时间作为核销时间。
+		if (verifyTime == null
+				&& "STORE_CONSUME".equalsIgnoreCase(String.valueOf(detail.get("orderType")))
+				&& detail.get("verifyStatus") instanceof Number verifyStatus
+				&& verifyStatus.intValue() == 1) {
+			List<Map<String, Object>> paidTransactions = query("""
+					select paid_at as verify_time
+					from payment_transaction
+					where order_no = ? and status = 'SUCCEEDED' and paid_at is not null
+					order by id desc limit 1
+					""", orderNo);
+			verifyTime = paidTransactions.isEmpty() ? null : paidTransactions.get(0).get("verifyTime");
+		}
+		detail.put("verifyTime", verifyTime);
 		Object itemId = detail.get("productId") == null ? detail.get("benefitId") : detail.get("productId");
 		Object itemName = firstNonNull(detail.get("productNameSnapshot"), detail.get("productName"), detail.get("benefitName"));
 		Object itemCover = firstNonNull(detail.get("productCoverUrlSnapshot"), detail.get("productCoverUrl"), detail.get("merchantCoverUrl"));
@@ -197,11 +216,7 @@
 			where.append(" and m.merchant_name like ?");
 			args.add("%" + merchantName.trim() + "%");
 		}
-		if (cardLevel != null && !cardLevel.isBlank()) {
-			where.append(" and (tc.card_level = ? or tu.talent_level = ?)");
-			args.add(cardLevel);
-			args.add(cardLevel);
-		}
+		appendCardLevelFilter(where, args, cardLevel);
 		if (hasSubsidy != null) {
 			where.append(hasSubsidy == 1 ? " and o.subsidy_amount > 0" : " and o.subsidy_amount = 0");
 		}
@@ -225,16 +240,18 @@
 				select r.id, r.refund_no, r.order_no, r.order_type, r.paid_amount, r.refund_amount,
 				       r.refundable_amount, r.refund_status, r.reason, r.operator_name, r.refund_time,
 				       tu.name as talent_name, tu.mobile as talent_mobile,
-				       coalesce(tc.card_level, tu.talent_level) as talent_level, tc.card_no,
-				       m.merchant_name, m.merchant_type, coalesce(b.benefit_name, o.product_name_snapshot) as benefit_name,
+				       %s as talent_level, tc.card_no,
+				       m.merchant_name, m.merchant_type,
+				       coalesce(nullif(o.product_name_snapshot, ''), nullif(p.product_name, ''), b.benefit_name) as benefit_name,
 				       o.order_amount, o.subsidy_amount, o.pay_amount, o.created_at as order_time
 				from order_refund r
 				left join benefit_order o on o.id = r.order_id
 				left join talent_user tu on tu.id = r.talent_id
 				left join talent_card tc on tc.id = r.card_id
 				left join benefit b on b.id = r.benefit_id
+				left join merchant_product p on p.id = o.product_id and p.deleted = 0
 				left join merchant m on m.id = r.merchant_id
-				""" + where + " order by r.id desc limit ? offset ?", pageArgs.toArray());
+				""".formatted(ORDER_CARD_LEVEL_SQL) + where + " order by r.id desc limit ? offset ?", pageArgs.toArray());
 		Long total = jdbcTemplate.queryForObject("""
 				select count(*)
 				from order_refund r
@@ -281,11 +298,7 @@
 			where.append(" and m.merchant_name like ?");
 			args.add("%" + merchantName.trim() + "%");
 		}
-		if (cardLevel != null && !cardLevel.isBlank()) {
-			where.append(" and (tc.card_level = ? or tu.talent_level = ?)");
-			args.add(cardLevel);
-			args.add(cardLevel);
-		}
+		appendCardLevelFilter(where, args, cardLevel);
 		if ("未核销".equals(status)) {
 			return new PageResult<>(List.of(), safePage, safeSize, 0);
 		}
@@ -305,7 +318,7 @@
 				select r.id, r.verify_no, r.verify_type, r.verify_amount, r.subsidy_amount, r.verify_time,
 				       r.remark, o.order_no, o.order_type,
 				       tu.name as talent_name, tu.mobile as talent_mobile,
-				       coalesce(tc.card_level, tu.talent_level) as talent_level, tc.card_no,
+				       %s as talent_level, tc.card_no,
 				       m.merchant_name, m.merchant_type, b.benefit_name,
 				       '已核销' as status
 				from verify_record r
@@ -314,7 +327,7 @@
 				left join talent_card tc on tc.id = r.card_id
 				left join benefit b on b.id = r.benefit_id
 				left join merchant m on m.id = r.merchant_id
-				""" + where + " order by r.id desc limit ? offset ?", pageArgs.toArray());
+				""".formatted(ORDER_CARD_LEVEL_SQL) + where + " order by r.id desc limit ? offset ?", pageArgs.toArray());
 		Long total = jdbcTemplate.queryForObject("""
 				select count(*)
 				from verify_record r
@@ -375,11 +388,7 @@
 			where.append(" and m.merchant_name like ?");
 			args.add("%" + merchantName.trim() + "%");
 		}
-		if (cardLevel != null && !cardLevel.isBlank()) {
-			where.append(" and (tc.card_level = ? or tu.talent_level = ?)");
-			args.add(cardLevel);
-			args.add(cardLevel);
-		}
+		appendCardLevelFilter(where, args, cardLevel);
 		if (hasSubsidy != null) {
 			where.append(hasSubsidy == 1 ? " and o.subsidy_amount > 0" : " and o.subsidy_amount = 0");
 		}
@@ -404,7 +413,7 @@
 		pageArgs.add((safePage - 1) * safeSize);
 		List<Map<String, Object>> records = query("""
 				select o.id, o.order_no, o.talent_id, tu.name as talent_name, tu.mobile as talent_mobile,
-				       coalesce(tc.card_level, tu.talent_level) as talent_level,
+				       %s as talent_level,
 				       o.card_id, tc.card_no, tc.card_type,
 				       o.merchant_id, m.merchant_name, m.merchant_type,
 				       o.benefit_id, b.benefit_name, o.order_type,
@@ -415,7 +424,7 @@
 				left join talent_card tc on tc.id = o.card_id
 				left join benefit b on b.id = o.benefit_id
 				left join merchant m on m.id = o.merchant_id
-				""" + where + " order by o.id desc limit ? offset ?", pageArgs.toArray());
+				""".formatted(ORDER_CARD_LEVEL_SQL) + where + " order by o.id desc limit ? offset ?", pageArgs.toArray());
 		Long total = jdbcTemplate.queryForObject("""
 				select count(*)
 				from benefit_order o
@@ -439,6 +448,14 @@
 		return rows.get(0);
 	}
 
+	private void appendCardLevelFilter(StringBuilder where, List<Object> args, String cardLevel) {
+		if (cardLevel == null || cardLevel.isBlank()) {
+			return;
+		}
+		where.append(" and ").append(ORDER_CARD_LEVEL_SQL).append(" = ?");
+		args.add(cardLevel.trim());
+	}
+
 	private void appendOrderTypeFilter(StringBuilder where, List<Object> args, String alias, String orderType) {
 		if (orderType == null || orderType.isBlank()) {
 			return;

--
Gitblit v1.7.1