Browse Source

Merge remote-tracking branch 'refs/remotes/origin/milestone-20260401-现金管理四期' into lijianlin/feature-20260401-现金管理四期

lijianlin/feature-20260401-现金管理四期
lijianlin 1 day ago
parent
commit
2a5469eefb
  1. 63
      src/main/java/com/example/demo/Util/AppleJWTGenerator.java
  2. 58
      src/main/java/com/example/demo/Util/AppleTokenGenerator.java
  3. 9
      src/main/java/com/example/demo/controller/cash/CashCollectionController.java
  4. 2
      src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java
  5. 1
      src/main/java/com/example/demo/domain/entity/UserWalletRecord.java
  6. 3
      src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java
  7. 2
      src/main/java/com/example/demo/mapper/coin/RateMapper.java
  8. 3
      src/main/java/com/example/demo/service/cash/CashCollectionService.java
  9. 10
      src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java
  10. 4
      src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java
  11. 3
      src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java
  12. 3
      src/main/resources/cashMapper/CashCollectionMapper.xml
  13. 3
      src/main/resources/mapper/RateMapper.xml

63
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;
}
}

58
src/main/java/com/example/demo/Util/AppleTokenGenerator.java

@ -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);
//// }
//}

9
src/main/java/com/example/demo/controller/cash/CashCollectionController.java

@ -339,18 +339,19 @@ public class CashCollectionController {
UserWalletRecord queryCondition = page.getUserWalletRecord(); UserWalletRecord queryCondition = page.getUserWalletRecord();
if (queryCondition == null || 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( Result result = Result.success(cashCollectionService.selectWalletRecordsByJwcodeAndWalletId(
page.getPageNum(), page.getPageNum(),
page.getPageSize(), page.getPageSize(),
queryCondition.getJwcode(), queryCondition.getJwcode(),
queryCondition.getWalletId()
queryCondition.getWalletId(),
queryCondition.getMarket()
)); ));
// 对返回结果进行多语言转换
if (result.getCode() == 200 && result.getData() instanceof PageInfo) { if (result.getCode() == 200 && result.getData() instanceof PageInfo) {
PageInfo<UserWalletRecordVO> pageInfo = (PageInfo<UserWalletRecordVO>) result.getData(); PageInfo<UserWalletRecordVO> pageInfo = (PageInfo<UserWalletRecordVO>) result.getData();
translateWalletRecordVOs(pageInfo, lang); translateWalletRecordVOs(pageInfo, lang);

2
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 int[][] matrix = new int[6][6];
private Double weight; // 权重 private Double weight; // 权重
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private LocalDateTime Time; // 时间
private LocalDateTime time; // 时间
} }

1
src/main/java/com/example/demo/domain/entity/UserWalletRecord.java

@ -13,6 +13,7 @@ import java.util.Date;
public class UserWalletRecord { public class UserWalletRecord {
private Integer id; // 主键 ID private Integer id; // 主键 ID
private Integer jwcode; // 精网号 private Integer jwcode; // 精网号
private String market; // 地区
private Integer walletId; // 钱包 ID private Integer walletId; // 钱包 ID
private Integer type; // 交易类型0=充值1=消耗2=退款3=软件购买 private Integer type; // 交易类型0=充值1=消耗2=退款3=软件购买
private String transactionCurrency; // 交易币种 private String transactionCurrency; // 交易币种

3
src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java

@ -113,7 +113,8 @@ public interface CashCollectionMapper {
// 根据精网号和钱包 ID 查询用户钱包明细列表 // 根据精网号和钱包 ID 查询用户钱包明细列表
List<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId( List<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId(
@Param("jwcode") Integer jwcode, @Param("jwcode") Integer jwcode,
@Param("walletId") Integer walletId);
@Param("walletId") Integer walletId,
@Param("market") String market);
// 查询符合条件的精网号列表用于分页每个精网号算一条记录 // 查询符合条件的精网号列表用于分页每个精网号算一条记录
List<Integer> selectDistinctJwcodes(@Param("jwcode") Integer jwcode, List<Integer> selectDistinctJwcodes(@Param("jwcode") Integer jwcode,

2
src/main/java/com/example/demo/mapper/coin/RateMapper.java

@ -17,4 +17,6 @@ public interface RateMapper {
void add(Rate rate); void add(Rate rate);
//获取货币名称列表 //获取货币名称列表
List<Rate> listRateName(); List<Rate> listRateName();
Integer getIdByName(String rateName);
} }

3
src/main/java/com/example/demo/service/cash/CashCollectionService.java

@ -51,8 +51,7 @@ public interface CashCollectionService {
// 根据精网号和钱包 ID 查询用户钱包明细列表分页 // 根据精网号和钱包 ID 查询用户钱包明细列表分页
PageInfo<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId( PageInfo<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId(
Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId);
Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId, String market);
// 根据精网号和地区查询用户的所有钱包 ID 和金币数量包含用户名和地区分页 // 根据精网号和地区查询用户的所有钱包 ID 和金币数量包含用户名和地区分页
PageInfo<UserWalletVO> selectUserWallets(Integer jwcode, String market, Integer pageNum, Integer pageSize, String sortField, String sortOrder, Integer sortWalletId); PageInfo<UserWalletVO> selectUserWallets(Integer jwcode, String market, Integer pageNum, Integer pageSize, String sortField, String sortOrder, Integer sortWalletId);
// 添加流水--其他收入 // 添加流水--其他收入

10
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.cash.CashCollectionMapper;
import com.example.demo.mapper.coin.AuditMapper; import com.example.demo.mapper.coin.AuditMapper;
import com.example.demo.mapper.coin.MarketMapper; 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.mapper.coin.RechargeMapper;
import com.example.demo.service.cash.CashAuditService; import com.example.demo.service.cash.CashAuditService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -49,6 +50,8 @@ public class CashAuditServiceImpl implements CashAuditService {
private RabbitTemplate rabbitTemplate; private RabbitTemplate rabbitTemplate;
@Autowired @Autowired
private MarketMapper marketMapper; private MarketMapper marketMapper;
@Autowired
private RateMapper rateMapper;
@Transactional @Transactional
@ -92,7 +95,12 @@ public class CashAuditServiceImpl implements CashAuditService {
rechargeOrder.setFreeDecember(order.getFreeGold()); rechargeOrder.setFreeDecember(order.getFreeGold());
} }
rechargeOrder.setSumGold(order.getPermanentGold() + 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.setMoney(order.getPaymentAmount().intValue());
rechargeOrder.setRemark(order.getRemark()); rechargeOrder.setRemark(order.getRemark());
rechargeOrder.setVoucher(order.getVoucher()); rechargeOrder.setVoucher(order.getVoucher());

4
src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java

@ -620,9 +620,9 @@ public class CashCollectionServiceImpl implements CashCollectionService {
// 根据精网号和钱包 ID 查询用户钱包明细列表分页 // 根据精网号和钱包 ID 查询用户钱包明细列表分页
@Override @Override
public PageInfo<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId( public PageInfo<UserWalletRecordVO> selectWalletRecordsByJwcodeAndWalletId(
Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId) {
Integer pageNum, Integer pageSize, Integer jwcode, Integer walletId, String market) {
PageHelper.startPage(pageNum, pageSize); PageHelper.startPage(pageNum, pageSize);
List<UserWalletRecordVO> records = cashCollectionMapper.selectWalletRecordsByJwcodeAndWalletId(jwcode, walletId);
List<UserWalletRecordVO> records = cashCollectionMapper.selectWalletRecordsByJwcodeAndWalletId(jwcode, walletId, market);
return new PageInfo<>(records); return new PageInfo<>(records);
} }

3
src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java

@ -844,7 +844,7 @@ public class CashRefundServiceImpl implements RefundService {
{ {
wallet = 3; wallet = 3;
} }
if (payType.equals("iPay88"))
if (payType.equals("iPay88")||payType.equals("Ipay88"))
{ {
wallet = 4; 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())); walletMapper.insert(new UserRegionWallet(null, cashRecordRefund.getJwcode(), wallet, BigDecimal.ZERO, new Date(), new Date()));
log.warn("用户钱包不存在,已初始化钱包"); log.warn("用户钱包不存在,已初始化钱包");
} }
userRegionWallet = walletMapper.selectWallet(cashRecordRefund.getJwcode(), wallet);
if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPartRefundGold())) < 0) { if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPartRefundGold())) < 0) {
throw new BusinessException("用户钱包金币不足"); throw new BusinessException("用户钱包金币不足");
} }

3
src/main/resources/cashMapper/CashCollectionMapper.xml

@ -522,6 +522,9 @@
<if test="walletId != null"> <if test="walletId != null">
AND uwr.wallet_id = #{walletId} AND uwr.wallet_id = #{walletId}
</if> </if>
<if test="market != null and market != ''">
AND u.market = #{market}
</if>
</where> </where>
ORDER BY uwr.create_time DESC ORDER BY uwr.create_time DESC
</select> </select>

3
src/main/resources/mapper/RateMapper.xml

@ -16,6 +16,9 @@
FROM rate FROM rate
</select> </select>
<select id="getIdByName" resultType="java.lang.Integer">
SELECT id FROM rate WHERE rate_name = #{rateName}
</select>
<update id="update"> <update id="update">
UPDATE UPDATE

Loading…
Cancel
Save