From 41c1288616ca6fcd6d5ae19371795f44124b2fe2 Mon Sep 17 00:00:00 2001 From: sion Date: Sun, 29 Mar 2026 16:15:07 +0800 Subject: [PATCH] 111 --- .../lib/data/services/bonus_service.dart | 28 ++++++ .../monisuo/controller/BonusController.java | 48 +++++++++ .../rattan/monisuo/service/BonusService.java | 98 +++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 flutter_monisuo/lib/data/services/bonus_service.dart create mode 100644 src/main/java/com/it/rattan/monisuo/controller/BonusController.java create mode 100644 src/main/java/com/it/rattan/monisuo/service/BonusService.java diff --git a/flutter_monisuo/lib/data/services/bonus_service.dart b/flutter_monisuo/lib/data/services/bonus_service.dart new file mode 100644 index 0000000..a72e581 --- /dev/null +++ b/flutter_monisuo/lib/data/services/bonus_service.dart @@ -0,0 +1,28 @@ +import '../../core/constants/api_endpoints.dart'; +import '../../core/network/api_response.dart'; +import '../../core/network/dio_client.dart'; + +/// 福利服务 +class BonusService { + final DioClient _client; + + BonusService(this._client); + + /// 查询新人福利状态 + Future>> getStatus() async { + final response = await _client.get>( + ApiEndpoints.bonusStatus, + ); + if (response.success && response.data != null) { + return ApiResponse.success(response.data!, response.message); + } + return ApiResponse.fail(response.message ?? '获取福利状态失败'); + } + + /// 领取新人福利 + Future>> claim() async { + return _client.post>( + ApiEndpoints.bonusClaim, + ); + } +} diff --git a/src/main/java/com/it/rattan/monisuo/controller/BonusController.java b/src/main/java/com/it/rattan/monisuo/controller/BonusController.java new file mode 100644 index 0000000..1f9835c --- /dev/null +++ b/src/main/java/com/it/rattan/monisuo/controller/BonusController.java @@ -0,0 +1,48 @@ +package com.it.rattan.monisuo.controller; + +import com.it.rattan.monisuo.common.Result; +import com.it.rattan.monisuo.context.UserContext; +import com.it.rattan.monisuo.service.BonusService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * 福利接口 + */ +@RestController +@RequestMapping("/api/bonus") +public class BonusController { + + @Autowired + private BonusService bonusService; + + /** + * 查询是否已领取新人福利 + */ + @GetMapping("/status") + public Result> getStatus() { + Long userId = UserContext.getUserId(); + if (userId == null) { + return Result.unauthorized("请先登录"); + } + return Result.success(bonusService.getStatus(userId)); + } + + /** + * 领取新人福利 + */ + @PostMapping("/claim") + public Result> claim() { + Long userId = UserContext.getUserId(); + if (userId == null) { + return Result.unauthorized("请先登录"); + } + try { + return Result.success(bonusService.claim(userId)); + } catch (Exception e) { + return Result.fail(e.getMessage()); + } + } +} diff --git a/src/main/java/com/it/rattan/monisuo/service/BonusService.java b/src/main/java/com/it/rattan/monisuo/service/BonusService.java new file mode 100644 index 0000000..434afa2 --- /dev/null +++ b/src/main/java/com/it/rattan/monisuo/service/BonusService.java @@ -0,0 +1,98 @@ +package com.it.rattan.monisuo.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.it.rattan.monisuo.entity.AccountFlow; +import com.it.rattan.monisuo.entity.AccountFund; +import com.it.rattan.monisuo.mapper.AccountFlowMapper; +import com.it.rattan.monisuo.mapper.AccountFundMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * 福利服务 + */ +@Service +public class BonusService { + + private static final BigDecimal BONUS_AMOUNT = new BigDecimal("50"); + private static final String BONUS_REMARK = "新人福利"; + + @Autowired + private AccountFundMapper accountFundMapper; + + @Autowired + private AccountFlowMapper accountFlowMapper; + + @Autowired + private AssetService assetService; + + /** + * 查询领取状态 + */ + public Map getStatus(Long userId) { + Map result = new HashMap<>(); + result.put("amount", BONUS_AMOUNT); + result.put("claimed", hasClaimed(userId)); + return result; + } + + /** + * 领取新人福利 + */ + @Transactional(rollbackFor = Exception.class) + public Map claim(Long userId) { + // 检查是否已领取 + if (hasClaimed(userId)) { + throw new RuntimeException("您已领取过新人福利"); + } + + // 获取资金账户 + AccountFund fund = assetService.getOrCreateFundAccount(userId); + BigDecimal balanceBefore = fund.getBalance(); + BigDecimal balanceAfter = balanceBefore.add(BONUS_AMOUNT); + + // 更新余额 + fund.setBalance(balanceAfter); + fund.setTotalDeposit(fund.getTotalDeposit().add(BONUS_AMOUNT)); + accountFundMapper.update(null, new LambdaUpdateWrapper() + .eq(AccountFund::getId, fund.getId()) + .set(AccountFund::getBalance, balanceAfter) + .set(AccountFund::getTotalDeposit, fund.getTotalDeposit()) + .set(AccountFund::getUpdateTime, LocalDateTime.now())); + + // 记录流水 + AccountFlow flow = new AccountFlow(); + flow.setUserId(userId); + flow.setFlowNo(com.it.rattan.monisuo.util.OrderNoUtil.flowNo()); + flow.setFlowType(1); // 充值类型 + flow.setAmount(BONUS_AMOUNT); + flow.setBalanceBefore(balanceBefore); + flow.setBalanceAfter(balanceAfter); + flow.setCoinCode("USDT"); + flow.setRemark(BONUS_REMARK); + flow.setCreateTime(LocalDateTime.now()); + accountFlowMapper.insert(flow); + + Map result = new HashMap<>(); + result.put("amount", BONUS_AMOUNT); + result.put("balance", balanceAfter); + return result; + } + + /** + * 检查是否已领取(通过流水记录判断) + */ + private boolean hasClaimed(Long userId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(AccountFlow::getUserId, userId) + .eq(AccountFlow::getRemark, BONUS_REMARK); + return accountFlowMapper.selectCount(wrapper) > 0; + } +}