AccountManagerImpl.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. package com.punchsettle.server.service.manager.impl;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Objects;
  7. import java.util.Optional;
  8. import java.util.function.Function;
  9. import java.util.stream.Collectors;
  10. import org.springframework.beans.BeanUtils;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.cache.annotation.Cacheable;
  13. import org.springframework.stereotype.Component;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import org.springframework.util.CollectionUtils;
  16. import com.punchsettle.server.atomic.entity.Account;
  17. import com.punchsettle.server.atomic.entity.AccountTransferHistory;
  18. import com.punchsettle.server.atomic.service.IAccountService;
  19. import com.punchsettle.server.atomic.service.IAccountTransferHistoryService;
  20. import com.punchsettle.server.common.exception.BusinessException;
  21. import com.punchsettle.server.common.utils.Assert;
  22. import com.punchsettle.server.constant.AccountCategoryEnum;
  23. import com.punchsettle.server.constant.CacheNameConstant;
  24. import com.punchsettle.server.constant.TransferCategoryEnum;
  25. import com.punchsettle.server.pojo.account.AccountInfoVO;
  26. import com.punchsettle.server.pojo.account.AccountQuery;
  27. import com.punchsettle.server.pojo.account.AccountRequest;
  28. import com.punchsettle.server.pojo.account.AccountVO;
  29. import com.punchsettle.server.pojo.account.TransferHistoryVO;
  30. import com.punchsettle.server.pojo.account.TransferRequest;
  31. import com.punchsettle.server.service.manager.IAccountManager;
  32. import com.punchsettle.server.service.manager.ICacheManager;
  33. import com.punchsettle.server.utiis.DateUtils;
  34. import com.punchsettle.server.utiis.UserUtils;
  35. import lombok.extern.slf4j.Slf4j;
  36. /**
  37. * @author tyuio
  38. * @version 1.0.0
  39. * @date 2025/4/24 17:40
  40. * @description 账户 服务类
  41. */
  42. @Slf4j
  43. @Component
  44. public class AccountManagerImpl implements IAccountManager {
  45. @Autowired
  46. private IAccountService accountService;
  47. @Autowired
  48. private IAccountTransferHistoryService accountTransferHistoryService;
  49. @Autowired
  50. private ICacheManager cacheManager;
  51. @Override
  52. @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_INFO_VO, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()")
  53. public AccountInfoVO queryAccountInfo() {
  54. AccountInfoVO accountInfoVO = new AccountInfoVO();
  55. accountInfoVO.setAccountNum(0);
  56. // 查询账户数据
  57. AccountQuery accountQuery = new AccountQuery();
  58. accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId()));
  59. List<Account> accounts = accountService.getAccountByCondition(accountQuery);
  60. if (CollectionUtils.isEmpty(accounts)) {
  61. return accountInfoVO;
  62. }
  63. // 设置基本户
  64. accounts.stream().filter(v -> AccountCategoryEnum.BASIC.equals(v.getAccountCategory())).findFirst().ifPresent(account -> {
  65. AccountVO accountVO = new AccountVO();
  66. BeanUtils.copyProperties(account, accountVO);
  67. accountInfoVO.setBasicAccount(accountVO);
  68. });
  69. // 设置一般户
  70. List<AccountVO> generalAccounts = accounts.stream().filter(v -> AccountCategoryEnum.GENERAL.equals(v.getAccountCategory())).map(account -> {
  71. AccountVO accountVO = new AccountVO();
  72. BeanUtils.copyProperties(account, accountVO);
  73. return accountVO;
  74. }).collect(Collectors.toList());
  75. accountInfoVO.setGeneralAccountList(generalAccounts);
  76. return accountInfoVO;
  77. }
  78. @Override
  79. @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_LIST, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()")
  80. public List<AccountVO> queryAccountList() {
  81. // 查询账户数据
  82. AccountQuery accountQuery = new AccountQuery();
  83. accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId()));
  84. List<Account> accounts = accountService.getAccountByCondition(accountQuery);
  85. if (CollectionUtils.isEmpty(accounts)) {
  86. return List.of();
  87. }
  88. return accounts.stream().map(account -> {
  89. AccountVO accountVO = new AccountVO();
  90. BeanUtils.copyProperties(account, accountVO);
  91. return accountVO;
  92. }).collect(Collectors.toList());
  93. }
  94. @Override
  95. public AccountVO queryAccount(Long id) {
  96. Assert.isNullInBusiness(id, "账户ID不能为空");
  97. // 查询账户
  98. Account account = Optional.ofNullable(accountService.getById(id)).orElseThrow(() -> BusinessException.fail("待查询账户不存在"));
  99. AccountVO accountVO = new AccountVO();
  100. BeanUtils.copyProperties(account, accountVO);
  101. return accountVO;
  102. }
  103. @Override
  104. public void saveAccount(AccountRequest request) {
  105. Assert.isNullInBusiness(request, "账户名称不能为空");
  106. Long userId = UserUtils.getCurrentUserId();
  107. // 新账户则创建
  108. if (Objects.isNull(request.getId())) {
  109. Account addAccount = new Account();
  110. addAccount.setAccountCategory(AccountCategoryEnum.GENERAL);
  111. addAccount.setUserId(userId);
  112. addAccount.setPoints(0);
  113. addAccount.setAccountName(request.getAccountName());
  114. accountService.insert(addAccount);
  115. return;
  116. }
  117. // 否则更新
  118. Account account = Optional.ofNullable(accountService.getById(request.getId())).orElseThrow(() -> BusinessException.fail("待更新账户不存在"));
  119. Account updateAccount = new Account();
  120. updateAccount.setId(account.getId());
  121. updateAccount.setAccountName(request.getAccountName());
  122. accountService.batchUpdate(Arrays.asList(updateAccount));
  123. // 清理缓存
  124. clearCache(userId);
  125. }
  126. @Override
  127. public void deleteAccount(Long id) {
  128. Assert.isNullInBusiness(id, "待删除账户ID不能为空");
  129. // 获取账户信息
  130. Account account = Optional.ofNullable(accountService.getById(id)).orElseThrow(() -> BusinessException.fail("待删除账户不存在"));
  131. // 账户中还有积分则不允许删除
  132. Integer points = Optional.ofNullable(account.getPoints()).orElse(0);
  133. if (points > 0) {
  134. throw BusinessException.fail("请先清空积分后再删除");
  135. }
  136. accountService.deleteById(id);
  137. // 清理缓存
  138. Long userId = UserUtils.getCurrentUserId();
  139. clearCache(userId);
  140. }
  141. @Override
  142. @Transactional(rollbackFor = Exception.class)
  143. public void transfer(TransferRequest request) {
  144. Assert.isNullInBusiness(request, "请传入转账信息");
  145. // 当前用户ID
  146. Long userId = UserUtils.getCurrentUserId();
  147. // 获取转出账户
  148. Account senderAccount = Optional.ofNullable(accountService.getById(request.getSenderAccountId())).orElseThrow(() -> BusinessException.fail("转出账户不存在"));
  149. // 转出账户的积分小于转账积分则不允许转出
  150. Integer beforeSenderAccountPoints = Optional.ofNullable(senderAccount.getPoints()).orElse(0);
  151. if (beforeSenderAccountPoints.compareTo(request.getTransferPoints()) < 0) {
  152. BusinessException.throwFail("转出账户积分不足");
  153. }
  154. // 转出后积分
  155. Integer afterSenderAccountPoints = beforeSenderAccountPoints - request.getTransferPoints();
  156. // 获取转入账户
  157. Account recipientAccount = Optional.ofNullable(accountService.getById(request.getRecipientAccountId())).orElseThrow(() -> BusinessException.fail("转入账户不存在"));
  158. Integer beforeRecipientAccountPoints = Optional.ofNullable(recipientAccount.getPoints()).orElse(0);
  159. Integer afterRecipientAccountPoints = beforeRecipientAccountPoints + request.getTransferPoints();
  160. // 转账记录 新增
  161. AccountTransferHistory accountTransferHistory = new AccountTransferHistory();
  162. accountTransferHistory.setUserId(userId);
  163. accountTransferHistory.setSenderAccountId(request.getSenderAccountId());
  164. accountTransferHistory.setRecipientAccountId(request.getRecipientAccountId());
  165. accountTransferHistory.setTransferCategory(TransferCategoryEnum.TRANSFER);
  166. accountTransferHistory.setTransferPoints(request.getTransferPoints());
  167. accountTransferHistory.setSaPointsBeforeTransfer(beforeSenderAccountPoints);
  168. accountTransferHistory.setSaPointsAfterTransfer(afterSenderAccountPoints);
  169. accountTransferHistory.setRaPointsBeforeTransfer(beforeRecipientAccountPoints);
  170. accountTransferHistory.setRaPointsAfterTransfer(afterRecipientAccountPoints);
  171. accountTransferHistoryService.insertList(Arrays.asList(accountTransferHistory));
  172. // 转出账户和转入账户 更新
  173. Account updateSenderAccount = new Account();
  174. updateSenderAccount.setId(senderAccount.getId());
  175. updateSenderAccount.setPoints(afterSenderAccountPoints);
  176. Account updateRecipientAccount = new Account();
  177. updateRecipientAccount.setId(recipientAccount.getId());
  178. updateRecipientAccount.setPoints(afterRecipientAccountPoints);
  179. accountService.batchUpdate(Arrays.asList(updateSenderAccount, updateRecipientAccount));
  180. // 清理缓存
  181. clearCache(userId);
  182. }
  183. @Override
  184. @Cacheable(cacheNames = CacheNameConstant.ACCOUNT_TRANSFER_HISTORY, key = "T(com.punchsettle.server.utiis.UserUtils).getCurrentUserId()+'_'+#transferMonth", condition = "#transferMonth != null && !#transferMonth.isBlank()")
  185. public List<TransferHistoryVO> queryTransferHistory(String transferMonth) {
  186. Assert.isNullInBusiness(transferMonth, "转账月份不能为空");
  187. List<AccountTransferHistory> accountTransferHistories = accountTransferHistoryService.queryTransferHistory(UserUtils.getCurrentUserId(), transferMonth);
  188. if (CollectionUtils.isEmpty(accountTransferHistories)) {
  189. return List.of();
  190. }
  191. // 查询账户
  192. AccountQuery accountQuery = new AccountQuery();
  193. accountQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId()));
  194. List<Account> accounts = accountService.getAccountByCondition(accountQuery);
  195. Map<Long, Account> accountMap = accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity(), (key1, key2) -> key1));
  196. // 日期格式化器,格式:yyyy-MM-dd HH:mm:ss
  197. SimpleDateFormat sdf = DateUtils.buildDateTimeFormat();
  198. return accountTransferHistories.stream().map(accountTransferHistory -> {
  199. TransferHistoryVO transferHistoryVO = new TransferHistoryVO();
  200. BeanUtils.copyProperties(accountTransferHistory, transferHistoryVO);
  201. transferHistoryVO.setTransferTime(sdf.format(accountTransferHistory.getCreationTime()));
  202. Account senderAccount = accountMap.get(accountTransferHistory.getSenderAccountId());
  203. if (Objects.nonNull(senderAccount)) {
  204. transferHistoryVO.setSenderAccountName(senderAccount.getAccountName());
  205. }
  206. Account recipientAccount = accountMap.get(accountTransferHistory.getRecipientAccountId());
  207. if (Objects.nonNull(recipientAccount)) {
  208. transferHistoryVO.setRecipientAccountName(recipientAccount.getAccountName());
  209. }
  210. return transferHistoryVO;
  211. }).collect(Collectors.toList());
  212. }
  213. @Override
  214. @Transactional(rollbackFor = Exception.class)
  215. public void createBasicAccount(Long userId) {
  216. Account account = new Account();
  217. account.setUserId(userId);
  218. account.setPoints(0);
  219. account.setAccountName("基本账户");
  220. account.setAccountCategory(AccountCategoryEnum.BASIC);
  221. accountService.insert(account);
  222. }
  223. @Override
  224. public void clearCache(Long userId) {
  225. cacheManager.batchEvict(Arrays.asList(CacheNameConstant.ACCOUNT_INFO_VO, CacheNameConstant.ACCOUNT_LIST), userId);
  226. cacheManager.batchEvictLike(Arrays.asList(CacheNameConstant.ACCOUNT_TRANSFER_HISTORY), String.valueOf(userId));
  227. }
  228. }