diff --git a/src/main/java/com/example/demo/Util/AppleJWTGenerator.java b/src/main/java/com/example/demo/Util/AppleJWTGenerator.java new file mode 100644 index 0000000..4ff91ef --- /dev/null +++ b/src/main/java/com/example/demo/Util/AppleJWTGenerator.java @@ -0,0 +1,63 @@ +package com.example.demo.Util; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import java.util.Date; + +public class AppleJWTGenerator { + + // 你提供的信息 + private static final String KEY_ID = "3J2S9VXU3V"; + private static final String ISSUER_ID = "69a6de7e-1f9a-47e3-e053-5b8c7c11a4d1"; + private static final String P8_FILE_PATH = "E:/Work/newgold/gold-java/src/main/java/com/example/demo/Util/AuthKey_3J2S9VXU3V.p8"; + + public static void main(String[] args) { + try { + String token = generateAppleJWT(); + System.out.println("在 Apifox 里直接复制这一行:"); + System.out.println("Bearer " + token); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String generateAppleJWT() throws Exception { + // 读取 p8 文件 + String p8Content = Files.readString(Paths.get(P8_FILE_PATH)) + .replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + + // 解码私钥 + byte[] decoded = Base64.getDecoder().decode(p8Content); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded); + KeyFactory kf = KeyFactory.getInstance("EC"); + PrivateKey privateKey = kf.generatePrivate(spec); + + // ========== JWT Header ========== + String header = "{\"alg\":\"ES256\",\"kid\":\"" + KEY_ID + "\",\"typ\":\"JWT\"}"; + String headerBase64 = Base64.getUrlEncoder().withoutPadding().encodeToString(header.getBytes()); + + // ========== JWT Payload ========== + long now = new Date().getTime() / 1000; + String payload = String.format( + "{\"iss\":\"%s\",\"iat\":%d,\"exp\":%d,\"aud\":\"appstoreconnect-v1\"}", + ISSUER_ID, now, now + 15 * 60 // 15分钟有效期 + ); + String payloadBase64 = Base64.getUrlEncoder().withoutPadding().encodeToString(payload.getBytes()); + + // ========== ES256 签名 ========== + String data = headerBase64 + "." + payloadBase64; + java.security.Signature signature = java.security.Signature.getInstance("SHA256withECDSAinP1363Format"); + signature.initSign(privateKey); + signature.update(data.getBytes()); + byte[] signed = signature.sign(); + String signatureBase64 = Base64.getUrlEncoder().withoutPadding().encodeToString(signed); + + return data + "." + signatureBase64; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/Util/AppleTokenGenerator.java b/src/main/java/com/example/demo/Util/AppleTokenGenerator.java deleted file mode 100644 index a0fcff0..0000000 --- a/src/main/java/com/example/demo/Util/AppleTokenGenerator.java +++ /dev/null @@ -1,58 +0,0 @@ -//package com.example.demo.Util; -// -//import io.jsonwebtoken.Jwts; -//import io.jsonwebtoken.SignatureAlgorithm; -//import io.jsonwebtoken.io.Decoders; -//import java.nio.file.Files; -//import java.nio.file.Paths; -//import java.security.KeyFactory; -//import java.security.PrivateKey; -//import java.security.spec.PKCS8EncodedKeySpec; -//import java.util.Date; -// -//public class AppleTokenGenerator { -// -// // 你提供的真实信息(已全部填好) -// private static final String KEY_ID = "3J2S9VXU3V"; -// private static final String ISSUER_ID = "69a6de7e-1f9a-47e3-e053-5b8c7c11a4d1"; -// private static final String P8_FILE_PATH = "E:/Work/newgold/gold-java/src/main/java/com/example/demo/Util/AuthKey_3J2S9VXU3V.p8"; -// -// public static String generateToken() { -// try { -// // 读取 P8 私钥内容 -// String p8Content = Files.readString(Paths.get(P8_FILE_PATH)) -// .replace("-----BEGIN PRIVATE KEY-----", "") -// .replace("-----END PRIVATE KEY-----", "") -// .replaceAll("\\s+", ""); -// -// // 解码私钥 -// byte[] keyBytes = Decoders.BASE64.decode(p8Content); -// PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); -// KeyFactory keyFactory = KeyFactory.getInstance("EC"); -// PrivateKey privateKey = keyFactory.generatePrivate(spec); -// -// // 生成苹果官方标准 JWT(补全typ字段,完全符合文档要求) -// return Jwts.builder() -// .setHeaderParam("alg", "ES256") -// .setHeaderParam("kid", KEY_ID) -// .setHeaderParam("typ", "JWT") // 🔴 苹果官方强制要求,之前漏了! -// .setIssuer(ISSUER_ID) -// .setAudience("appstoreconnect-v1") -// .setIssuedAt(new Date()) -// .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 15)) // 15分钟有效期(≤20分钟) -// .signWith(privateKey, SignatureAlgorithm.ES256) -// .compact(); -// -// } catch (Exception e) { -// e.printStackTrace(); -// return null; -// } -// } -// -//// // 运行直接输出可用 Token -//// public static void main(String[] args) { -//// String token = generateToken(); -//// System.out.println("复制下面这一行直接用:"); -//// System.out.println("Bearer " + token); -//// } -//} \ No newline at end of file diff --git a/src/main/java/com/example/demo/controller/cash/CashCollectionController.java b/src/main/java/com/example/demo/controller/cash/CashCollectionController.java index 65aad69..3d884d6 100644 --- a/src/main/java/com/example/demo/controller/cash/CashCollectionController.java +++ b/src/main/java/com/example/demo/controller/cash/CashCollectionController.java @@ -339,18 +339,19 @@ public class CashCollectionController { UserWalletRecord queryCondition = page.getUserWalletRecord(); if (queryCondition == null || - (queryCondition.getJwcode() == null && queryCondition.getWalletId() == null)) { - return Result.error("精网号和钱包 ID 不能同时为空"); + (queryCondition.getJwcode() == null && queryCondition.getWalletId() == null && + (queryCondition.getMarket() == null || queryCondition.getMarket().isEmpty()))) { + return Result.error("精网号、钱包 ID 和地区不能同时为空"); } Result result = Result.success(cashCollectionService.selectWalletRecordsByJwcodeAndWalletId( page.getPageNum(), page.getPageSize(), queryCondition.getJwcode(), - queryCondition.getWalletId() + queryCondition.getWalletId(), + queryCondition.getMarket() )); - // 对返回结果进行多语言转换 if (result.getCode() == 200 && result.getData() instanceof PageInfo) { PageInfo pageInfo = (PageInfo) result.getData(); translateWalletRecordVOs(pageInfo, lang); diff --git a/src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java b/src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java index 979cf2f..0577259 100644 --- a/src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java +++ b/src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java @@ -24,6 +24,6 @@ public class PerformanceAdjustmentDTO { private int[][] matrix = new int[6][6]; private Double weight; // 权重 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") - private LocalDateTime Time; // 时间 + private LocalDateTime time; // 时间 } diff --git a/src/main/java/com/example/demo/domain/entity/UserWalletRecord.java b/src/main/java/com/example/demo/domain/entity/UserWalletRecord.java index 60e4365..1728aa2 100644 --- a/src/main/java/com/example/demo/domain/entity/UserWalletRecord.java +++ b/src/main/java/com/example/demo/domain/entity/UserWalletRecord.java @@ -13,6 +13,7 @@ import java.util.Date; public class UserWalletRecord { private Integer id; // 主键 ID private Integer jwcode; // 精网号 + private String market; // 地区 private Integer walletId; // 钱包 ID private Integer type; // 交易类型(0=充值,1=消耗,2=退款,3=软件购买) private String transactionCurrency; // 交易币种 diff --git a/src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java b/src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java index 0f5ff2f..907faac 100644 --- a/src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java +++ b/src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java @@ -113,7 +113,8 @@ public interface CashCollectionMapper { // 根据精网号和钱包 ID 查询用户钱包明细列表 List selectWalletRecordsByJwcodeAndWalletId( @Param("jwcode") Integer jwcode, - @Param("walletId") Integer walletId); + @Param("walletId") Integer walletId, + @Param("market") String market); // 查询符合条件的精网号列表(用于分页,每个精网号算一条记录) List selectDistinctJwcodes(@Param("jwcode") Integer jwcode, diff --git a/src/main/java/com/example/demo/mapper/coin/RateMapper.java b/src/main/java/com/example/demo/mapper/coin/RateMapper.java index 9000fe5..f836886 100644 --- a/src/main/java/com/example/demo/mapper/coin/RateMapper.java +++ b/src/main/java/com/example/demo/mapper/coin/RateMapper.java @@ -17,4 +17,6 @@ public interface RateMapper { void add(Rate rate); //获取货币名称列表 List listRateName(); + + Integer getIdByName(String rateName); } diff --git a/src/main/java/com/example/demo/service/cash/CashCollectionService.java b/src/main/java/com/example/demo/service/cash/CashCollectionService.java index 2cdcabf..f57218c 100644 --- a/src/main/java/com/example/demo/service/cash/CashCollectionService.java +++ b/src/main/java/com/example/demo/service/cash/CashCollectionService.java @@ -51,8 +51,7 @@ public interface CashCollectionService { // 根据精网号和钱包 ID 查询用户钱包明细列表(分页) PageInfo selectWalletRecordsByJwcodeAndWalletId( - Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId); - + Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId, String market); // 根据精网号和地区查询用户的所有钱包 ID 和金币数量(包含用户名和地区)(分页) PageInfo selectUserWallets(Integer jwcode, String market, Integer pageNum, Integer pageSize, String sortField, String sortOrder, Integer sortWalletId); // 添加流水--其他收入 diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java index 8b305de..eb97fcc 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java @@ -10,6 +10,7 @@ import com.example.demo.mapper.cash.CashAuditMapper; import com.example.demo.mapper.cash.CashCollectionMapper; import com.example.demo.mapper.coin.AuditMapper; import com.example.demo.mapper.coin.MarketMapper; +import com.example.demo.mapper.coin.RateMapper; import com.example.demo.mapper.coin.RechargeMapper; import com.example.demo.service.cash.CashAuditService; import lombok.extern.slf4j.Slf4j; @@ -49,6 +50,8 @@ public class CashAuditServiceImpl implements CashAuditService { private RabbitTemplate rabbitTemplate; @Autowired private MarketMapper marketMapper; + @Autowired + private RateMapper rateMapper; @Transactional @@ -92,7 +95,12 @@ public class CashAuditServiceImpl implements CashAuditService { rechargeOrder.setFreeDecember(order.getFreeGold()); } rechargeOrder.setSumGold(order.getPermanentGold() + order.getFreeGold()); - rechargeOrder.setRateId(Integer.valueOf(order.getPaymentCurrency())); + Integer rateId = rateMapper.getIdByName(order.getPaymentCurrency()); + if (rateId == null) { + log.warn("未找到币种 '{}' 对应的ID,使用默认值0", order.getPaymentCurrency()); + rateId = 0; + } + rechargeOrder.setRateId(rateId); rechargeOrder.setMoney(order.getPaymentAmount().intValue()); rechargeOrder.setRemark(order.getRemark()); rechargeOrder.setVoucher(order.getVoucher()); diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java index 2cba3a6..ee22a06 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java @@ -620,9 +620,9 @@ public class CashCollectionServiceImpl implements CashCollectionService { // 根据精网号和钱包 ID 查询用户钱包明细列表(分页) @Override public PageInfo selectWalletRecordsByJwcodeAndWalletId( - Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId) { + Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId, String market) { PageHelper.startPage(pageNum, pageSize); - List records = cashCollectionMapper.selectWalletRecordsByJwcodeAndWalletId(jwcode, walletId); + List records = cashCollectionMapper.selectWalletRecordsByJwcodeAndWalletId(jwcode, walletId, market); return new PageInfo<>(records); } diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java index c91cc44..ab8e101 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java @@ -844,7 +844,7 @@ public class CashRefundServiceImpl implements RefundService { { wallet = 3; } - if (payType.equals("iPay88")) + if (payType.equals("iPay88")||payType.equals("Ipay88")) { wallet = 4; } @@ -867,6 +867,7 @@ public class CashRefundServiceImpl implements RefundService { walletMapper.insert(new UserRegionWallet(null, cashRecordRefund.getJwcode(), wallet, BigDecimal.ZERO, new Date(), new Date())); log.warn("用户钱包不存在,已初始化钱包"); } + userRegionWallet = walletMapper.selectWallet(cashRecordRefund.getJwcode(), wallet); if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPartRefundGold())) < 0) { throw new BusinessException("用户钱包金币不足"); } diff --git a/src/main/resources/cashMapper/CashCollectionMapper.xml b/src/main/resources/cashMapper/CashCollectionMapper.xml index eb9596e..baa319f 100644 --- a/src/main/resources/cashMapper/CashCollectionMapper.xml +++ b/src/main/resources/cashMapper/CashCollectionMapper.xml @@ -522,6 +522,9 @@ AND uwr.wallet_id = #{walletId} + + AND u.market = #{market} + ORDER BY uwr.create_time DESC diff --git a/src/main/resources/mapper/RateMapper.xml b/src/main/resources/mapper/RateMapper.xml index b6870ed..3e5e8da 100644 --- a/src/main/resources/mapper/RateMapper.xml +++ b/src/main/resources/mapper/RateMapper.xml @@ -16,6 +16,9 @@ FROM rate + UPDATE