111
This commit is contained in:
@@ -8,11 +8,13 @@ import com.it.rattan.monisuo.context.UserContext;
|
||||
import com.it.rattan.monisuo.entity.*;
|
||||
import com.it.rattan.monisuo.mapper.AccountFundMapper;
|
||||
import com.it.rattan.monisuo.mapper.OrderFundMapper;
|
||||
import com.it.rattan.monisuo.mapper.OrderTradeMapper;
|
||||
import com.it.rattan.monisuo.service.*;
|
||||
import com.it.rattan.monisuo.util.JwtUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -46,6 +48,9 @@ public class AdminController {
|
||||
@Autowired
|
||||
private OrderFundMapper orderFundMapper;
|
||||
|
||||
@Autowired
|
||||
private OrderTradeMapper orderTradeMapper;
|
||||
|
||||
// ==================== 公开接口 ====================
|
||||
|
||||
/**
|
||||
@@ -451,7 +456,7 @@ public class AdminController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 资金总览
|
||||
* 资金总览(看板专用,一次 API 返回所有数据)
|
||||
*/
|
||||
@GetMapping("/finance/overview")
|
||||
public Result<Map<String, Object>> getFinanceOverview() {
|
||||
@@ -461,21 +466,47 @@ public class AdminController {
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
|
||||
// 合并为一次查询获取充值总额、提现总额、待审批数
|
||||
Map<String, Object> fundStats = orderFundMapper.sumFinanceOverview();
|
||||
// 本月和上月时间范围(用于环比)
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime monthStart = today.withDayOfMonth(1).atStartOfDay();
|
||||
LocalDateTime monthEnd = today.plusMonths(1).withDayOfMonth(1).atStartOfDay();
|
||||
LocalDateTime lastMonthStart = today.minusMonths(1).withDayOfMonth(1).atStartOfDay();
|
||||
LocalDateTime lastMonthEnd = monthStart;
|
||||
|
||||
// 查询1:order_fund 一次聚合(充值总额、提现总额、实际出款、待审批、环比)
|
||||
Map<String, Object> fundStats = orderFundMapper.sumDashboardStats(
|
||||
monthStart, monthEnd, lastMonthStart, lastMonthEnd);
|
||||
data.put("totalDeposit", fundStats.get("totalDeposit"));
|
||||
data.put("totalWithdraw", fundStats.get("totalWithdraw"));
|
||||
data.put("totalActualPayout", fundStats.get("totalActualPayout"));
|
||||
data.put("pendingCount", ((Number) fundStats.get("pendingCount")).intValue());
|
||||
data.put("monthlyDeposit", fundStats.get("monthlyDeposit"));
|
||||
data.put("monthlyWithdraw", fundStats.get("monthlyWithdraw"));
|
||||
data.put("lastMonthDeposit", fundStats.get("lastMonthDeposit"));
|
||||
data.put("lastMonthWithdraw", fundStats.get("lastMonthWithdraw"));
|
||||
|
||||
BigDecimal fundBalance = accountFundMapper.sumAllBalance();
|
||||
data.put("fundBalance", fundBalance);
|
||||
// 查询2:account_fund 余额和冻结
|
||||
Map<String, Object> balanceStats = accountFundMapper.sumBalanceAndFrozen();
|
||||
data.put("fundBalance", balanceStats.get("totalBalance"));
|
||||
data.put("totalFrozen", balanceStats.get("totalFrozen"));
|
||||
|
||||
// 查询3:交易账户市值
|
||||
BigDecimal tradeValue = accountFundMapper.sumAllTradeValue();
|
||||
data.put("tradeValue", tradeValue != null ? tradeValue : BigDecimal.ZERO);
|
||||
|
||||
// 查询4:用户统计
|
||||
long userCount = userService.count();
|
||||
data.put("userCount", userCount);
|
||||
|
||||
int monthNewUsers = userService.count(new LambdaQueryWrapper<User>()
|
||||
.ge(User::getCreateTime, monthStart));
|
||||
data.put("monthNewUsers", monthNewUsers);
|
||||
|
||||
// 查询5:今日活跃用户(今日有过交易的独立用户数)
|
||||
int todayActiveUsers = orderTradeMapper.countDistinctUserByTime(
|
||||
today.atStartOfDay(), LocalDateTime.now());
|
||||
data.put("todayActiveUsers", todayActiveUsers);
|
||||
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,4 +135,13 @@ public class ColdWalletController {
|
||||
result.put("network", wallet.getNetwork());
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户端 - 获取可用的提现网络列表
|
||||
*/
|
||||
@GetMapping("/api/wallet/networks")
|
||||
public Result<List<String>> getNetworks() {
|
||||
List<String> networks = coldWalletService.getEnabledNetworks();
|
||||
return Result.success(networks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ public class FundController {
|
||||
|
||||
BigDecimal amount = request.getAmount();
|
||||
String withdrawAddress = request.getWithdrawAddress();
|
||||
String network = request.getNetwork();
|
||||
String withdrawContact = request.getWithdrawContact();
|
||||
String remark = request.getRemark();
|
||||
|
||||
@@ -99,7 +100,7 @@ public class FundController {
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Object> result = fundService.withdraw(userId, amount, withdrawAddress, withdrawContact, remark);
|
||||
Map<String, Object> result = fundService.withdraw(userId, amount, withdrawAddress, network, withdrawContact, remark);
|
||||
return Result.success("申请成功,等待审批", result);
|
||||
} catch (Exception e) {
|
||||
return Result.fail(e.getMessage());
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.math.BigDecimal;
|
||||
public class WithdrawRequest {
|
||||
private BigDecimal amount;
|
||||
private String withdrawAddress;
|
||||
private String network;
|
||||
private String withdrawContact;
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ public class OrderFund implements Serializable {
|
||||
/** 冷钱包地址(充值)/提现地址 */
|
||||
private String walletAddress;
|
||||
|
||||
/** 提现网络类型(TRC20/ERC20等) */
|
||||
private String network;
|
||||
|
||||
/** 提现联系方式 */
|
||||
private String withdrawContact;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.it.rattan.monisuo.entity.AccountFund;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 资金账户Mapper
|
||||
@@ -15,6 +16,12 @@ public interface AccountFundMapper extends BaseMapper<AccountFund> {
|
||||
@Select("SELECT IFNULL(SUM(balance), 0) FROM account_fund")
|
||||
BigDecimal sumAllBalance();
|
||||
|
||||
/**
|
||||
* 一次查询获取总余额和总冻结金额
|
||||
*/
|
||||
@Select("SELECT IFNULL(SUM(balance), 0) as totalBalance, IFNULL(SUM(frozen), 0) as totalFrozen FROM account_fund")
|
||||
Map<String, Object> sumBalanceAndFrozen();
|
||||
|
||||
@Select("SELECT IFNULL(SUM(total_deposit), 0) FROM account_fund")
|
||||
BigDecimal sumTotalDeposit();
|
||||
|
||||
|
||||
@@ -16,31 +16,34 @@ import java.util.Map;
|
||||
@Mapper
|
||||
public interface OrderFundMapper extends BaseMapper<OrderFund> {
|
||||
|
||||
@Select("SELECT IFNULL(SUM(amount), 0) FROM order_fund WHERE type = 1 AND status = 2")
|
||||
BigDecimal sumCompletedDeposit();
|
||||
|
||||
@Select("SELECT IFNULL(SUM(amount), 0) FROM order_fund WHERE type = 2 AND status = 2")
|
||||
BigDecimal sumCompletedWithdraw();
|
||||
|
||||
@Select("SELECT COUNT(*) FROM order_fund WHERE status = 1")
|
||||
int countPending();
|
||||
|
||||
/**
|
||||
* 一次性聚合查询:充值总额、提现总额、待审批数
|
||||
* 一次性聚合查询:充值总额、提现总额、实际出款、待审批数、本月/上月环比数据
|
||||
* 充值已完成 status=3,提现已完成 status=2
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 2 THEN amount ELSE 0 END), 0) as totalDeposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 3 THEN amount ELSE 0 END), 0) as totalDeposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 2 AND status = 2 THEN amount ELSE 0 END), 0) as totalWithdraw, " +
|
||||
"SUM(CASE WHEN status IN (1, 5) THEN 1 ELSE 0 END) as pendingCount " +
|
||||
"IFNULL(SUM(CASE WHEN type = 2 AND status = 2 THEN IFNULL(receivable_amount, amount * 0.9) ELSE 0 END), 0) as totalActualPayout, " +
|
||||
"SUM(CASE WHEN (type = 1 AND status = 2) OR (type = 2 AND status IN (1, 5)) THEN 1 ELSE 0 END) as pendingCount, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 3 AND create_time >= #{monthStart} AND create_time < #{monthEnd} THEN amount ELSE 0 END), 0) as monthlyDeposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 2 AND status = 2 AND create_time >= #{monthStart} AND create_time < #{monthEnd} THEN amount ELSE 0 END), 0) as monthlyWithdraw, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 3 AND create_time >= #{lastMonthStart} AND create_time < #{lastMonthEnd} THEN amount ELSE 0 END), 0) as lastMonthDeposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 2 AND status = 2 AND create_time >= #{lastMonthStart} AND create_time < #{lastMonthEnd} THEN amount ELSE 0 END), 0) as lastMonthWithdraw " +
|
||||
"FROM order_fund")
|
||||
Map<String, Object> sumFinanceOverview();
|
||||
Map<String, Object> sumDashboardStats(
|
||||
@Param("monthStart") LocalDateTime monthStart,
|
||||
@Param("monthEnd") LocalDateTime monthEnd,
|
||||
@Param("lastMonthStart") LocalDateTime lastMonthStart,
|
||||
@Param("lastMonthEnd") LocalDateTime lastMonthEnd);
|
||||
|
||||
// ========== 分析相关查询 ==========
|
||||
|
||||
/**
|
||||
* 指定时间段内的手续费总额(0.5%)
|
||||
* 充值已完成 status=3,提现已完成 status=2
|
||||
*/
|
||||
@Select("SELECT IFNULL(SUM(amount * 0.005), 0) FROM order_fund WHERE status = 2 AND create_time >= #{startTime}")
|
||||
@Select("SELECT IFNULL(SUM(amount * 0.005), 0) FROM order_fund WHERE " +
|
||||
"((type = 1 AND status = 3) OR (type = 2 AND status = 2)) AND create_time >= #{startTime}")
|
||||
BigDecimal sumFeeByTime(@Param("startTime") LocalDateTime startTime);
|
||||
|
||||
/**
|
||||
@@ -58,9 +61,10 @@ public interface OrderFundMapper extends BaseMapper<OrderFund> {
|
||||
|
||||
/**
|
||||
* 按月分组统计充值/提现金额(替代循环 N 次查询)
|
||||
* 充值已完成 status=3,提现已完成 status=2
|
||||
*/
|
||||
@Select("SELECT DATE_FORMAT(create_time, '%Y-%m') as month, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 2 THEN amount ELSE 0 END), 0) as deposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 1 AND status = 3 THEN amount ELSE 0 END), 0) as deposit, " +
|
||||
"IFNULL(SUM(CASE WHEN type = 2 AND status = 2 THEN amount ELSE 0 END), 0) as withdraw " +
|
||||
"FROM order_fund WHERE create_time >= #{startTime} AND create_time < #{endTime} " +
|
||||
"GROUP BY DATE_FORMAT(create_time, '%Y-%m') ORDER BY month")
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 冷钱包地址服务
|
||||
@@ -28,6 +29,18 @@ public class ColdWalletService {
|
||||
return coldWalletMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有启用的网络类型(去重)
|
||||
*/
|
||||
public List<String> getEnabledNetworks() {
|
||||
List<ColdWallet> wallets = getEnabledList();
|
||||
return wallets.stream()
|
||||
.map(ColdWallet::getNetwork)
|
||||
.filter(n -> n != null && !n.isEmpty())
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启用的钱包列表
|
||||
*/
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.*;
|
||||
*
|
||||
* 状态定义:
|
||||
* 充值: 1=待付款, 2=待确认, 3=已完成, 4=已驳回, 5=已取消
|
||||
* 提现: 1=待审批, 2=已完成, 3=已驳回, 4=已取消
|
||||
* 提现: 1=待审批, 2=已出款, 3=已驳回, 4=已取消
|
||||
*
|
||||
* 审批参数说明:
|
||||
* status=2 表示审批通过(充值订单最终状态为3,提现订单最终状态为2)
|
||||
@@ -128,7 +128,7 @@ public class FundService {
|
||||
*/
|
||||
@Transactional
|
||||
public Map<String, Object> withdraw(Long userId, BigDecimal amount, String withdrawAddress,
|
||||
String withdrawContact, String remark) {
|
||||
String network, String withdrawContact, String remark) {
|
||||
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new RuntimeException("提现金额必须大于0");
|
||||
}
|
||||
@@ -200,6 +200,7 @@ public class FundService {
|
||||
order.setReceivableAmount(receivableAmount);
|
||||
order.setStatus(1); // 待审批
|
||||
order.setWalletAddress(withdrawAddress);
|
||||
order.setNetwork(network);
|
||||
order.setWithdrawContact(withdrawContact);
|
||||
order.setRemark(remark);
|
||||
order.setCreateTime(LocalDateTime.now());
|
||||
|
||||
Reference in New Issue
Block a user