package com.punchsettle.server.service.manager.impl; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import com.punchsettle.server.atomic.entity.Account; import com.punchsettle.server.atomic.entity.AccountTransferHistory; import com.punchsettle.server.atomic.service.IAccountService; import com.punchsettle.server.atomic.service.IAccountTransferHistoryService; import com.punchsettle.server.common.exception.BusinessException; import com.punchsettle.server.common.utils.Assert; import com.punchsettle.server.constant.AccountCategoryEnum; import com.punchsettle.server.constant.CacheNameConstant; import com.punchsettle.server.constant.TransferCategoryEnum; import com.punchsettle.server.pojo.account.AccountInfoVO; import com.punchsettle.server.pojo.account.AccountQuery; import com.punchsettle.server.pojo.account.AccountRequest; import com.punchsettle.server.pojo.account.AccountVO; import com.punchsettle.server.pojo.account.TransferHistoryVO; import com.punchsettle.server.pojo.account.TransferRequest; import com.punchsettle.server.service.manager.IAccountManager; import com.punchsettle.server.service.manager.ICacheManager; import com.punchsettle.server.utiis.DateUtils; import com.punchsettle.server.utiis.UserUtils; import lombok.extern.slf4j.Slf4j; /** * @author tyuio * @version 1.0.0 * @date 2025/4/24 17:40 * @description 账户 服务类 */ @Slf4j @Component public class AccountManagerImpl implements IAccountManager { @Autowired private IAccountService accountService; @Autowired private IAccountTransferHistoryService accountTransferHistoryService; @Autowired private ICacheManager cacheManager; @Override @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_INFO_VO, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()") public AccountInfoVO queryAccountInfo() { AccountInfoVO accountInfoVO = new AccountInfoVO(); accountInfoVO.setAccountNum(0); // 查询账户数据 AccountQuery accountQuery = new AccountQuery(); accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId())); List accounts = accountService.getAccountByCondition(accountQuery); if (CollectionUtils.isEmpty(accounts)) { return accountInfoVO; } // 设置基本户 accounts.stream().filter(v -> AccountCategoryEnum.BASIC.equals(v.getAccountCategory())).findFirst().ifPresent(account -> { AccountVO accountVO = new AccountVO(); BeanUtils.copyProperties(account, accountVO); accountInfoVO.setBasicAccount(accountVO); }); // 设置一般户 List generalAccounts = accounts.stream().filter(v -> AccountCategoryEnum.GENERAL.equals(v.getAccountCategory())).map(account -> { AccountVO accountVO = new AccountVO(); BeanUtils.copyProperties(account, accountVO); return accountVO; }).collect(Collectors.toList()); accountInfoVO.setGeneralAccountList(generalAccounts); return accountInfoVO; } @Override @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_LIST, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()") public List queryAccountList() { // 查询账户数据 AccountQuery accountQuery = new AccountQuery(); accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId())); List accounts = accountService.getAccountByCondition(accountQuery); if (CollectionUtils.isEmpty(accounts)) { return List.of(); } return accounts.stream().map(account -> { AccountVO accountVO = new AccountVO(); BeanUtils.copyProperties(account, accountVO); return accountVO; }).collect(Collectors.toList()); } @Override public AccountVO queryAccount(Long id) { Assert.isNullInBusiness(id, "账户ID不能为空"); // 查询账户 Account account = Optional.ofNullable(accountService.getById(id)).orElseThrow(() -> BusinessException.fail("待查询账户不存在")); AccountVO accountVO = new AccountVO(); BeanUtils.copyProperties(account, accountVO); return accountVO; } @Override public void saveAccount(AccountRequest request) { Assert.isNullInBusiness(request, "账户名称不能为空"); Long userId = UserUtils.getCurrentUserId(); // 新账户则创建 if (Objects.isNull(request.getId())) { Account addAccount = new Account(); addAccount.setAccountCategory(AccountCategoryEnum.GENERAL); addAccount.setUserId(userId); addAccount.setPoints(0); addAccount.setAccountName(request.getAccountName()); accountService.insert(addAccount); return; } // 否则更新 Account account = Optional.ofNullable(accountService.getById(request.getId())).orElseThrow(() -> BusinessException.fail("待更新账户不存在")); Account updateAccount = new Account(); updateAccount.setId(account.getId()); updateAccount.setAccountName(request.getAccountName()); accountService.batchUpdate(Arrays.asList(updateAccount)); // 清理缓存 clearCache(userId); } @Override public void deleteAccount(Long id) { Assert.isNullInBusiness(id, "待删除账户ID不能为空"); // 获取账户信息 Account account = Optional.ofNullable(accountService.getById(id)).orElseThrow(() -> BusinessException.fail("待删除账户不存在")); // 账户中还有积分则不允许删除 Integer points = Optional.ofNullable(account.getPoints()).orElse(0); if (points > 0) { throw BusinessException.fail("请先清空积分后再删除"); } accountService.deleteById(id); // 清理缓存 Long userId = UserUtils.getCurrentUserId(); clearCache(userId); } @Override @Transactional(rollbackFor = Exception.class) public void transfer(TransferRequest request) { Assert.isNullInBusiness(request, "请传入转账信息"); // 当前用户ID Long userId = UserUtils.getCurrentUserId(); // 获取转出账户 Account senderAccount = Optional.ofNullable(accountService.getById(request.getSenderAccountId())).orElseThrow(() -> BusinessException.fail("转出账户不存在")); // 转出账户的积分小于转账积分则不允许转出 Integer beforeSenderAccountPoints = Optional.ofNullable(senderAccount.getPoints()).orElse(0); if (beforeSenderAccountPoints.compareTo(request.getTransferPoints()) < 0) { BusinessException.throwFail("转出账户积分不足"); } // 转出后积分 Integer afterSenderAccountPoints = beforeSenderAccountPoints - request.getTransferPoints(); // 获取转入账户 Account recipientAccount = Optional.ofNullable(accountService.getById(request.getRecipientAccountId())).orElseThrow(() -> BusinessException.fail("转入账户不存在")); Integer beforeRecipientAccountPoints = Optional.ofNullable(recipientAccount.getPoints()).orElse(0); Integer afterRecipientAccountPoints = beforeRecipientAccountPoints + request.getTransferPoints(); // 转账记录 新增 AccountTransferHistory accountTransferHistory = new AccountTransferHistory(); accountTransferHistory.setUserId(userId); accountTransferHistory.setSenderAccountId(request.getSenderAccountId()); accountTransferHistory.setRecipientAccountId(request.getRecipientAccountId()); accountTransferHistory.setTransferCategory(TransferCategoryEnum.TRANSFER); accountTransferHistory.setTransferPoints(request.getTransferPoints()); accountTransferHistory.setSaPointsBeforeTransfer(beforeSenderAccountPoints); accountTransferHistory.setSaPointsAfterTransfer(afterSenderAccountPoints); accountTransferHistory.setRaPointsBeforeTransfer(beforeRecipientAccountPoints); accountTransferHistory.setRaPointsAfterTransfer(afterRecipientAccountPoints); accountTransferHistoryService.insertList(Arrays.asList(accountTransferHistory)); // 转出账户和转入账户 更新 Account updateSenderAccount = new Account(); updateSenderAccount.setId(senderAccount.getId()); updateSenderAccount.setPoints(afterSenderAccountPoints); Account updateRecipientAccount = new Account(); updateRecipientAccount.setId(recipientAccount.getId()); updateRecipientAccount.setPoints(afterRecipientAccountPoints); accountService.batchUpdate(Arrays.asList(updateSenderAccount, updateRecipientAccount)); // 清理缓存 clearCache(userId); } @Override @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_TRANSFER_HISTORY, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()+'_'+#transferMonth", condition = "#transferMonth != null && !#transferMonth.isBlank()") public List queryTransferHistory(String transferMonth) { Assert.isNullInBusiness(transferMonth, "转账月份不能为空"); List accountTransferHistories = accountTransferHistoryService.queryTransferHistory(UserUtils.getCurrentUserId(), transferMonth); if (CollectionUtils.isEmpty(accountTransferHistories)) { return List.of(); } // 查询账户 AccountQuery accountQuery = new AccountQuery(); accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId())); List accounts = accountService.getAccountByCondition(accountQuery); Map accountMap = accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity(), (key1, key2) -> key1)); // 日期格式化器,格式:yyyy-MM-dd HH:mm:ss SimpleDateFormat sdf = DateUtils.buildDateTimeFormat(); return accountTransferHistories.stream().map(accountTransferHistory -> { TransferHistoryVO transferHistoryVO = new TransferHistoryVO(); BeanUtils.copyProperties(accountTransferHistory, transferHistoryVO); transferHistoryVO.setTransferTime(sdf.format(accountTransferHistory.getCreationTime())); Account senderAccount = accountMap.get(accountTransferHistory.getSenderAccountId()); if (Objects.nonNull(senderAccount)) { transferHistoryVO.setSenderAccountName(senderAccount.getAccountName()); } Account recipientAccount = accountMap.get(accountTransferHistory.getRecipientAccountId()); if (Objects.nonNull(recipientAccount)) { transferHistoryVO.setRecipientAccountName(recipientAccount.getAccountName()); } return transferHistoryVO; }).collect(Collectors.toList()); } @Override @Transactional(rollbackFor = Exception.class) public void createBasicAccount(Long userId) { Account account = new Account(); account.setUserId(userId); account.setPoints(0); account.setAccountName("基本账户"); account.setAccountCategory(AccountCategoryEnum.BASIC); accountService.insert(account); } @Override public void clearCache(Long userId) { cacheManager.batchEvict(Arrays.asList(CacheNameConstant.ACCOUNT_INFO_VO, CacheNameConstant.ACCOUNT_LIST), userId); cacheManager.batchEvictLike(Arrays.asList(CacheNameConstant.ACCOUNT_TRANSFER_HISTORY), String.valueOf(userId)); } }