|
|
@ -41,8 +41,7 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
Set<Integer> validTwoTypes = new HashSet<>(Arrays.asList(52,61)); |
|
|
Set<Integer> validTwoTypes = new HashSet<>(Arrays.asList(52,61)); |
|
|
Set<Integer> validThreeTypes = new HashSet<>(Arrays.asList(10, 16, 30, 31, 32, 33, 34, 39, 44)); |
|
|
Set<Integer> validThreeTypes = new HashSet<>(Arrays.asList(10, 16, 30, 31, 32, 33, 34, 39, 44)); |
|
|
Set<Integer> validFourTypes = new HashSet<>(Arrays.asList(55, 56, 57, 58, 59, 63, 64, 65)); |
|
|
Set<Integer> validFourTypes = new HashSet<>(Arrays.asList(55, 56, 57, 58, 59, 63, 64, 65)); |
|
|
LocalDateTime now = LocalDateTime.now(); |
|
|
|
|
|
Month currentMonth = now.getMonth(); |
|
|
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private AdminService adminService; |
|
|
private AdminService adminService; |
|
|
@Autowired |
|
|
@Autowired |
|
|
@ -340,6 +339,9 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
return existing; |
|
|
return existing; |
|
|
} |
|
|
} |
|
|
private void setStatementParams(PreparedStatement stmt, RecordData data) throws SQLException { |
|
|
private void setStatementParams(PreparedStatement stmt, RecordData data) throws SQLException { |
|
|
|
|
|
|
|
|
|
|
|
Month currentMonth = LocalDateTime.now().getMonth(); |
|
|
|
|
|
|
|
|
String name = data.cz_user; |
|
|
String name = data.cz_user; |
|
|
|
|
|
|
|
|
// 设置 admin_id |
|
|
// 设置 admin_id |
|
|
@ -440,6 +442,8 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
private void updateUserBalance(Connection conn, RecordData data) throws Exception { |
|
|
private void updateUserBalance(Connection conn, RecordData data) throws Exception { |
|
|
logger.info("处理用户余额更新,jwcode={}", data.jwcode); |
|
|
logger.info("处理用户余额更新,jwcode={}", data.jwcode); |
|
|
|
|
|
|
|
|
|
|
|
Month currentMonth = LocalDateTime.now().getMonth(); |
|
|
|
|
|
|
|
|
User user = userService.selectAllUser(String.valueOf(data.jwcode)); |
|
|
User user = userService.selectAllUser(String.valueOf(data.jwcode)); |
|
|
BigDecimal freeBD = BigDecimal.valueOf(data.free); |
|
|
BigDecimal freeBD = BigDecimal.valueOf(data.free); |
|
|
BigDecimal buyJbBD = BigDecimal.valueOf(data.buy_jb); |
|
|
BigDecimal buyJbBD = BigDecimal.valueOf(data.buy_jb); |
|
|
@ -568,53 +572,102 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
* @param mysqlConn 当前事务连接(⚠️必须使用此连接) |
|
|
* @param mysqlConn 当前事务连接(⚠️必须使用此连接) |
|
|
* @param records 本批次有效记录 |
|
|
* @param records 本批次有效记录 |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
/** |
|
|
|
|
|
* 查 g_order 获取 pay_style,路由更新 user_region_wallet 余额 |
|
|
|
|
|
* 逻辑:仅当 linkId 是 G+ 自增 id 格式 且 g_order 查到了,才更新钱包;否则直接跳过 |
|
|
|
|
|
* @param mysqlConn 当前事务连接(⚠️必须使用此连接) |
|
|
|
|
|
* @param records 本批次有效记录 |
|
|
|
|
|
*/ |
|
|
private void updateUserRegionWallet(Connection mysqlConn, List<RecordData> records) { |
|
|
private void updateUserRegionWallet(Connection mysqlConn, List<RecordData> records) { |
|
|
if (records == null || records.isEmpty()) return; |
|
|
|
|
|
|
|
|
if (records == null || records.isEmpty()) { |
|
|
|
|
|
logger.debug("updateUserRegionWallet: records 为空,跳过钱包更新"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 1. 收集符合 G+ 数字 格式的 order_id(只处理 permanent_gold > 0 的记录) |
|
|
|
|
|
// ⚠️ 注意:这里用 r.linkId 而不是 r.uid |
|
|
|
|
|
Map<Long, RecordData> orderIdRecordMap = new HashMap<>(); |
|
|
|
|
|
for (RecordData r : records) { |
|
|
|
|
|
if (r.permanent_gold == null || r.permanent_gold <= 0) continue; |
|
|
|
|
|
// ⚠️ 关键修改:用 linkId 判断 G+ 格式 |
|
|
|
|
|
if (r.linkId != null && r.linkId.matches("^G\\d+$")) { |
|
|
|
|
|
try { |
|
|
|
|
|
long orderId = Long.parseLong(r.linkId.substring(1)); |
|
|
|
|
|
orderIdRecordMap.put(orderId, r); |
|
|
|
|
|
logger.debug("提取 order_id={} from linkId={}, jwcode={}", orderId, r.linkId, r.jwcode); |
|
|
|
|
|
} catch (NumberFormatException e) { |
|
|
|
|
|
logger.debug("linkId={} 格式解析失败,跳过钱包更新", r.linkId); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 非 G+ 格式的记录,直接跳过钱包更新(不查 g_order) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 1. 收集 jwcode 去重 |
|
|
|
|
|
List<Integer> jwcodes = records.stream() |
|
|
|
|
|
.map(r -> r.jwcode).filter(Objects::nonNull).distinct() |
|
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
if (jwcodes.isEmpty()) return; |
|
|
|
|
|
|
|
|
if (orderIdRecordMap.isEmpty()) { |
|
|
|
|
|
logger.info("无符合 G+ 格式的记录,跳过钱包更新"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 2. 批量查 g_order 获取 pay_style(state=1 支付完成) |
|
|
|
|
|
String inSql = String.join(",", Collections.nCopies(jwcodes.size(), "?")); |
|
|
|
|
|
String querySql = "SELECT jwcode, pay_style FROM g_order WHERE jwcode IN (" + inSql + ") AND state = 1"; |
|
|
|
|
|
|
|
|
// 2. 批量查 g_order 获取 pay_style(按 id 查询 + state=1) |
|
|
|
|
|
List<Long> orderIds = new ArrayList<>(orderIdRecordMap.keySet()); |
|
|
|
|
|
String inSql = String.join(",", Collections.nCopies(orderIds.size(), "?")); |
|
|
|
|
|
String querySql = "SELECT id, jwcode, pay_style FROM g_order WHERE id IN (" + inSql + ") AND state = 1"; |
|
|
|
|
|
|
|
|
Map<Integer, Integer> jwcodePayStyleMap = new HashMap<>(); |
|
|
Map<Integer, Integer> jwcodePayStyleMap = new HashMap<>(); |
|
|
try (PreparedStatement stmt = mysqlConn.prepareStatement(querySql)) { |
|
|
try (PreparedStatement stmt = mysqlConn.prepareStatement(querySql)) { |
|
|
for (int i = 0; i < jwcodes.size(); i++) stmt.setInt(i + 1, jwcodes.get(i)); |
|
|
|
|
|
|
|
|
for (int i = 0; i < orderIds.size(); i++) { |
|
|
|
|
|
stmt.setLong(i + 1, orderIds.get(i)); // ⚠️ g_order.id 可能是 bigint,用 setLong |
|
|
|
|
|
} |
|
|
try (ResultSet rs = stmt.executeQuery()) { |
|
|
try (ResultSet rs = stmt.executeQuery()) { |
|
|
while (rs.next()) jwcodePayStyleMap.put(rs.getInt("jwcode"), rs.getInt("pay_style")); |
|
|
|
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
int jwcode = rs.getInt("jwcode"); |
|
|
|
|
|
int payStyle = rs.getInt("pay_style"); |
|
|
|
|
|
jwcodePayStyleMap.put(jwcode, payStyle); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} catch (SQLException e) { |
|
|
} catch (SQLException e) { |
|
|
throw new RuntimeException("查询 g_order 失败", e); |
|
|
|
|
|
|
|
|
// ⚠️ 关键:查库异常只记录日志,不抛异常,避免影响主流程(金币更新照常) |
|
|
|
|
|
logger.error("查询 g_order 失败,跳过钱包更新", e); |
|
|
|
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 3. 按 pay_style 路由到 wallet_id,累加永久金币 |
|
|
|
|
|
Map<String, Integer> userWalletGoldMap = new HashMap<>(); // key: "jwcode_walletId" -> 累加金额 |
|
|
|
|
|
for (RecordData data : records) { |
|
|
|
|
|
if (!jwcodePayStyleMap.containsKey(data.jwcode)) continue; |
|
|
|
|
|
if (data.permanent_gold == null || data.permanent_gold <= 0) continue; |
|
|
|
|
|
|
|
|
if (jwcodePayStyleMap.isEmpty()) { |
|
|
|
|
|
logger.info("g_order 未匹配到支付记录,跳过钱包更新(用户金币仍会更新)"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3. 按 pay_style 路由到 wallet_id,累加 permanent_gold |
|
|
|
|
|
Map<String, Integer> userWalletGoldMap = new HashMap<>(); |
|
|
|
|
|
for (RecordData data : orderIdRecordMap.values()) { |
|
|
Integer payStyle = jwcodePayStyleMap.get(data.jwcode); |
|
|
Integer payStyle = jwcodePayStyleMap.get(data.jwcode); |
|
|
|
|
|
if (payStyle == null) { |
|
|
|
|
|
logger.debug("jwcode={} 未在 g_order 中匹配到 pay_style,跳过钱包更新", data.jwcode); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Integer walletId = mapPayStyleToWalletId(payStyle); |
|
|
Integer walletId = mapPayStyleToWalletId(payStyle); |
|
|
if (walletId == null) continue; |
|
|
|
|
|
|
|
|
if (walletId == null) { |
|
|
|
|
|
logger.debug("payStyle={} 未映射到 wallet_id,跳过钱包更新", payStyle); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
String key = data.jwcode + "_" + walletId; |
|
|
String key = data.jwcode + "_" + walletId; |
|
|
userWalletGoldMap.merge(key, data.permanent_gold, Integer::sum); |
|
|
userWalletGoldMap.merge(key, data.permanent_gold, Integer::sum); |
|
|
} |
|
|
} |
|
|
if (userWalletGoldMap.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
|
|
// 4. UPSERT 批量更新 user_region_wallet(不存在则插入,存在则累加) |
|
|
|
|
|
|
|
|
if (userWalletGoldMap.isEmpty()) { |
|
|
|
|
|
logger.info("无有效记录需要更新地区钱包"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4. UPSERT 批量更新 user_region_wallet |
|
|
String upsertSql = """ |
|
|
String upsertSql = """ |
|
|
INSERT INTO user_region_wallet |
|
|
|
|
|
(jwcode, wallet_id, current_permanent_gold, create_time, update_time) |
|
|
|
|
|
VALUES (?, ?, ?, NOW(), NOW()) |
|
|
|
|
|
ON DUPLICATE KEY UPDATE |
|
|
|
|
|
current_permanent_gold = current_permanent_gold + VALUES(current_permanent_gold), |
|
|
|
|
|
update_time = NOW() |
|
|
|
|
|
"""; |
|
|
|
|
|
|
|
|
INSERT INTO user_region_wallet |
|
|
|
|
|
(jwcode, wallet_id, current_permanent_gold, create_time, update_time) |
|
|
|
|
|
VALUES (?, ?, ?, NOW(), NOW()) |
|
|
|
|
|
ON DUPLICATE KEY UPDATE |
|
|
|
|
|
current_permanent_gold = current_permanent_gold + VALUES(current_permanent_gold), |
|
|
|
|
|
update_time = NOW() |
|
|
|
|
|
"""; |
|
|
|
|
|
|
|
|
try (PreparedStatement stmt = mysqlConn.prepareStatement(upsertSql)) { |
|
|
try (PreparedStatement stmt = mysqlConn.prepareStatement(upsertSql)) { |
|
|
for (Map.Entry<String, Integer> entry : userWalletGoldMap.entrySet()) { |
|
|
for (Map.Entry<String, Integer> entry : userWalletGoldMap.entrySet()) { |
|
|
@ -628,9 +681,10 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
stmt.addBatch(); |
|
|
stmt.addBatch(); |
|
|
} |
|
|
} |
|
|
int[] results = stmt.executeBatch(); |
|
|
int[] results = stmt.executeBatch(); |
|
|
logger.info("✅ 地区钱包余额更新 {} 条", results.length); |
|
|
|
|
|
|
|
|
logger.info("✅ 地区钱包余额更新成功 {} 条", results.length); |
|
|
} catch (SQLException e) { |
|
|
} catch (SQLException e) { |
|
|
throw new RuntimeException("更新地区钱包失败", e); |
|
|
|
|
|
|
|
|
// ⚠️ 关键:更新异常只记录日志,不抛异常,避免回滚主事务 |
|
|
|
|
|
logger.error("更新 user_region_wallet 失败,跳过钱包更新", e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -645,7 +699,7 @@ public class MysqlServiceImpl implements MysqlService { |
|
|
case 7 -> 4; // 其他 → 西南钱包 |
|
|
case 7 -> 4; // 其他 → 西南钱包 |
|
|
case 10 -> 8; |
|
|
case 10 -> 8; |
|
|
case 15 -> 3; |
|
|
case 15 -> 3; |
|
|
default -> null; |
|
|
|
|
|
|
|
|
default -> 1; |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |