فهرست منبع

feat: 新增PlatformPointsService管理CF值余额与流水

Xiaogang Liao 1 ماه پیش
والد
کامیت
48d5d3fe1f
1فایلهای تغییر یافته به همراه188 افزوده شده و 0 حذف شده
  1. 188 0
      cfc-backend/src/main/java/com/etotem/cfc/service/PlatformPointsService.java

+ 188 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/PlatformPointsService.java

@@ -0,0 +1,188 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.etotem.cfc.entity.PlatformBalanceLog;
+import com.etotem.cfc.entity.UserPlatformBalance;
+import com.etotem.cfc.mapper.PlatformBalanceLogMapper;
+import com.etotem.cfc.mapper.UserPlatformBalanceMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class PlatformPointsService {
+
+    private static final String TYPE_EARN = "earn";
+    private static final String TYPE_SPEND = "spend";
+    private static final String TYPE_FREEZE = "freeze";
+    private static final String TYPE_UNFREEZE = "unfreeze";
+    private static final String TYPE_WITHDRAW = "withdraw";
+
+    @Resource
+    private UserPlatformBalanceMapper balanceMapper;
+
+    @Resource
+    private PlatformBalanceLogMapper logMapper;
+
+    /** 获取或创建用户的 CF 值余额记录 */
+    private UserPlatformBalance getOrCreate(Long userId) {
+        UserPlatformBalance balance = balanceMapper.selectOne(
+                new LambdaQueryWrapper<UserPlatformBalance>()
+                        .eq(UserPlatformBalance::getUserId, userId));
+        if (balance == null) {
+            balance = new UserPlatformBalance();
+            balance.setUserId(userId);
+            balance.setTotalEarned(0);
+            balance.setAvailable(0);
+            balance.setFrozen(0);
+            balance.setWithdrawn(0);
+            balance.setExchanged(0);
+            balance.setCreatedAt(new Date());
+            balance.setUpdatedAt(new Date());
+            balanceMapper.insert(balance);
+        }
+        return balance;
+    }
+
+    private int safeInt(Integer v) {
+        return v == null ? 0 : v;
+    }
+
+    private void writeLog(Long userId, Long familyId, String type, int amount,
+                          int balanceAfter, String refType, Long refId, String remark) {
+        PlatformBalanceLog log = new PlatformBalanceLog();
+        log.setUserId(userId);
+        log.setFamilyId(familyId);
+        log.setType(type);
+        log.setAmount(amount);
+        log.setBalanceAfter(balanceAfter);
+        log.setRefType(refType);
+        log.setRefId(refId);
+        log.setRemark(remark);
+        log.setCreatedAt(new Date());
+        logMapper.insert(log);
+    }
+
+    /** 用户获得 CF 值 */
+    @Transactional
+    public void earn(Long userId, int amount, String refType, Long refId, String remark) {
+        if (amount <= 0) {
+            throw new IllegalArgumentException("CF值数量必须为正数");
+        }
+        UserPlatformBalance b = getOrCreate(userId);
+        b.setTotalEarned(safeInt(b.getTotalEarned()) + amount);
+        b.setAvailable(safeInt(b.getAvailable()) + amount);
+        b.setUpdatedAt(new Date());
+        balanceMapper.updateById(b);
+        writeLog(userId, b.getFamilyId(), TYPE_EARN, amount, safeInt(b.getAvailable()),
+                refType, refId, remark);
+    }
+
+    /** 消费可用 CF 值(兑换等),余额不足抛异常 */
+    @Transactional
+    public void spend(Long userId, int amount, String refType, Long refId, String remark) {
+        if (amount <= 0) {
+            throw new IllegalArgumentException("CF值数量必须为正数");
+        }
+        UserPlatformBalance b = getOrCreate(userId);
+        int available = safeInt(b.getAvailable());
+        if (available < amount) {
+            throw new RuntimeException("CF值余额不足");
+        }
+        b.setAvailable(available - amount);
+        b.setExchanged(safeInt(b.getExchanged()) + amount);
+        b.setUpdatedAt(new Date());
+        balanceMapper.updateById(b);
+        writeLog(userId, b.getFamilyId(), TYPE_SPEND, amount, safeInt(b.getAvailable()),
+                refType, refId, remark);
+    }
+
+    /** 提现申请:可用 → 冻结 */
+    @Transactional
+    public void freeze(Long userId, int amount, Long refId) {
+        if (amount <= 0) {
+            throw new IllegalArgumentException("CF值数量必须为正数");
+        }
+        UserPlatformBalance b = getOrCreate(userId);
+        int available = safeInt(b.getAvailable());
+        if (available < amount) {
+            throw new RuntimeException("CF值余额不足");
+        }
+        b.setAvailable(available - amount);
+        b.setFrozen(safeInt(b.getFrozen()) + amount);
+        b.setUpdatedAt(new Date());
+        balanceMapper.updateById(b);
+        writeLog(userId, b.getFamilyId(), TYPE_FREEZE, amount, safeInt(b.getAvailable()),
+                "withdrawal", refId, "提现冻结");
+    }
+
+    /** 提现审核拒绝:冻结 → 可用 */
+    @Transactional
+    public void unfreeze(Long userId, int amount, Long refId) {
+        if (amount <= 0) {
+            throw new IllegalArgumentException("CF值数量必须为正数");
+        }
+        UserPlatformBalance b = getOrCreate(userId);
+        int frozen = safeInt(b.getFrozen());
+        if (frozen < amount) {
+            throw new RuntimeException("冻结CF值不足");
+        }
+        b.setFrozen(frozen - amount);
+        b.setAvailable(safeInt(b.getAvailable()) + amount);
+        b.setUpdatedAt(new Date());
+        balanceMapper.updateById(b);
+        writeLog(userId, b.getFamilyId(), TYPE_UNFREEZE, amount, safeInt(b.getAvailable()),
+                "withdrawal", refId, "提现审核拒绝解冻");
+    }
+
+    /** 提现审核通过:冻结 → 已提现 */
+    @Transactional
+    public void confirmWithdraw(Long userId, int amount, Long refId) {
+        if (amount <= 0) {
+            throw new IllegalArgumentException("CF值数量必须为正数");
+        }
+        UserPlatformBalance b = getOrCreate(userId);
+        int frozen = safeInt(b.getFrozen());
+        if (frozen < amount) {
+            throw new RuntimeException("冻结CF值不足");
+        }
+        b.setFrozen(frozen - amount);
+        b.setWithdrawn(safeInt(b.getWithdrawn()) + amount);
+        b.setUpdatedAt(new Date());
+        balanceMapper.updateById(b);
+        writeLog(userId, b.getFamilyId(), TYPE_WITHDRAW, amount, safeInt(b.getAvailable()),
+                "withdrawal", refId, "提现成功");
+    }
+
+    /** 查询用户 CF 值余额 */
+    public Map<String, Object> getBalance(Long userId) {
+        UserPlatformBalance b = getOrCreate(userId);
+        Map<String, Object> result = new HashMap<>();
+        result.put("available", safeInt(b.getAvailable()));
+        result.put("frozen", safeInt(b.getFrozen()));
+        result.put("withdrawn", safeInt(b.getWithdrawn()));
+        result.put("exchanged", safeInt(b.getExchanged()));
+        result.put("totalEarned", safeInt(b.getTotalEarned()));
+        return result;
+    }
+
+    /** 查询可提现余额 */
+    public Integer getWithdrawable(Long userId) {
+        UserPlatformBalance b = getOrCreate(userId);
+        return safeInt(b.getAvailable());
+    }
+
+    /** CF 值流水分页 */
+    public Page<PlatformBalanceLog> getLogs(Long userId, Integer page, Integer size) {
+        Page<PlatformBalanceLog> pageParam = new Page<>(page, size);
+        return logMapper.selectPage(pageParam,
+                new LambdaQueryWrapper<PlatformBalanceLog>()
+                        .eq(PlatformBalanceLog::getUserId, userId)
+                        .orderByDesc(PlatformBalanceLog::getCreatedAt));
+    }
+}