Compare commits

...

46 Commits

Author SHA1 Message Date
lijianlin 7b44a12a10 04-08 资金流水详情补充字段 18 hours ago
lijianlin 9b6461fce2 Merge remote-tracking branch 'refs/remotes/origin/lijianlin/feature-20260401-现金管理四期' into milestone-20260401-现金管理四期 18 hours ago
lijianlin ff5bbee306 04-08 新增流水添加是否归属业绩字段 20 hours ago
wangguorui 02c67a9407 Merge remote-tracking branch 'origin/milestone-20260401-现金管理四期' into milestone-20260401-现金管理四期 20 hours ago
wangguorui 0139f95436 20260408 退款提交的退款币种优化 20 hours ago
sunjiabei 9e12d0ffbe 20260404业绩调整 20 hours ago
wangguorui bddcd3a442 20260408 导出字段优化 21 hours ago
wangguorui e054a42d16 20260407 钱包明细页面字段更新 2 days ago
lijianlin f3b0f46f43 04-07 工作台营收汇率算法修改 2 days ago
sunjiabei 6ab47bed9a 20260404业绩调整 5 days ago
sunjiabei 613700f396 20260404业绩调整 5 days ago
sunjiabei 38c085624f 20260404业绩调整 5 days ago
sunjiabei 81dd5b7a56 20260404业绩调整 5 days ago
sunjiabei eff03cf1da 20260404业绩调整 5 days ago
sunjiabei 8aafbe5df6 20260414业绩调整 5 days ago
sunjiabei 114ca39852 20260414业绩调整 5 days ago
wangguorui bdce9d7689 20260404 新增地区支付方式翻译 5 days ago
wangguorui 1d732d6d6a 20260404 新增流水翻译 5 days ago
wangguorui 6e20de3d7c Merge remote-tracking branch 'origin/milestone-20260401-现金管理四期' into milestone-20260401-现金管理四期 6 days ago
wangguorui f3a0b2cd76 20260403 导出翻译 6 days ago
lijianlin c2747cd22a Merge remote-tracking branch 'refs/remotes/origin/milestone-20260401-现金管理四期' into lijianlin/feature-20260401-现金管理四期 6 days ago
lijianlin 03dc6b4c46 04-03 资金流水账 地区-支付方式筛选 6 days ago
lijianlin a3565c96b0 04-03 地区-支付方式树形结构 6 days ago
wangguorui f12b375365 20260403 修复问题 6 days ago
huangqizhen 40f2553204 Merge remote-tracking branch 'refs/remotes/origin/合并分支使用' into milestone-20260401-现金管理四期 6 days ago
wangguorui f2e0373ea1 20260403 翻译交易币种 6 days ago
wangguorui ebefe887e7 20260403 交易币种(退款) 6 days ago
lijianlin bcfbbbf1f5 04-03 新增流水——iPay88手续费 6 days ago
wangguorui 0841876f4d 20260403 交易币种(消耗) 6 days ago
wangguorui fa0da36a53 20260403 交易币种(充值) 6 days ago
lijianlin 5cc4c82811 04-03 新增流水——其他收入补充字段 6 days ago
lijianlin b5ab3ce0b9 04-03 新增流水——其他收入 6 days ago
lijianlin 016dae45b8 Merge remote-tracking branch 'refs/remotes/origin/lijianlin/feature-20260401-现金管理四期' into milestone-20260401-现金管理四期 7 days ago
lijianlin d0755aef89 04-02 新增流水——其他收入骨架 7 days ago
lijianlin 03fbac8a77 04-02 退款订单同步展示到资金流水账 7 days ago
lijianlin db13b3cc41 Merge remote-tracking branch 'refs/remotes/origin/milestone-20260401-现金管理四期' into lijianlin/feature-20260401-现金管理四期 7 days ago
lijianlin 1dd94a4797 04-02 新增流水——其他收入骨架 7 days ago
lijianlin 490194c6fc 04-02 退款订单同步展示到资金流水账 7 days ago
sunjiabei f8e90ad97b 20260412业绩归属地字段 7 days ago
sunjiabei 967d58c260 20260412业绩归属地字段 7 days ago
wangguorui 081a5cd689 Merge remote-tracking branch 'origin/milestone-20260401-现金管理四期' into milestone-20260401-现金管理四期 7 days ago
wangguorui 41d5663a5e 20260402 查询活动归属地 7 days ago
lijianlin 63ad3ae5f4 Merge remote-tracking branch 'refs/remotes/origin/milestone-20260401-现金管理四期' into lijianlin/feature-20260401-现金管理四期 7 days ago
lijianlin 2a50130f0d 04-02 修改本地redis配置 7 days ago
lijianlin 0ab14a89e9 04-02 资金流水账补充字段,添加业绩归属筛选 7 days ago
sunjiabei 9a11afc2c3 20260412ipay88手续费 7 days ago
  1. 18
      pom.xml
  2. 58
      src/main/java/com/example/demo/Util/AppleTokenGenerator.java
  3. 6
      src/main/java/com/example/demo/Util/AuthKey_3J2S9VXU3V.p8
  4. 33
      src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java
  5. 80
      src/main/java/com/example/demo/controller/cash/CashCollectionController.java
  6. 76
      src/main/java/com/example/demo/controller/coin/MarketController.java
  7. 48
      src/main/java/com/example/demo/controller/coin/RechargeActivityCenterController.java
  8. 33
      src/main/java/com/example/demo/domain/DTO/AddFundsDTO.java
  9. 19
      src/main/java/com/example/demo/domain/DTO/AreaPayTypeDTO.java
  10. 29
      src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java
  11. 3
      src/main/java/com/example/demo/domain/entity/CashRecord.java
  12. 3
      src/main/java/com/example/demo/domain/entity/UserWalletRecord.java
  13. 20
      src/main/java/com/example/demo/domain/vo/cash/AreaPayTypeTreeVO.java
  14. 2
      src/main/java/com/example/demo/domain/vo/cash/CashCollection.java
  15. 45
      src/main/java/com/example/demo/domain/vo/cash/FundsDTO.java
  16. 16
      src/main/java/com/example/demo/domain/vo/cash/PayTypeVO.java
  17. 13
      src/main/java/com/example/demo/domain/vo/cash/PerformanceVO.java
  18. 1
      src/main/java/com/example/demo/domain/vo/cash/UserWalletRecordVO.java
  19. 13
      src/main/java/com/example/demo/domain/vo/coin/AreaInfo.java
  20. 11
      src/main/java/com/example/demo/mapper/cash/CashCollectionMapper.java
  21. 3
      src/main/java/com/example/demo/mapper/coin/MarketMapper.java
  22. 4
      src/main/java/com/example/demo/mapper/coin/RechargeActivityCenterMapper.java
  23. 1
      src/main/java/com/example/demo/mapper/coin/UserMapper.java
  24. 13
      src/main/java/com/example/demo/service/cash/CashCollectionService.java
  25. 4
      src/main/java/com/example/demo/service/coin/MarketService.java
  26. 4
      src/main/java/com/example/demo/service/coin/RechargeActivityCenterService.java
  27. 5
      src/main/java/com/example/demo/serviceImpl/cash/BankServiceImpl.java
  28. 19
      src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java
  29. 158
      src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java
  30. 39
      src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java
  31. 1
      src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java
  32. 4
      src/main/java/com/example/demo/serviceImpl/coin/ConsumeServiceImpl.java
  33. 4
      src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java
  34. 40
      src/main/java/com/example/demo/serviceImpl/coin/MarketServiceImpl.java
  35. 17
      src/main/java/com/example/demo/serviceImpl/coin/RechargeActivityCenterServiceImpl.java
  36. 7
      src/main/resources/application-test.yml
  37. 119
      src/main/resources/cashMapper/CashCollectionMapper.xml
  38. 143
      src/main/resources/cashMapper/CashRefundMapper.xml
  39. 6
      src/main/resources/mapper/ConsumeMapper.xml
  40. 12
      src/main/resources/mapper/MarketMapper.xml
  41. 11
      src/main/resources/mapper/RechargeActivityCenterMapper.xml
  42. 6
      src/main/resources/mapper/UserMapper.xml
  43. 5
      src/main/resources/mapper/WalletMapper.xml
  44. 2
      src/main/resources/mapper/WorkBenchMapper.xml

18
pom.xml

@ -40,7 +40,23 @@
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>io.jsonwebtoken</groupId>-->
<!-- <artifactId>jjwt-api</artifactId>-->
<!-- <version>0.11.5</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.jsonwebtoken</groupId>-->
<!-- <artifactId>jjwt-impl</artifactId>-->
<!-- <version>0.11.5</version>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.jsonwebtoken</groupId>-->
<!-- <artifactId>jjwt-jackson</artifactId>-->
<!-- <version>0.11.5</version>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>

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

@ -0,0 +1,58 @@
//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);
//// }
//}

6
src/main/java/com/example/demo/Util/AuthKey_3J2S9VXU3V.p8

@ -0,0 +1,6 @@
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQge12P08wGtrp8dttS
6fA0dtL46GYnBYEumTnx3/g53qGgCgYIKoZIzj0DAQehRANCAATiWWs9qLs7eYCv
ZIfG0JYRrLjLqotAGdEtfTii1gh+IKK4snS499kwk+vKg1vHy2ZovyZDdvmW/z+i
WSzRu18f
-----END PRIVATE KEY-----

33
src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java

@ -237,6 +237,7 @@ public class ExcelHeaderTranslator {
headers.put("id", "序号");
headers.put("jwcode", "精网号");
headers.put("name", "姓名");
headers.put("performanceMarket", "业绩归属地区");
headers.put("marketName", "所属地区");
headers.put("activity", "活动名称");
headers.put("orderCode", "金币订单号");
@ -273,7 +274,7 @@ public class ExcelHeaderTranslator {
*/
public List<String> getCashCollectionColumnOrder() {
return Arrays.asList(
"id", "jwcode", "name", "marketName", "activity", "orderCode", "bankCode",
"id", "jwcode", "name", "performanceMarket", "marketName", "activity", "orderCode", "bankCode",
"goodsName", "goodNum", "numUnit", "permanentGold", "freeGold", "paymentCurrency",
"paymentAmount", "receivedCurrency", "receivedAmount", "handlingCharge",
"receivedMarket", "payType", "payTime", "receivedTime", "submitterName",
@ -558,16 +559,21 @@ public class ExcelHeaderTranslator {
// 添加所有表头的原始中文名称对应 FundsDTO 类的字段
headers.put("id", "序号");
headers.put("jwcode", "精网号");
headers.put("orderCode", "金币订单号");
headers.put("receivedMarket", "到账地区");
headers.put("performanceMarket", "业绩归属地区");
headers.put("name", "姓名");
headers.put("jwcode", "精网号");
headers.put("remark", "备注");
headers.put("goodNum", "商品数量");
headers.put("goodsName", "商品名称");
headers.put("payType", "付款类型");
headers.put("paymentAmount", "付款金额");
headers.put("handlingCharge", "手续费");
headers.put("receivedAmount", "到账金额");
headers.put("marketName", "所属地区");
headers.put("orderCode", "金币订单号");
headers.put("paymentCurrencyName", "付款币种");
headers.put("paymentAmount", "付款金额");
headers.put("receivedCurrencyName", "到账币种");
headers.put("receivedAmount", "到账金额");
headers.put("handlingCharge", "手续费");
headers.put("payType", "付款类型");
headers.put("statusName", "退款状态");
headers.put("refundCurrency", "退款币种");
headers.put("refundAmount", "退款金额");
@ -585,9 +591,10 @@ public class ExcelHeaderTranslator {
*/
public List<String> getFundsColumnOrder() {
return Arrays.asList(
"id", "jwcode", "name", "marketName", "orderCode", "paymentCurrencyName", "paymentAmount",
"receivedCurrencyName", "receivedAmount", "handlingCharge", "payType", "statusName", "refundCurrency",
"refundAmount"
"id", "orderCode", "receivedMarket", "performanceMarket", "name", "jwcode",
"remark", "goodNum", "goodsName", "payType", "paymentAmount", "handlingCharge",
"receivedAmount", "marketName", "paymentCurrencyName", "receivedCurrencyName",
"statusName", "refundCurrency", "refundAmount"
);
}
@ -604,6 +611,7 @@ public class ExcelHeaderTranslator {
headers.put("marketName", "所属地区");
headers.put("walletName", "钱包名称");
headers.put("typeText", "交易类型");
headers.put("transactionCurrency", "交易币种");
headers.put("amount", "交易金额");
headers.put("orderCode", "订单号");
headers.put("description", "交易说明");
@ -623,8 +631,9 @@ public class ExcelHeaderTranslator {
*/
public List<String> getUserWalletColumnOrder() {
return Arrays.asList(
"jwcode", "userName", "marketName", "walletName", "typeText", "amount",
"orderCode", "description", "statusText", "createTime"
"jwcode", "userName", "marketName", "walletName", "typeText",
"transactionCurrency", "amount", "orderCode", "description",
"statusText", "createTime"
);
}

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

@ -3,6 +3,8 @@ package com.example.demo.controller.cash;
import com.example.demo.Util.JWTUtil;
import com.example.demo.Util.LanguageTranslationUtil;
import com.example.demo.config.interfac.Log;
import com.example.demo.domain.DTO.AddFundsDTO;
import com.example.demo.domain.DTO.PerformanceAdjustmentDTO;
import com.example.demo.domain.DTO.PerformanceDTO;
import com.example.demo.domain.entity.*;
import com.example.demo.domain.vo.cash.*;
@ -457,6 +459,51 @@ public class CashCollectionController {
return Result.error("查询失败" + ": " + e.getMessage());
}
}
/**
*新增流水-其他收入
*/
@PostMapping("/addExFund")
public Result addExFund(@RequestBody CashCollection addFundsDTO, @RequestHeader(defaultValue = "zh_CN") String lang) {
try {
// 解析语言代码
String languageCode = parseLanguageCode(lang);
// 如果不是中文环境将查询条件中的翻译文本转换为中文简体
if (!"zh".equalsIgnoreCase(languageCode) && !"zh_cn".equalsIgnoreCase(languageCode)) {
convertTranslatedFieldsToChinese(addFundsDTO, languageCode);
}
String result = cashCollectionService.addExFund(addFundsDTO);
String successMsg = languageTranslationUtil.translate(result, lang);
return Result.success(successMsg);
} catch (Exception e) {
String errorMsg = languageTranslationUtil.translate(e.getMessage(), lang);
return Result.error(errorMsg);
}
}
/**
*新增iPay88手续费
*/
@PostMapping("/addiPay88Fee")
public Result addIpay88Fee(@RequestBody CashCollection cashCollection, @RequestHeader(defaultValue = "zh_CN") String lang) {
try {
// 解析语言代码
String languageCode = parseLanguageCode(lang);
// 如果不是中文环境将查询条件中的翻译文本转换为中文简体
if (!"zh".equalsIgnoreCase(languageCode) && !"zh_cn".equalsIgnoreCase(languageCode)) {
convertTranslatedFieldsToChinese(cashCollection, languageCode);
}
String result = cashCollectionService.addIpay88Fee(cashCollection);
String successMsg = languageTranslationUtil.translate(result, lang);
return Result.success(successMsg);
} catch (Exception e) {
String errorMsg = languageTranslationUtil.translate(e.getMessage(), lang);
return Result.error(errorMsg);
}
}
/**
* 查询所有钱包类型
@ -485,6 +532,16 @@ public class CashCollectionController {
return Result.error("查询失败");
}
}
@PostMapping("/adjust")
public Result adjust(@RequestBody PerformanceAdjustmentDTO adjustDTO) {
try {
cashCollectionService.adjust(adjustDTO);
return Result.success("调整成功");
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 转换用户钱包 VO 的多语言字段
*/
@ -808,7 +865,24 @@ public class CashCollectionController {
}
// 翻译交易类型
if (vo.getType() != null) {
String typeText = vo.getType() == 0 ? "充值" : (vo.getType() == 1 ? "消耗" : "退款");
String typeText;
switch (vo.getType()) {
case 0:
typeText = "充值";
break;
case 1:
typeText = "消耗";
break;
case 2:
typeText = "退款";
break;
case 3:
typeText = "软件购买";
break;
default:
typeText = "未知";
break;
}
vo.setTypeText(languageTranslationUtil.translate(typeText, lang));
}
// 翻译状态
@ -816,6 +890,10 @@ public class CashCollectionController {
String statusText = vo.getStatus() == 0 ? "正常" : "已退款";
vo.setStatusText(languageTranslationUtil.translate(statusText, lang));
}
// 翻译交易币种
if (vo.getTransactionCurrency() != null) {
vo.setTransactionCurrency(languageTranslationUtil.translate(vo.getTransactionCurrency(), lang));
}
}
}
}

76
src/main/java/com/example/demo/controller/coin/MarketController.java

@ -2,6 +2,8 @@ package com.example.demo.controller.coin;
import com.example.demo.config.interfac.Log;
import com.example.demo.domain.entity.Market;
import com.example.demo.domain.vo.cash.AreaPayTypeTreeVO;
import com.example.demo.domain.vo.cash.PayTypeVO;
import com.example.demo.domain.vo.coin.Result;
import com.example.demo.service.coin.MarketService;
import com.example.demo.Util.LanguageTranslationUtil;
@ -48,6 +50,30 @@ public class MarketController {
}
}
//获取市场 - 支付方式树形结构
@RequestMapping("/getAreaPayTypeTree")
public Result getAreaPayTypeTree(@RequestHeader(defaultValue = "zh_CN") String lang) {
try {
// 解析语言代码
String languageCode = parseLanguageCode(lang);
List<AreaPayTypeTreeVO> marketsTree = marketService.getAreaPayTypeTree();
// 如果不是中文环境先将翻译后的名称转换为中文简体进行处理
if (!"zh".equalsIgnoreCase(languageCode) && !"zh_cn".equalsIgnoreCase(languageCode)) {
convertTranslatedAreaPayTypeTreeToChinese(marketsTree, languageCode);
}
// 对地区名称和支付方式名称进行多语言转换
translateAreaPayTypeTree(marketsTree, lang);
return Result.success(marketsTree);
} catch (Exception e) {
log.error("获取市场列表失败", e);
String errorMsg = languageTranslationUtil.translate("获取市场列表失败", lang);
return Result.error(errorMsg);
}
}
/**
* 递归转换市场名称为指定语言
@ -67,6 +93,56 @@ public class MarketController {
}
}
/**
* 转换地区支付方式树的多语言字段
*/
private void translateAreaPayTypeTree(List<AreaPayTypeTreeVO> treeList, String lang) {
if (treeList != null) {
for (AreaPayTypeTreeVO node : treeList) {
// 翻译地区名称
if (node.getName() != null) {
node.setName(languageTranslationUtil.translate(node.getName(), lang));
}
// 翻译支付方式名称
if (node.getChildren() != null) {
for (PayTypeVO payType : node.getChildren()) {
if (payType.getName() != null) {
payType.setName(languageTranslationUtil.translate(payType.getName(), lang));
}
}
}
}
}
}
/**
* 将翻译后的地区支付方式树名称转换为中文简体
*/
private void convertTranslatedAreaPayTypeTreeToChinese(List<AreaPayTypeTreeVO> treeList, String languageCode) {
if (treeList != null) {
for (AreaPayTypeTreeVO node : treeList) {
// 转换地区名称
if (node.getName() != null && !node.getName().isEmpty()) {
String chineseName = translationService.findChineseSimplifiedByTranslation(
node.getName(), languageCode);
node.setName(chineseName);
}
// 转换支付方式名称
if (node.getChildren() != null) {
for (PayTypeVO payType : node.getChildren()) {
if (payType.getName() != null && !payType.getName().isEmpty()) {
String chineseName = translationService.findChineseSimplifiedByTranslation(
payType.getName(), languageCode);
payType.setName(chineseName);
}
}
}
}
}
}
/**
* 解析语言代码
*/
private String parseLanguageCode(String langHeader) {

48
src/main/java/com/example/demo/controller/coin/RechargeActivityCenterController.java

@ -1,6 +1,7 @@
package com.example.demo.controller.coin;
import com.example.demo.config.interfac.Log;
import com.example.demo.domain.vo.coin.AreaInfo;
import com.example.demo.domain.vo.coin.Page;
import com.example.demo.domain.vo.coin.RechargeActivity;
import com.example.demo.domain.vo.coin.Result;
@ -264,6 +265,53 @@ public class RechargeActivityCenterController {
}
/**
* 根据活动 ID 查询归属地
*
* @param activity 充值活动请求参数包含活动 ID
* @return 查询结果成功返回归属地信息失败返回错误信息
* @throws NullPointerException 当活动 ID 为空时抛出
* @throws IllegalArgumentException 当活动 ID 无效时抛出
*/
@Log("查询活动归属地")
@PostMapping("/queryActivityArea")
public Result queryActivityArea(@RequestBody RechargeActivity activity, @RequestHeader(defaultValue = "zh_CN") String lang) {
try {
// 解析语言代码
String languageCode = parseLanguageCode(lang);
if (activity.getId() == null) {
String errorMsg = languageTranslationUtil.translate("查询失败:活动 ID 不能为空", lang);
return Result.error(errorMsg);
}
AreaInfo result = rechargeActivityCenterService.queryActivityAreaById(activity.getId());
// 如果 area "0"直接返回
if ("0".equals(result.getArea())) {
return Result.success(result);
}
// 对返回结果进行多语言转换
if (result.getArea() != null && !result.getArea().isEmpty()) {
result.setArea(languageTranslationUtil.translate(result.getArea(), lang));
}
if (result.getAreaName() != null && !result.getAreaName().isEmpty()) {
result.setAreaName(languageTranslationUtil.translate(result.getAreaName(), lang));
}
return Result.success(result);
} catch (NullPointerException e) {
log.error("查询活动归属地失败:空指针异常", e);
String errorMsg = languageTranslationUtil.translate("查询失败:数据为空", lang);
return Result.error(errorMsg);
} catch (IllegalArgumentException e) {
log.error("查询活动归属地失败:参数异常", e);
String errorMsg = languageTranslationUtil.translate("查询失败:" + e.getMessage(), lang);
return Result.error(errorMsg);
}
}
/**
* 转换充值活动的多语言字段
*/
private void translateRechargeActivities(com.github.pagehelper.PageInfo<RechargeActivity> pageInfo, String lang) {

33
src/main/java/com/example/demo/domain/DTO/AddFundsDTO.java

@ -0,0 +1,33 @@
package com.example.demo.domain.DTO;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
/**
* @program: gold-java
* @ClassName addFundsDTO
* @description:
* @author: Ethan
* @create: 202604-02 16:56
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class AddFundsDTO {
private String performanceMarket; //业绩归属地区
private Integer goodNum; //商品数量
private String payType; //付款方式
private Integer paymentCurrency; //付款币种
private BigDecimal paymentAmount; //付款金额
@ExcelIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date payTime; //付款时间
private BigDecimal handlingCharge; //手续费
private String remark; //备注
}

19
src/main/java/com/example/demo/domain/DTO/AreaPayTypeDTO.java

@ -0,0 +1,19 @@
package com.example.demo.domain.DTO;
import lombok.Data;
/**
* @program: gold-java
* @ClassName AreaPayTypeDTO
* @description:
* @author: Ethan
* @create: 202604-03 16:06
* @Version 1.0
**/
@Data
public class AreaPayTypeDTO {
private Integer areaId;
private String areaName;
private Integer payTypeId;
private String payTypeName;
private String payType; // 支付方式名称pay_type
}

29
src/main/java/com/example/demo/domain/DTO/PerformanceAdjustmentDTO.java

@ -0,0 +1,29 @@
package com.example.demo.domain.DTO;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @program: gold-java
* @ClassName PerformanceAdjustmentDTO
* @description:
* @author: Double
* @create: 202604-03 09:56
* @Version 1.0
**/
@Data
public class PerformanceAdjustmentDTO {
private Integer submitterId; // 提交人ID
private String submitterMarket; // 提交人市场
private int[][] matrix = new int[6][6];
private Double weight; // 权重
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private LocalDateTime Time; // 时间
}

3
src/main/java/com/example/demo/domain/entity/CashRecord.java

@ -83,7 +83,8 @@ public class CashRecord implements Serializable {
private LocalDateTime refundTime; // 退款日期到天
private String refundRemark; // 退款备注执行人填写
private String refundVoucher; // 退款截图
private String performanceMarket; // 业绩地区
private String performanceMarketName; // 业绩地区名称
// 系统字段
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private LocalDateTime createTime;

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

@ -14,7 +14,8 @@ public class UserWalletRecord {
private Integer id; // 主键 ID
private Integer jwcode; // 精网号
private Integer walletId; // 钱包 ID
private Integer type; // 交易类型0=充值1=消耗2=退款
private Integer type; // 交易类型0=充值1=消耗2=退款3=软件购买
private String transactionCurrency; // 交易币种
private Integer amount; // 交易金额
private String orderCode; // 交易单号
private String description; // 交易说明

20
src/main/java/com/example/demo/domain/vo/cash/AreaPayTypeTreeVO.java

@ -0,0 +1,20 @@
package com.example.demo.domain.vo.cash;
import lombok.Data;
import java.util.List;
/**
* @program: gold-java
* @ClassName AreaPayTypeTreeVO
* @description:
* @author: Ethan
* @create: 202604-03 16:04
* @Version 1.0
**/
@Data
public class AreaPayTypeTreeVO {
private Integer id; // 地区ID
private String name; // 地区名称
private List<PayTypeVO> children; // 支付方式列表
}

2
src/main/java/com/example/demo/domain/vo/cash/CashCollection.java

@ -34,6 +34,8 @@ public class CashCollection implements Serializable {
private Integer orderType; // 订单类型1-收款2-退款
private Integer jwcode; // 精网号
private String name; // 姓名
private String performanceMarket; //业绩归属地区
private String isPerformance; // 是否归属业绩 1归 0不归
@ExcelIgnore
private String market; // 所属地区
private String marketName; // 所属地区名称

45
src/main/java/com/example/demo/domain/vo/cash/FundsDTO.java

@ -1,6 +1,7 @@
package com.example.demo.domain.vo.cash;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.example.demo.domain.DTO.AreaPayTypeDTO;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -23,27 +24,49 @@ import java.util.List;
@NoArgsConstructor
public class FundsDTO {
private Integer id;
private Integer jwcode;
@ExcelIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date payTime;
private String orderCode;
private String receivedMarket; //到账地区
private String performanceMarket; //业绩归属地区
private String activityName; //活动名称
private String name;
private Integer jwcode;
private String remark; //备注
private Integer goodNum; //商品数量
private String goodsName;
private String voucher; //转账凭证
private String payType;
// 地区+支付方式组合列表
@ExcelIgnore
private List<AreaPayTypeDTO> areaPayTypeList;
@ExcelIgnore
private Integer receivedCurrency;
private BigDecimal paymentAmount;
private BigDecimal handlingCharge;
private BigDecimal receivedAmount;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date receivedTime;
@ExcelIgnore
private Integer market;
private String marketName;
@ExcelIgnore
private List<String> markets;
private String orderCode;
@ExcelIgnore
private List<String> performanceMarkets;
@ExcelIgnore
private Integer paymentCurrency;
private String paymentCurrencyName;
private BigDecimal paymentAmount;
@ExcelIgnore
private Integer receivedCurrency;
private String receivedCurrencyName;
private BigDecimal receivedAmount;
private BigDecimal handlingCharge;
private String payType;
@ExcelIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date payTime;
@ExcelIgnore
private Integer status;
private String statusName;

16
src/main/java/com/example/demo/domain/vo/cash/PayTypeVO.java

@ -0,0 +1,16 @@
package com.example.demo.domain.vo.cash;
import lombok.Data;
/**
* @program: gold-java
* @ClassName PayTypeVO
* @description:
* @author: Ethan
* @create: 202604-03 16:04
* @Version 1.0
**/
@Data
public class PayTypeVO {
private Integer id;
private String name;
}

13
src/main/java/com/example/demo/domain/vo/cash/PerformanceVO.java

@ -33,5 +33,14 @@ public class PerformanceVO {
private String receivedCurrency; // 到账币种
private BigDecimal receivedAmount; // 到账金额
private BigDecimal handlingCharge; // 手续费
}
private String receivedMarket; // 到账地区
private String receivedMarketName; // 到账地区名称
private String performanceMarket; // 收款地区
private String performanceMarketName; // 收款地区名称
private String goodsName; // 商品名称
private String remark; // 备注
private Integer goodNum; // 商品数量
private String payType; // 付款方式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime payTime; // 付款时间
}

1
src/main/java/com/example/demo/domain/vo/cash/UserWalletRecordVO.java

@ -26,6 +26,7 @@ public class UserWalletRecordVO {
@ExcelIgnore
private Integer type; // 交易类型0=充值1=消耗2=退款
private String typeText; // 交易类型文本多语言
private String transactionCurrency; // 交易币种
private Integer amount; // 交易金额
private String orderCode; // 交易单号
private String description; // 交易说明

13
src/main/java/com/example/demo/domain/vo/coin/AreaInfo.java

@ -0,0 +1,13 @@
package com.example.demo.domain.vo.coin;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AreaInfo {
private String area; // 归属地 ID
private String areaName; // 归属地名称
}

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

@ -3,10 +3,7 @@ package com.example.demo.mapper.cash;
//import com.example.demo.domain.DTO.PaymentDTO;
import com.example.demo.domain.DTO.*;
import com.example.demo.domain.entity.*;
import com.example.demo.domain.vo.cash.CashCollection;
import com.example.demo.domain.vo.cash.PerformanceVO;
import com.example.demo.domain.vo.cash.UserWalletRecordVO;
import com.example.demo.domain.vo.cash.UserWalletVO;
import com.example.demo.domain.vo.cash.*;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -131,4 +128,10 @@ public interface CashCollectionMapper {
@Param("sortField") String sortField,
@Param("sortOrder") String sortOrder,
@Param("sortWalletId") Integer sortWalletId);
// 添加流水--其他收入
void addExFund(@Param("addFundsDTO") CashCollection addFundsDTO);
void adjust(CashRecord cashRecord);
// 添加流水--iPay88手续费
void addIpay88Fee(CashCollection cashCollection);
}

3
src/main/java/com/example/demo/mapper/coin/MarketMapper.java

@ -1,6 +1,7 @@
package com.example.demo.mapper.coin;
import cn.hutool.core.lang.Opt;
import com.example.demo.domain.DTO.AreaPayTypeDTO;
import com.example.demo.domain.entity.Market;
import org.apache.ibatis.annotations.Param;
@ -23,4 +24,6 @@ public interface MarketMapper {
String getMarketById(String market);
//获取市场id
List<Market> getMarketByIds(@Param("marketIds") Set<Integer> marketIds);
//获取市场-支付方式树形结构
List<AreaPayTypeDTO> selectAreaPayTypeList();
}

4
src/main/java/com/example/demo/mapper/coin/RechargeActivityCenterMapper.java

@ -23,9 +23,13 @@ public interface RechargeActivityCenterMapper {
// 根据ID查询活动
List<RechargeActivity> queryActivity(RechargeActivity activity);
// 根据活动名称查询活动
RechargeActivity queryActivityByName(RechargeActivity activity);
// 根据活动 ID 查询活动归属地
RechargeActivity queryActivityAreaById(@Param("id") Integer id);
// 新增活动
void addActivity(RechargeActivity activity);

1
src/main/java/com/example/demo/mapper/coin/UserMapper.java

@ -40,6 +40,7 @@ public interface UserMapper {
//查找用户全部信息
User selectAllUser(String jwcode);
User selectUserMarket(String jwcode);
//查找用户的首充日期
Date getFirstRecharge(String jwcode);

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

@ -1,13 +1,12 @@
package com.example.demo.service.cash;
import com.example.demo.domain.DTO.AddFundsDTO;
import com.example.demo.domain.DTO.PerformanceAdjustmentDTO;
import com.example.demo.domain.DTO.PerformanceDTO;
import com.example.demo.domain.entity.CashRecord;
import com.example.demo.domain.entity.GOrder;
import com.example.demo.domain.entity.RechargeActivity;
import com.example.demo.domain.vo.cash.CashCollection;
import com.example.demo.domain.vo.cash.PerformanceVO;
import com.example.demo.domain.vo.cash.UserWalletRecordVO;
import com.example.demo.domain.vo.cash.UserWalletVO;
import com.example.demo.domain.vo.cash.*;
import com.example.demo.domain.vo.coin.Result;
import com.github.pagehelper.PageInfo;
@ -56,4 +55,10 @@ public interface CashCollectionService {
// 根据精网号和地区查询用户的所有钱包 ID 和金币数量包含用户名和地区分页
PageInfo<UserWalletVO> selectUserWallets(Integer jwcode, String market, Integer pageNum, Integer pageSize, String sortField, String sortOrder, Integer sortWalletId);
// 添加流水--其他收入
String addExFund(CashCollection addFundsDTO);
// 调整业绩
void adjust(PerformanceAdjustmentDTO adjustDTO);
//添加iPay88手续费
String addIpay88Fee(CashCollection cashCollection);
}

4
src/main/java/com/example/demo/service/coin/MarketService.java

@ -1,6 +1,7 @@
package com.example.demo.service.coin;
import com.example.demo.domain.entity.Market;
import com.example.demo.domain.vo.cash.AreaPayTypeTreeVO;
import java.util.List;
@ -19,4 +20,7 @@ public interface MarketService {
List<String> getMarketIds(List<String> list);
//dao获取市场id
String getMarketIdsDao(String country);
//获取市场-支付方式树形结构
List<AreaPayTypeTreeVO> getAreaPayTypeTree();
}

4
src/main/java/com/example/demo/service/coin/RechargeActivityCenterService.java

@ -1,5 +1,6 @@
package com.example.demo.service.coin;
import com.example.demo.domain.vo.coin.AreaInfo;
import com.example.demo.domain.vo.coin.RechargeActivity;
import com.github.pagehelper.PageInfo;
@ -31,4 +32,7 @@ public interface RechargeActivityCenterService {
// 删除活动
void deleteActivity(RechargeActivity activity);
// 根据活动 ID 查询归属地
AreaInfo queryActivityAreaById(Integer id);
}

5
src/main/java/com/example/demo/serviceImpl/cash/BankServiceImpl.java

@ -957,8 +957,9 @@ public class BankServiceImpl implements BankService {
int amountInt = (int) Math.round(amountDouble);
ipay88DTO.setAmount(String.valueOf(amountInt));
double feeDouble = cashCollection.getPermanentGold() * 3.18 * 0.0085;
int feeInt = (int) Math.round(feeDouble);
// double feeDouble = cashCollection.getPermanentGold() * 3.18 * 0.0085;
// int feeInt = (int) Math.round(feeDouble);
int feeInt = 0;
ipay88DTO.setFee(String.valueOf(feeInt));
int netInt = amountInt-feeInt;

19
src/main/java/com/example/demo/serviceImpl/cash/CashAuditServiceImpl.java

@ -143,6 +143,7 @@ public class CashAuditServiceImpl implements CashAuditService {
walletRecord.setJwcode(order.getJwcode());
walletRecord.setWalletId(walletId);
walletRecord.setType(0); // 0=充值
walletRecord.setTransactionCurrency("金币");
walletRecord.setAmount(order.getPermanentGold());
walletRecord.setOrderCode(orderCode);
walletRecord.setDescription(order.getPayType());
@ -237,6 +238,24 @@ public class CashAuditServiceImpl implements CashAuditService {
user.setRechargeNum(1); //充值次数加一
auditMapper.updateUserGold(user);
}
else {
// 先从数据库中获取订单的 walletId
CashRecord dbRecord = cashCollectionMapper.selectByOrderCode(orderCode);
Integer walletId = dbRecord != null ? dbRecord.getWalletId() : null;
// 创建钱包明细记录
UserWalletRecord walletRecord = new UserWalletRecord();
walletRecord.setJwcode(order.getJwcode());
walletRecord.setWalletId(walletId);
walletRecord.setType(3); // 3=软件购买
walletRecord.setTransactionCurrency(order.getPaymentCurrency());
walletRecord.setAmount(order.getPaymentAmount().intValue());
walletRecord.setOrderCode(orderCode);
walletRecord.setDescription(order.getGoodsName()+order.getGoodNum()+order.getNumUnit());
walletRecord.setStatus(0); // 0=正常
cashCollectionMapper.insertUserWalletRecord(walletRecord);
log.info("创建钱包明细记录:jwcode={}, walletId={}, orderCode={}, amount={}",
order.getJwcode(), walletId, orderCode, order.getPermanentGold());
}
} else if (action == 2) { //驳回
updateOrder.setStatus(2);
updateOrder.setRejectReason(rejectReason);

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

@ -3,9 +3,12 @@ package com.example.demo.serviceImpl.cash;
import com.example.demo.Util.JWTUtil;
import com.example.demo.Util.LanguageTranslationUtil;
import com.example.demo.config.RabbitMQConfig;
import com.example.demo.domain.DTO.AddFundsDTO;
import com.example.demo.domain.DTO.PerformanceAdjustmentDTO;
import com.example.demo.domain.DTO.PerformanceDTO;
import com.example.demo.domain.entity.*;
import com.example.demo.domain.vo.cash.*;
import com.example.demo.domain.vo.coin.AreaInfo;
import com.example.demo.domain.vo.coin.GoldUser;
import com.example.demo.domain.vo.coin.Messages;
import com.example.demo.domain.vo.coin.Result;
@ -13,6 +16,7 @@ import com.example.demo.mapper.cash.CashCollectionMapper;
import com.example.demo.mapper.coin.MarketMapper;
import com.example.demo.mapper.coin.UserMapper;
import com.example.demo.service.cash.CashCollectionService;
import com.example.demo.service.coin.RechargeActivityCenterService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.servlet.http.HttpServletRequest;
@ -54,6 +58,8 @@ public class CashCollectionServiceImpl implements CashCollectionService {
private RabbitTemplate rabbitTemplate;
@Autowired
private LanguageTranslationUtil languageTranslationUtil;
@Autowired
private RechargeActivityCenterService rechargeActivityCenterService;
//新增收款订单
@Override
@ -70,6 +76,9 @@ public class CashCollectionServiceImpl implements CashCollectionService {
if (cashCollection.getActivity() == null || cashCollection.getActivity().isEmpty()) {
throw new IllegalArgumentException("活动不能为空");
}
if (cashCollection.getWalletId() == null || cashCollection.getWalletId() < 1 || cashCollection.getWalletId() > 10) {
throw new IllegalArgumentException("钱包 ID 为 1~10");
}
if (cashCollection.getGoodsName() == null|| cashCollection.getGoodsName().isEmpty()) {
throw new IllegalArgumentException("产品名称不能为空");
}
@ -77,9 +86,6 @@ public class CashCollectionServiceImpl implements CashCollectionService {
if (cashCollection.getPermanentGold() == 0 && cashCollection.getFreeGold() == 0) {
throw new IllegalArgumentException("金币数量不能为空");
}
if (cashCollection.getWalletId() == null || cashCollection.getWalletId() < 1 || cashCollection.getWalletId() > 10) {
throw new IllegalArgumentException("钱包 ID 为 1~10");
}
}
if (!cashCollection.getGoodsName().equals("金币充值")) {
if (cashCollection.getGoodNum() == 0) {
@ -104,7 +110,7 @@ public class CashCollectionServiceImpl implements CashCollectionService {
if (cashCollection.getPayTime() == null) {
throw new IllegalArgumentException("付款时间不能为空");
}
AreaInfo areaInfo = rechargeActivityCenterService.queryActivityAreaById(Integer.parseInt(cashCollection.getActivity()));
// 校验钱包 ID 和到账地区的对应关系
validateWalletAndMarket(cashCollection.getWalletId(), cashCollection.getReceivedMarket());
@ -134,6 +140,12 @@ public class CashCollectionServiceImpl implements CashCollectionService {
cashRecord.setSubmitterMarket(cashCollection.getSubmitterMarket());
cashRecord.setOrderType(1); //订单类型1-收款
cashRecord.setMarket(cashCollection.getMarket());
if(areaInfo.getArea().equals("0")){
cashRecord.setPerformanceMarket(cashCollection.getMarket());
}else {
cashRecord.setPerformanceMarket(areaInfo.getArea());
}
//地区根据 jwcode 插入
//cashRecord.setMarket(cashCollectionMapper.getMarketByJwcode(cashRecord.getJwcode()));
//插入新收款订单
@ -510,6 +522,7 @@ public class CashCollectionServiceImpl implements CashCollectionService {
}else cashRecord.setName("未知");
cashRecord.setMarket(cashCollectionMapper.getMarketByJwcode(gOrder.getJwcode()));
cashRecord.setPerformanceMarket(cashRecord.getMarket());
if (gOrder.getType().equals("gold")){ //充金豆
cashRecord.setActivity("99");
cashRecord.setGoodsName("Link充值金豆");
@ -534,6 +547,7 @@ public class CashCollectionServiceImpl implements CashCollectionService {
cashRecord.setPayType("IOS内购");
cashRecord.setBankCode(gOrder.getIosTransactionId());
cashRecord.setReceivedMarket("4");
cashRecord.setPerformanceMarket("4");
cashRecord.setPayload("IOS");
break;
case 5:
@ -673,6 +687,141 @@ public class CashCollectionServiceImpl implements CashCollectionService {
return resultPageInfo;
}
//新增流水--其他收入
@Override
public String addExFund(CashCollection addFundsDTO) {
if (addFundsDTO.getPerformanceMarket() == null|| addFundsDTO.getPerformanceMarket().isEmpty())
throw new IllegalArgumentException("业绩归属地区不能为空");
if (addFundsDTO.getGoodsName() == null|| addFundsDTO.getGoodsName().isEmpty())
throw new IllegalArgumentException("收入类别不能为空");
if (addFundsDTO.getPayType() == null|| addFundsDTO.getPayType().isEmpty())
throw new IllegalArgumentException("付款方式不能为空");
if (addFundsDTO.getPaymentCurrency() == null)
throw new IllegalArgumentException("币种不能为空");
if (addFundsDTO.getPaymentAmount() == null)
throw new IllegalArgumentException("付款金额不能为空");
if (addFundsDTO.getGoodNum() == null)
addFundsDTO.setGoodNum(0);
//生成订单号后半部分
String orderNumber = UUID.randomUUID().toString().replaceAll("-", "");
//构建订单信息
addFundsDTO.setOrderCode("QT_" + orderNumber); //订单号
addFundsDTO.setStatus(4);
addFundsDTO.setActivity("123");
addFundsDTO.setJwcode(90039082);
addFundsDTO.setName("HomilyLink");
addFundsDTO.setMarket("24032");
addFundsDTO.setOrderType(1);
addFundsDTO.setReceivedMarket(addFundsDTO.getPerformanceMarket());
addFundsDTO.setReceivedAmount(addFundsDTO.getPaymentAmount());
addFundsDTO.setReceivedCurrency(addFundsDTO.getPaymentCurrency());
cashCollectionMapper.addExFund(addFundsDTO);
return "添加成功";
}
//添加iPay88手续费
@Override
public String addIpay88Fee(CashCollection cashCollection) {
if (cashCollection.getPayType()== null|| cashCollection.getPayType().isEmpty())
throw new IllegalArgumentException("支付方式不能为空");
if (cashCollection.getPerformanceMarket()== null|| cashCollection.getPerformanceMarket().isEmpty())
throw new IllegalArgumentException("业绩归属地区不能为空");
if (cashCollection.getPaymentCurrency()== null|| cashCollection.getPaymentCurrency().isEmpty())
throw new IllegalArgumentException("币种不能为空");
if (cashCollection.getHandlingCharge()== null|| cashCollection.getHandlingCharge().compareTo(BigDecimal.ZERO) < 0)
throw new IllegalArgumentException("手续费不能为空");
if (cashCollection.getRemark()== null|| cashCollection.getRemark().isEmpty())
throw new IllegalArgumentException("备注不能为空");
//生成订单号后半部分
String orderNumber = UUID.randomUUID().toString().replaceAll("-", "");
//构建订单信息
cashCollection.setOrderCode("QT_" + orderNumber); //订单号
cashCollection.setGoodsName("手续费");
cashCollection.setReceivedMarket("5");
cashCollection.setStatus(4);
cashCollection.setPaymentAmount(BigDecimal.ZERO);
cashCollection.setJwcode(90039082);
cashCollection.setName("HomilyLink");
cashCollection.setMarket("24032");
cashCollection.setOrderType(1);
cashCollection.setActivity("124");
cashCollectionMapper.addIpay88Fee(cashCollection);
return "添加成功";
}
@Override
public void adjust(PerformanceAdjustmentDTO adjustDTO) {
if (adjustDTO == null) {
throw new IllegalArgumentException("传参不能为空");
}
int[][] matrix = adjustDTO.getMatrix();
Double weight = adjustDTO.getWeight();
if (weight == null) {
throw new IllegalArgumentException("权重不能为空");
}
// Performance market codes and corresponding Chinese names
String[] performanceMarkets = {"4", "5", "13", "24018", "24022", "24016"};
String[] marketNames = {"新加坡", "马来西亚", "香港", "泰国", "越南", "加拿大"};
// Multiply each element in the matrix by the factor
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
// Calculate adjusted value and round to nearest integer
int adjustedValue = (int) (matrix[i][j] * weight);
matrix[i][j] = adjustedValue;
if (i == j) {
continue;
}
// Skip if value is 0
if (adjustedValue == 0) {
continue;
}
// Create order code with timestamp
String orderCode = "TZ_" + System.currentTimeMillis();
// Determine direction and create remark based on value sign
String fromMarket = performanceMarkets[i];
String toMarket = performanceMarkets[j];
String fromName = marketNames[i];
String toName = marketNames[j];
String remark;
if (adjustedValue > 0) {
// Positive value: row to column (转出方 to 转入方)
remark = fromName + "→" + toName + "调整金额:" + adjustedValue;
} else {
// Negative value: column to row (转入方 to 转出方)
remark = toName + "→" + fromName + "调整金额:" + -adjustedValue;
}
// Create CashRecord objects and call mapper adjust method twice
for (int k = 0; k < 2; k++) {
CashRecord cashRecord = new CashRecord();
cashRecord.setOrderCode(orderCode + "_" + k);
cashRecord.setSubmitterId(adjustDTO.getSubmitterId());
cashRecord.setSubmitterMarket(adjustDTO.getSubmitterMarket());
cashRecord.setRemark(remark);
cashRecord.setPayTime(adjustDTO.getTime());
if(k == 0){
cashRecord.setPerformanceMarket(fromMarket);
cashRecord.setReceivedMarket(fromMarket);
cashRecord.setReceivedAmount(new BigDecimal(-adjustedValue));
}else{
cashRecord.setPerformanceMarket(toMarket);
cashRecord.setReceivedMarket(toMarket);
cashRecord.setReceivedAmount(new BigDecimal(adjustedValue));
}
// Call mapper adjust method
cashCollectionMapper.adjust(cashRecord);
}
}
}
}
/**
* 校验钱包 ID 和到账地区的对应关系
* @param walletId 钱包 ID
@ -709,4 +858,5 @@ public class CashCollectionServiceImpl implements CashCollectionService {
throw new IllegalArgumentException("钱包 ID=" + walletId + " 对应的到账地区应为:" + marketName + "(" + expectedMarket + ")");
}
}
}

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

@ -536,6 +536,7 @@ public class CashRefundServiceImpl implements RefundService {
// 5. 插入退款流水amount 存负数表示扣减
UserWalletRecord refundRecord = new UserWalletRecord();
refundRecord.setType(2); // 充值退款类型
refundRecord.setTransactionCurrency("金币"); // 交易币种
refundRecord.setJwcode(userGoldRecord.getJwcode());
refundRecord.setWalletId(walletId);
refundRecord.setAmount(refundAmount.negate().intValue()); // 🔥 负数扣款
@ -925,41 +926,6 @@ public class CashRefundServiceImpl implements RefundService {
}
List<FundsDTO> list = cashRefundMapper.selectfunds(fundsDTO);
// 2. 收集 status == 6 的记录 ID
List<Integer> needQueryIds = new ArrayList<>();
for (FundsDTO dto : list) {
if (dto.getStatus() != null && dto.getStatus() == 6) {
needQueryIds.add(dto.getId());
}
}
// 3. 批量查询 refundDetail 信息用于负数处理
if (!needQueryIds.isEmpty()) {
List<FundsDTO> detailList = cashRefundMapper.selectRefundCount(needQueryIds);
Map<Integer, FundsDTO> detailMap = new HashMap<>();
for (FundsDTO detail : detailList) {
// 假设 detail.getRelatedId() 对应主表的 id
detailMap.put(detail.getRelatedId(), detail);
}
// 回填 refundAmount取负 refundCurrency
for (FundsDTO dto : list) {
if (dto.getStatus() != null && dto.getStatus() == 6) {
FundsDTO detail = detailMap.get(dto.getId());
if (detail != null) {
BigDecimal amount = detail.getRefundAmount();
if (amount != null) {
dto.setRefundAmount(amount.negate()); // 转为负数
} else {
dto.setRefundAmount(null); // 或设为 BigDecimal.ZERO
}
dto.setRefundCurrency(detail.getRefundCurrency());
}
}
}
}
// 4. 收集所有需要转换的 regionId currencyId
Set<Integer> regionIds = new HashSet<>();
Set<Integer> currencyIds = new HashSet<>();
@ -1011,6 +977,9 @@ public class CashRefundServiceImpl implements RefundService {
// 8. 返回分页结果
return new PageInfo<>(list);
}
/**
* 计算用户指定钱包列表的总可用余额
* @param jwcode 用户标识

1
src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java

@ -252,6 +252,7 @@ public class AuditServiceImpl implements AuditService {
refundRecord.setJwcode(order.getJwcode());
refundRecord.setWalletId(walletId);
refundRecord.setType(2); // 退款类型
refundRecord.setTransactionCurrency("金币"); // 交易币种
refundRecord.setAmount(refundAmount.intValue()); // 🔥 退款存正数
refundRecord.setOrderCode(order.getOrderCode());
if(refundModel==0){

4
src/main/java/com/example/demo/serviceImpl/coin/ConsumeServiceImpl.java

@ -238,12 +238,14 @@ public class ConsumeServiceImpl implements ConsumeService {
UserWalletRecord userWalletRecord = new UserWalletRecord();
userWalletRecord.setJwcode(consumeUser.getJwcode());
userWalletRecord.setWalletId(wallet.getWalletId());
userWalletRecord.setType(1); // 1=消耗
userWalletRecord.setTransactionCurrency("金币"); // 交易币种
userWalletRecord.setAmount(-deductAmount.intValue());
userWalletRecord.setOrderCode(userGoldRecord.getOrderCode());
userWalletRecord.setDescription("购买" + consumeUser.getGoodsName());
// 设置需要扣除的永久金币金额
updateWallet.setPermanentGold(deductAmount);
// 调用Mapper方法更新钱包余额
// 调用 Mapper 方法更新钱包余额
consumeMapper.updateRegionWallet(updateWallet);
consumeMapper.addRegionWalletRecord(userWalletRecord);
}

4
src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java

@ -2078,6 +2078,10 @@ public class ExportExcelServiceImpl implements ExportExcelService {
if (item.getDescription() != null && !item.getDescription().isEmpty()) {
item.setDescription(languageTranslationUtil.translate(item.getDescription(), lang));
}
// 翻译交易币种
if (item.getTransactionCurrency() != null && !item.getTransactionCurrency().isEmpty()) {
item.setTransactionCurrency(languageTranslationUtil.translate(item.getTransactionCurrency(), lang));
}
}
}
/**

40
src/main/java/com/example/demo/serviceImpl/coin/MarketServiceImpl.java

@ -1,12 +1,17 @@
package com.example.demo.serviceImpl.coin;
import com.example.demo.domain.DTO.AreaPayTypeDTO;
import com.example.demo.domain.entity.Market;
import com.example.demo.domain.vo.cash.AreaPayTypeTreeVO;
import com.example.demo.domain.vo.cash.PayTypeVO;
import com.example.demo.mapper.coin.MarketMapper;
import com.example.demo.service.coin.MarketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@ -83,4 +88,39 @@ public class MarketServiceImpl implements MarketService {
return "24030"; // 异常时返回默认市场
}
}
@Override
public List<AreaPayTypeTreeVO> getAreaPayTypeTree() {
// 1. 查询关联数据
List<AreaPayTypeDTO> dtoList = marketMapper.selectAreaPayTypeList();
// 2. 按地区分组
Map<Integer, List<AreaPayTypeDTO>> groupByArea = dtoList.stream()
.collect(Collectors.groupingBy(AreaPayTypeDTO::getAreaId));
List<AreaPayTypeTreeVO> treeList = new ArrayList<>();
// 3. 封装树形
for (Map.Entry<Integer, List<AreaPayTypeDTO>> entry : groupByArea.entrySet()) {
AreaPayTypeDTO first = entry.getValue().get(0);
AreaPayTypeTreeVO tree = new AreaPayTypeTreeVO();
tree.setId(first.getAreaId());
tree.setName(first.getAreaName());
// 封装支付方式
List<PayTypeVO> children = entry.getValue().stream()
.map(dto -> {
PayTypeVO vo = new PayTypeVO();
vo.setId(dto.getPayTypeId());
vo.setName(dto.getPayTypeName());
return vo;
})
.distinct() // 去重
.collect(Collectors.toList());
tree.setChildren(children);
treeList.add(tree);
}
return treeList;
}
}

17
src/main/java/com/example/demo/serviceImpl/coin/RechargeActivityCenterServiceImpl.java

@ -1,5 +1,6 @@
package com.example.demo.serviceImpl.coin;
import com.example.demo.domain.vo.coin.AreaInfo;
import com.example.demo.domain.vo.coin.RechargeActivity;
import com.example.demo.mapper.coin.RechargeActivityCenterMapper;
import com.example.demo.service.coin.RechargeActivityCenterService;
@ -165,4 +166,20 @@ public class RechargeActivityCenterServiceImpl implements RechargeActivityCenter
public void deleteActivity(RechargeActivity activity) {
rechargeActivityCenterMapper.deleteActivity(activity);
}
// 根据活动 ID 查询归属地
@Override
public AreaInfo queryActivityAreaById(Integer id) {
RechargeActivity activity = rechargeActivityCenterMapper.queryActivityAreaById(id);
if (activity == null || activity.getArea() == null) {
AreaInfo result = new AreaInfo();
result.setArea("0");
result.setAreaName(null);
return result;
}
AreaInfo areaInfo = new AreaInfo();
areaInfo.setArea(activity.getArea());
areaInfo.setAreaName(activity.getAreaName());
return areaInfo;
}
}

7
src/main/resources/application-test.yml

@ -81,9 +81,10 @@ spring:
data:
redis:
database: 0
host: localhost
port: 6379
password: 123456
host: 54.255.212.181
port: 10703
password: Ngc0FYUTA6h3wC5J
lettuce:
pool:

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

@ -6,12 +6,12 @@
<insert id="add" parameterType="com.example.demo.domain.entity.CashRecord"
useGeneratedKeys="true" keyProperty="id">
insert into
cash_record_collection(order_type,jwcode,name,market,activity,
cash_record_collection(order_type,jwcode,name,market,activity,performance_market,
order_code,bank_code,goods_name,good_num,num_unit,permanent_gold,free_gold,
payment_currency,payment_amount,received_market,
pay_type,pay_time,status,submitter_id,submitter_market,payload,audit_time,
voucher,remark,wallet_id)
values(#{orderType},#{jwcode},#{name},#{market},#{activity},
values(#{orderType},#{jwcode},#{name},#{market},#{activity},#{performanceMarket},
#{orderCode},#{bankCode},#{goodsName},#{goodNum},#{numUnit},#{permanentGold},#{freeGold},#{paymentCurrency},
#{paymentAmount},#{receivedMarket},#{payType},#{payTime},
#{status},#{submitterId},#{submitterMarket},#{payload},#{auditTime},#{voucher},#{remark},#{walletId})
@ -226,13 +226,15 @@
</choose>
</select>
<select id="selectAuditByOrderCode" resultType="com.example.demo.domain.entity.CashRecord">
select crc.id,jwcode,name,market,ra.activity_name as activity,
order_code,bank_code,goods_name,good_num,num_unit,permanent_gold,free_gold,
payment_currency,payment_amount,pay_type,pay_time,crc.status,submitter_id,
voucher,remark,version,received_market
from cash_record_collection crc
left join recharge_activity ra on ra.id = crc.activity
where order_code=#{orderCode}
select crc.id,jwcode,name,market,ra.activity_name as activity,
order_code,bank_code,goods_name,good_num,num_unit,permanent_gold,free_gold,
r1.rate_name as payment_currency,r2.rate_name as received_currency,payment_amount,pay_type,pay_time,crc.status,submitter_id,
voucher,remark,version,received_market
from cash_record_collection crc
left join recharge_activity ra on ra.id = crc.activity
left join rate r1 on r1.id = crc.payment_currency
left join rate r2 on r2.id = crc.received_currency
where order_code=#{orderCode}
</select>
<!--根据精网号获取姓名-->
<select id="getNameByJwcode" resultType="java.lang.String">
@ -326,12 +328,56 @@
</update>
<select id="performanceSelect" resultType="com.example.demo.domain.vo.cash.PerformanceVO" parameterType="com.example.demo.domain.DTO.PerformanceDTO">
select cr.jwcode,cr.name,cr.market,m.name as marketName,cr.order_code,r1.rate_name as paymentCurrency,cr.payment_amount,r2.rate_name as receivedCurrency,cr.received_amount,cr.handling_charge
<!-- 原始收款记录 -->
select cr.pay_time,cr.order_code,m2.name as receivedMarketName,m1.name as performanceMarketName,cr.name,cr.jwcode,cr.goods_name,cr.remark,cr.good_num,cr.pay_type,r2.rate_name as receivedCurrency,cr.payment_amount,cr.handling_charge,cr.received_amount
from cash_record_collection cr
left join market m on m.id = cr.market
left join rate r1 on r1.id = cr.payment_currency
left join market m1 on m1.id = cr.performance_market
left join market m2 on m2.id = cr.received_market
left join rate r2 on r2.id = cr.received_currency
where order_type = 1 and status = 4
where (cr.status = 4 or cr.status = 100 or (cr.status = 6 and cr.is_performance = 1))
<!-- adminMarket筛选:如果adminMarket列表不为空且不包含研发部或总部,则筛选market表中的name等于adminMarket列表中的内容 -->
<if test="adminMarket != null and adminMarket.size() > 0">
<choose>
<when test="adminMarket.contains('研发部'.toString()) or adminMarket.contains('总部'.toString())">
<!-- 如果包含研发部或总部,则不筛选 -->
</when>
<otherwise>
AND cr.received_market IN
<foreach collection="adminMarket" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</otherwise>
</choose>
</if>
<!-- customerMarket筛选:如果customerMarket列表不为空,则筛选cash_record_collection表中的market等于customerMarket列表中的内容 -->
<if test="customerMarket != null and customerMarket.size() > 0">
AND cr.performance_market IN
<foreach collection="customerMarket" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<!-- jwcode筛选:如果jwcode不为空,则筛选cash_record_collection表中的jwcode等于jwcode -->
<if test="jwcode != null and jwcode != ''">
AND cr.jwcode = #{jwcode}
</if>
<!-- 时间范围筛选:如果startTime和endTime不为空,则筛选cash_record_collection表中的pay_time在startTime和endTime之间 -->
<if test="startTime != null and endTime != null">
AND cr.pay_time BETWEEN #{startTime} AND #{endTime}
</if>
<!-- 当cr.status = 6时,添加退款记录 -->
UNION ALL
select crr.refund_time as pay_time,crr.order_code,m2.name as receivedMarketName,m1.name as performanceMarketName,crr.name,crr.jwcode,cr.goods_name,crr.refund_reason as remark,cr.good_num,cr.pay_type,r3.rate_name as receivedCurrency,-crr.refund_amount as payment_amount,0 as handling_charge,-crr.refund_amount as received_amount
from cash_record_refund crr
left join cash_record_collection cr on cr.id = crr.related_id
left join market m1 on m1.id = cr.performance_market
left join market m2 on m2.id = cr.received_market
left join rate r3 on r3.id = crr.refund_currency
where cr.status = 6 and cr.is_performance = 1
<!-- adminMarket筛选:如果adminMarket列表不为空且不包含研发部或总部,则筛选market表中的name等于adminMarket列表中的内容 -->
<if test="adminMarket != null and adminMarket.size() > 0">
@ -340,7 +386,7 @@
<!-- 如果包含研发部或总部,则不筛选 -->
</when>
<otherwise>
AND m.name IN
AND cr.received_market IN
<foreach collection="adminMarket" item="item" open="(" separator="," close=")">
#{item}
</foreach>
@ -350,7 +396,7 @@
<!-- customerMarket筛选:如果customerMarket列表不为空,则筛选cash_record_collection表中的market等于customerMarket列表中的内容 -->
<if test="customerMarket != null and customerMarket.size() > 0">
AND cr.market IN
AND cr.performance_market IN
<foreach collection="customerMarket" item="item" open="(" separator="," close=")">
#{item}
</foreach>
@ -365,6 +411,8 @@
<if test="startTime != null and endTime != null">
AND cr.pay_time BETWEEN #{startTime} AND #{endTime}
</if>
ORDER BY pay_time DESC
</select>
@ -418,8 +466,32 @@
<!-- 插入用户钱包明细记录 -->
<insert id="insertUserWalletRecord" parameterType="com.example.demo.domain.entity.UserWalletRecord">
INSERT INTO user_wallet_record (jwcode, wallet_id, type, amount, order_code, description, status, create_time)
VALUES (#{jwcode}, #{walletId}, #{type}, #{amount}, #{orderCode}, #{description}, #{status}, NOW())
INSERT INTO user_wallet_record (jwcode, wallet_id, type, transaction_currency, amount, order_code, description, status, create_time)
VALUES (#{jwcode}, #{walletId}, #{type}, #{transactionCurrency}, #{amount}, #{orderCode}, #{description}, #{status}, NOW())
</insert>
<!--新增流水——其他收入-->
<insert id="addExFund" >
insert into cash_record_collection
(jwcode,name,market,activity,order_code,goods_name,good_num,pay_type,payment_currency,
payment_amount,status,order_type,received_market,received_amount,received_currency,
performance_market,remark,handling_charge,pay_time,submitter_id,submitter_market,is_performance)
values(#{addFundsDTO.jwcode},#{addFundsDTO.name},#{addFundsDTO.market},
#{addFundsDTO.activity},#{addFundsDTO.orderCode},#{addFundsDTO.goodsName},
#{addFundsDTO.goodNum},#{addFundsDTO.payType},#{addFundsDTO.paymentCurrency},
#{addFundsDTO.paymentAmount},#{addFundsDTO.status},#{addFundsDTO.orderType},
#{addFundsDTO.receivedMarket},#{addFundsDTO.receivedAmount},#{addFundsDTO.receivedCurrency},
#{addFundsDTO.performanceMarket},#{addFundsDTO.remark},#{addFundsDTO.handlingCharge},#{addFundsDTO.payTime},
#{addFundsDTO.submitterId},#{addFundsDTO.submitterMarket},#{addFundsDTO.isPerformance})
</insert>
<insert id="addIpay88Fee">
insert into cash_record_collection
(order_type,jwcode,name,market,activity,order_code,goods_name,pay_type,payment_currency,handling_charge,remark,payment_amount,
received_market,performance_market,submitter_id,submitter_market,pay_time)
values(#{orderType},#{jwcode},#{name},#{market},#{activity},#{orderCode},
#{goodsName},#{payType},#{paymentCurrency},#{handlingCharge},#{remark},
#{paymentAmount},#{receivedMarket},#{performanceMarket},#{submitterId},
#{submitterMarket},now()
)
</insert>
<!-- 根据精网号和钱包 ID 查询用户钱包明细列表 -->
@ -433,6 +505,7 @@
uwr.wallet_id,
w.wallet_name as walletName,
uwr.type,
uwr.transaction_currency,
uwr.amount/100 as amount,
uwr.order_code as orderCode,
uwr.description,
@ -605,5 +678,15 @@
SET flag = #{flag}
WHERE type_id = #{typeId} AND type = #{type}
</update>
<insert id="adjust" parameterType="com.example.demo.domain.entity.CashRecord"
useGeneratedKeys="true" keyProperty="id">
insert into
cash_record_collection(order_type,jwcode,name,market,activity,performance_market,
order_code,goods_name,permanent_gold,free_gold,
pay_type,pay_time,status,submitter_id,submitter_market,
voucher,remark,received_currency,payment_amount,received_amount,received_market,is_performance)
values(1,90039082,"HomilyLink",24032,125,#{performanceMarket},
#{orderCode},"业绩",0,0,"调整",#{payTime},
100,#{submitterId},#{submitterMarket},1,#{remark},3,0,#{receivedAmount},#{receivedMarket},1)
</insert>
</mapper>

143
src/main/resources/cashMapper/CashRefundMapper.xml

@ -336,7 +336,7 @@
crc.good_num as goodsNum,
crc.num_unit,
crr.refund_model,
crr.refund_currency,
r.rate_name as refund_currency,
crr.refund_amount,
crr.refund_channels,
crr.refund_voucher,
@ -349,13 +349,14 @@
crr.submitter_id,
crr.related_id,
crr.refund_reason,
la.area_servise,
la.area_finance,
la.area_charge,
la.head_finance
from cash_record_refund crr
left join cash_record_collection crc on crc.id = crr.related_id
left join lhl_audit la on la.id = crr.audit_id
la.area_servise,
la.area_finance,
la.area_charge,
la.head_finance
from cash_record_refund crr
left join cash_record_collection crc on crc.id = crr.related_id
left join lhl_audit la on la.id = crr.audit_id
left join rate r on r.id = crr.refund_currency
<where>
<if test="status != null">
and crr.status = #{status}
@ -387,7 +388,7 @@
)
</if>
<if test="refundCurrency != null and refundCurrency.length() > 0">
AND crr.refund_currency like CONCAT('%', #{refundCurrency}, '%')
AND r.rate_name like CONCAT('%', #{refundCurrency}, '%')
</if>
<if test="refundChannels != null and refundChannels.length()>0">
and crr.refund_channels like CONCAT('%', #{refundChannels}, '%')
@ -435,38 +436,50 @@
crr.remark,
crr.reject_reason,
crr.refund_model,
crr.refund_currency,
r.rate_name as refund_currency,
crr.refund_amount,
crr.refund_channels,
crr.refund_time,
crr.refund_remark,
crr.refund_voucher
from cash_record_refund crr
left join rate r on r.id = crr.refund_currency
where crr.id = #{id}
</select>
<select id="selectfunds" resultType="com.example.demo.domain.vo.cash.FundsDTO">
SELECT * FROM (
SELECT
crc.id,
crc.jwcode,
ra.activity_name,
crc.goods_name,
crc.remark,
crc.good_num,
crc.performance_market,
crc.received_market,
crc.name,
crc.market,
crc.order_code,
crc.payment_currency,
ROUND(crc.payment_amount / 100.0, 2) as paymentAmount,
crc.received_currency,
ROUND(crc.received_amount / 100.0, 2) as receivedAmount,
ROUND(crc.handling_charge / 100.0, 2) as handlingCharge,
ROUND(crc.permanent_gold / 100.0, 2) as permanentGold,
ROUND(crc.free_gold / 100.0, 2) as freeGold,
crc.pay_type,
crc.pay_time,
crc.status
crc.received_time,
crc.voucher,
crc.status,
NULL as refundCurrency,
NULL as refundAmount,
NULL as relatedId,
0 as isRefundRow
FROM cash_record_collection crc
<where>
left join recharge_activity ra on ra.id = crc.activity
WHERE 1=1
<if test="jwcode != null">
and crc.jwcode = #{jwcode}
</if>
@ -476,6 +489,12 @@
#{markets}
</foreach>
</if>
<if test="performanceMarkets!= null and performanceMarkets.size > 0">
AND crc.performance_market IN
<foreach collection="performanceMarkets" item="performanceMarkets" open="(" separator="," close=")">
#{performanceMarkets}
</foreach>
</if>
<if test="localMarket != null and localMarket.size > 0">
AND crc.market IN
<foreach collection="localMarket" item="localMarket" open="(" separator="," close=")">
@ -485,9 +504,6 @@
<if test="startTime != null and endTime != null">
and crc.`pay_time` BETWEEN #{startTime} AND #{endTime}
</if>
<if test="payType!= null and payType.length > 0">
AND crc.pay_type like CONCAT('%', #{payType}, '%')
</if>
<if test="orderCode!= null and orderCode.length > 0">
AND crc.order_code like CONCAT('%', #{orderCode}, '%')
</if>
@ -497,16 +513,89 @@
#{statuses}
</foreach>
</if>
</where>
<choose>
<when test="sortField != null and sortField.length > 0 or sortOrder != null and sortOrder.length > 0">
ORDER BY ${sortField} ${sortOrder}
</when>
<otherwise>
ORDER BY crc.create_time DESC
</otherwise>
</choose>
<if test="areaPayTypeList != null and areaPayTypeList.size > 0">
AND (
<foreach collection="areaPayTypeList" item="item" separator=" OR ">
(crc.received_market = #{item.areaId} AND crc.pay_type = #{item.payType})
</foreach>
)
</if>
UNION ALL
SELECT
crc.id,
crc.jwcode,
ra.activity_name,
crc.goods_name,
crc.remark,
crc.good_num,
crc.performance_market,
crc.received_market,
crc.name,
crc.market,
CONCAT('TK', crc.order_code) as order_code,
NULL as payment_currency,
NULL as paymentAmount,
crc.received_currency as received_currency,
ROUND(-crr.refund_amount / 100.0, 2) as receivedAmount,
NULL as handlingCharge,
NULL as permanentGold,
NULL as freeGold,
crc.pay_type,
crr.refund_time as pay_time,
crc.status,
crc.received_time,
crc.voucher,
crr.refund_currency as refundCurrency,
ROUND(crr.refund_amount / 100.0, 2) as refundAmount,
crr.related_id as relatedId,
1 as isRefundRow
FROM cash_record_refund crr
INNER JOIN cash_record_collection crc ON crr.related_id = crc.id
left join recharge_activity ra on ra.id = crc.activity
WHERE crc.status =6 and crr.status =41
<if test="jwcode != null">
and crc.jwcode = #{jwcode}
</if>
<if test="markets!= null and markets.size > 0">
AND crc.received_market IN
<foreach collection="markets" item="markets" open="(" separator="," close=")">
#{markets}
</foreach>
</if>
<if test="performanceMarkets!= null and performanceMarkets.size > 0">
AND crc.performance_market IN
<foreach collection="performanceMarkets" item="performanceMarkets" open="(" separator="," close=")">
#{performanceMarkets}
</foreach>
</if>
<if test="localMarket != null and localMarket.size > 0">
AND crc.market IN
<foreach collection="localMarket" item="localMarket" open="(" separator="," close=")">
#{localMarket}
</foreach>
</if>
<if test="startTime != null and endTime != null">
and crc.`pay_time` BETWEEN #{startTime} AND #{endTime}
</if>
<if test="orderCode!= null and orderCode.length > 0">
AND crc.order_code like CONCAT('%', #{orderCode}, '%')
</if>
<if test="areaPayTypeList != null and areaPayTypeList.size > 0">
AND (
<foreach collection="areaPayTypeList" item="item" separator=" OR ">
(crc.received_market = #{item.areaId} AND crc.pay_type = #{item.payType})
</foreach>
)
</if>
) AS combined_result
ORDER BY
id,
isRefundRow DESC,
pay_time DESC
</select>
<select id="selectRefundCount" resultType="com.example.demo.domain.vo.cash.FundsDTO">
select crr.refund_currency,
crr.refund_amount,

6
src/main/resources/mapper/ConsumeMapper.xml

@ -376,13 +376,14 @@
</set>
WHERE id = #{id}
</update>
<!-- 添加钱包记录 -->
<insert id="addRegionWalletRecord" parameterType="com.example.demo.domain.entity.UserWalletRecord">
<!-- 添加钱包记录 -->
<insert id="addRegionWalletRecord" parameterType="com.example.demo.domain.entity.UserWalletRecord">
INSERT INTO user_wallet_record
<trim prefix="(" suffix=")" suffixOverrides=",">
jwcode,
wallet_id,
type,
transaction_currency,
amount,
order_code,
description,
@ -394,6 +395,7 @@
#{jwcode},
#{walletId},
1,
#{transactionCurrency},
#{amount},
#{orderCode},
#{description},

12
src/main/resources/mapper/MarketMapper.xml

@ -55,4 +55,16 @@
</foreach>
</if>
</select>
<select id="selectAreaPayTypeList" resultType="com.example.demo.domain.DTO.AreaPayTypeDTO">
SELECT
m.id AS areaId,
m.name AS areaName,
pt.id AS payTypeId,
pt.name AS payTypeName
FROM payment_type_tree ptt
LEFT JOIN market m ON ptt.area_id = m.id
LEFT JOIN payment_type pt ON ptt.type_id = pt.id
WHERE m.id IS NOT NULL AND pt.id IS NOT NULL
ORDER BY areaId
</select>
</mapper>

11
src/main/resources/mapper/RechargeActivityCenterMapper.xml

@ -120,7 +120,6 @@
</update>
<!-- 删除活动 -->
<!-- 删除活动 -->
<update id="deleteActivity" parameterType="com.example.demo.domain.vo.coin.RechargeActivity">
UPDATE recharge_activity
<set>
@ -130,4 +129,14 @@
WHERE id = #{id}
</update>
<!-- 根据活动 ID 查询归属地 -->
<select id="queryActivityAreaById" resultType="com.example.demo.domain.vo.coin.RechargeActivity">
SELECT
ra.area as area,
m.name as areaName
FROM recharge_activity ra
LEFT JOIN market m on m.id = ra.area
WHERE ra.id = #{id} AND ra.flag = 1
</select>
</mapper>

6
src/main/resources/mapper/UserMapper.xml

@ -88,6 +88,12 @@
FROM user
WHERE jwcode = #{jwcode}
</select>
<select id="selectUserMarket" resultType="com.example.demo.domain.entity.User">
SELECT
market AS "market"
FROM user
WHERE jwcode = #{jwcode}
</select>
<!-- 根据精网号查询金币余额 -->
<select id="selectGold" resultType="com.example.demo.domain.vo.coin.GoldUser">
SELECT

5
src/main/resources/mapper/WalletMapper.xml

@ -2,8 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.coin.WalletMapper">
<insert id="addUserWalletRecord">
insert into user_wallet_record(jwcode, wallet_id, type, amount, order_code, description, status)
values(#{jwcode}, #{walletId}, #{type}, #{amount}, #{orderCode}, #{description}, 1)
insert into user_wallet_record(jwcode, wallet_id, type, transaction_currency, amount, order_code, description, status)
values(#{jwcode}, #{walletId}, #{type}, #{transactionCurrency}, #{amount}, #{orderCode}, #{description}, 1)
</insert>
<insert id="insert">
insert into user_region_wallet(jwcode, wallet_id, current_permanent_gold)
@ -45,6 +45,7 @@
select jwcode,
wallet_id,
type,
transaction_currency,
amount,
order_code,
description,

2
src/main/resources/mapper/WorkBenchMapper.xml

@ -178,7 +178,7 @@
SUM(CASE WHEN r.id = 6 THEN cr.received_amount/100 ELSE 0 END) AS cad,
SUM(CASE WHEN r.id = 7 THEN cr.received_amount/100 ELSE 0 END) AS vdn,
SUM(CASE WHEN r.id = 8 THEN cr.received_amount/100 ELSE 0 END) AS krw,
ROUND( SUM(cr.received_amount/100 * r.num), 2) AS totalSGD
ROUND( SUM(cr.received_amount/100 / r.num), 2) AS totalSGD
FROM cash_record_collection cr
JOIN market m ON cr.received_market = m.id
JOIN rate r ON cr.received_currency = r.id

Loading…
Cancel
Save