From 069e411dc42bd7a01cb869e84ac3e6a7690cd9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Thu, 14 Mar 2024 00:29:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E6=8E=A5=E9=93=B6=E8=A1=8C?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=8D=B3=E5=B0=86?= =?UTF-8?q?=E4=B8=8A=E7=BA=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dtos/Bank/BankCardDto.cs | 45 ++++++++ .../Dtos/Bank/InterestRecordsDto.cs | 25 +++++ .../Services/Bank/BankService.cs | 78 ++++++++++++-- .../Etos/MoneyChangeEventArgs.cs | 3 + .../Entities/Bank/BankCardEntity.cs | 50 ++++++++- .../Entities/Bank/InterestRecordsEntity.cs | 4 +- .../Managers/BankManager.cs | 101 +++++++++++++++--- Yi.Bbs.Vue3/src/apis/bankApi.js | 43 ++++++++ Yi.Bbs.Vue3/src/main.js | 3 +- Yi.Bbs.Vue3/src/views/bank/Index.vue | 101 +++++++++++------- 10 files changed, 387 insertions(+), 66 deletions(-) create mode 100644 Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/BankCardDto.cs create mode 100644 Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/InterestRecordsDto.cs create mode 100644 Yi.Bbs.Vue3/src/apis/bankApi.js diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/BankCardDto.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/BankCardDto.cs new file mode 100644 index 00000000..8e0fe990 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/BankCardDto.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Yi.Framework.Bbs.Domain.Shared.Enums; + +namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Bank +{ + public class BankCardDto:EntityDto + { + + public DateTime? LastDepositTime { get; set; } + public DateTime CreationTime { get; set; } + + /// + /// 用户id + /// + public Guid UserId { get; set; } + + /// + /// 当前存储的钱 + /// + public decimal StorageMoney { get; set; } + + + /// + /// 最大可存储的钱钱 + /// + public decimal MaxStorageMoney { get; set; } + + + /// + /// 满期限时间,可空 + /// + public DateTime? Fullterm { get; set; } + + /// + /// 银行卡状态 + /// + public BankCardStateEnum BankCardState { get; set; } = BankCardStateEnum.Unused; + + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/InterestRecordsDto.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/InterestRecordsDto.cs new file mode 100644 index 00000000..c27d5554 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Bank/InterestRecordsDto.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Bank +{ + public class InterestRecordsDto : EntityDto + { + public DateTime CreationTime { get; set; } + + /// + /// 当前汇率值 + /// + public decimal Value { get; set; } + + /// + /// 是否波动期 + /// + public bool IsFluctuate { get; set; } + + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Bank/BankService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Bank/BankService.cs index 45b58c76..9f99fa92 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Bank/BankService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Bank/BankService.cs @@ -1,20 +1,51 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Mapster; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Volo.Abp.Application.Services; +using Yi.Framework.Bbs.Application.Contracts.Dtos.Bank; +using Yi.Framework.Bbs.Domain.Entities.Bank; using Yi.Framework.Bbs.Domain.Managers; +using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Bbs.Application.Services.Bank { public class BankService : ApplicationService { private BankManager _bankManager; - public BankService(BankManager bankManager) + private BbsUserManager _bbsUserManager; + private ISqlSugarRepository _repository; + private ISqlSugarRepository _interestRepository; + public BankService(BankManager bankManager, BbsUserManager userManager, ISqlSugarRepository repository, ISqlSugarRepository interestRepository) { _bankManager = bankManager; + _bbsUserManager = userManager; + _repository = repository; + _interestRepository = interestRepository; + } + + /// + /// 获取最近24小时汇率记录 + /// + /// + [HttpGet("bank/interest")] + public async Task> GetInterestRecordsAsync() + { + var entities = await _interestRepository._DbQueryable.OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 24); + var output = entities.Adapt>(); + return output; + } + + /// + /// 获取登录用户全部银行卡信息 + /// + /// + [Authorize] + [HttpGet("bank")] + public async Task> GetBankCardListAsync() + { + var entities = await _repository.GetListAsync(x => x.UserId == CurrentUser.Id); + var output = entities.Adapt>(); + return output; } /// @@ -22,9 +53,21 @@ namespace Yi.Framework.Bbs.Application.Services.Bank /// /// [Authorize] - public Task ApplyingBankCardAsync() + [HttpPost("bank/applying")] + public async Task ApplyingBankCardAsync() { - return _bankManager.ApplyingBankCardAsync(CurrentUser.Id.Value); + var userInfo = await _bbsUserManager.GetBbsUserInfoAsync(CurrentUser.Id!.Value); + var banCardNum = await _repository.CountAsync(x => x.UserId == CurrentUser.Id!.Value); + + var diffNum = userInfo.Level - banCardNum; + if (diffNum <= 0) + { + throw new UserFriendlyException($"申请失败,当前等级-【{userInfo.Level}】,最多可申领-【{userInfo.Level}】张银行卡,目前已拥有-【{banCardNum}】,请提升你的等级信誉,行长会考虑的"); + } + else + { + await _bankManager.ApplyingBankCardAsync(CurrentUser.Id.Value, diffNum); + } } /// @@ -33,6 +76,7 @@ namespace Yi.Framework.Bbs.Application.Services.Bank /// /// [Authorize] + [HttpPut("bank/draw/{cardId}")] public Task DrawMoneyAsync(Guid cardId) { return _bankManager.DrawMoneyAsync(cardId); @@ -40,12 +84,24 @@ namespace Yi.Framework.Bbs.Application.Services.Bank /// /// 给银行卡存款 /// - /// + /// /// /// - public Task DepositAsync(Guid CardId, decimal moneyNum) + [Authorize] + [HttpPut("bank/deposit/{cardId}/{moneyNum}")] + public async Task DepositAsync(Guid cardId, decimal moneyNum) { - return _bankManager.DepositAsync(CardId, moneyNum); + if (moneyNum < 50) + { + throw new UserFriendlyException("存款金额不能小于50"); + } + var userInfo = await _bbsUserManager.GetBbsUserInfoAsync(CurrentUser.Id!.Value); + if (userInfo.Money < moneyNum) + { + throw new UserFriendlyException("存钱失败!你的钱钱不足,再存进去,就负数啦~"); + } + + await _bankManager.DepositAsync(cardId, moneyNum); } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/MoneyChangeEventArgs.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/MoneyChangeEventArgs.cs index 6282e70d..fd0f927d 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/MoneyChangeEventArgs.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/MoneyChangeEventArgs.cs @@ -8,6 +8,9 @@ namespace Yi.Framework.Bbs.Domain.Shared.Etos { public class MoneyChangeEventArgs { + public MoneyChangeEventArgs() { } + public MoneyChangeEventArgs(Guid userId, decimal changeNumber) { UserId = userId; Number = changeNumber; } + /// /// 用户id /// diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/BankCardEntity.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/BankCardEntity.cs index accf3343..a2e59485 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/BankCardEntity.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/BankCardEntity.cs @@ -16,10 +16,28 @@ namespace Yi.Framework.Bbs.Domain.Entities.Bank [SugarTable("BankCard")] public class BankCardEntity : Entity, IHasCreationTime { + public BankCardEntity() + { + } + + public BankCardEntity(Guid userId) + { + this.UserId = userId; + } [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] public override Guid Id { get; protected set; } public DateTime CreationTime { get; set; } + /// + /// 上一次存款日期 + /// + public DateTime? LastDepositTime { get; set; } + + /// + /// 上一次取款日期 + /// + public DateTime? LastDrawTime { get; set; } + /// /// 用户id /// @@ -40,16 +58,44 @@ namespace Yi.Framework.Bbs.Domain.Entities.Bank /// /// 满期限时间,可空 /// - public DateTime? Fullterm { get; set; } + public DateTime? FulltermTime { get; set; } + - /// /// 银行卡状态 /// public BankCardStateEnum BankCardState { get; set; } = BankCardStateEnum.Unused; + public bool IsStorageFull() + { + if (FulltermTime is null) + { + return false; + } + return DateTime.Now >= FulltermTime; + } + public void SetDrawMoney() + { + this.BankCardState = BankCardStateEnum.Unused; + LastDrawTime = DateTime.Now; + this.FulltermTime = null; + this.StorageMoney = 0; + } + public void SetStorageMoney(decimal storageMoney) + { + if (storageMoney > MaxStorageMoney) + { + throw new UserFriendlyException($"存款数不能大于该卡的上限-【{MaxStorageMoney}】钱钱"); + } + + StorageMoney = storageMoney; + + LastDepositTime = DateTime.Now; + FulltermTime = LastDepositTime + TimeSpan.FromDays(3); + this.BankCardState = BankCardStateEnum.Wait; + } } } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/InterestRecordsEntity.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/InterestRecordsEntity.cs index 601d3a80..75ab9386 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/InterestRecordsEntity.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Entities/Bank/InterestRecordsEntity.cs @@ -20,8 +20,8 @@ namespace Yi.Framework.Bbs.Domain.Entities.Bank public InterestRecordsEntity(decimal inputValue, bool isFluctuate, decimal oldValue = 0) { //这里写好根据数据的值,以及是否要波动期,进行得出真是利息 - - + //有了老值和新值,我们可以根据这个变化程度去做一个涨幅或跌幅,Todo + Value=inputValue; } [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] public override Guid Id { get; protected set; } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/BankManager.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/BankManager.cs index 21ffcdaf..7cf75891 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/BankManager.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/BankManager.cs @@ -1,13 +1,31 @@ using Volo.Abp.Domain.Services; +using Volo.Abp.EventBus.Local; using Yi.Framework.Bbs.Domain.Entities.Bank; +using Yi.Framework.Bbs.Domain.Shared.Enums; +using Yi.Framework.Bbs.Domain.Shared.Etos; +using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Bbs.Domain.Managers { public class BankManager : DomainService { + private ISqlSugarRepository _repository; + private ILocalEventBus _localEventBus; + private ISqlSugarRepository _interestRepository; + public BankManager(ISqlSugarRepository repository, ILocalEventBus localEventBus, ISqlSugarRepository interestRepository) + { + _repository = repository; + _localEventBus = localEventBus; + _interestRepository = interestRepository; + } - public BankManager() { } - + public decimal CurrentInterestRate => GetCurrentInterestRate(); + private decimal GetCurrentInterestRate() + { + //先判断时间是否与当前时间差1小时,小于1小时直接返回即可,可以由一个单例类提供 + GetThirdPartyValue(); + return 1.30m; + } /// /// 获取第三方的值 @@ -22,39 +40,96 @@ namespace Yi.Framework.Bbs.Domain.Managers /// 创建一个记录 /// /// - public InterestRecordsEntity CreateInterestRecords() + public async Task CreateInterestRecordsAsync() { - return new InterestRecordsEntity(); + //获取最新的实体 + var newEntity = await _interestRepository._DbQueryable.OrderByDescending(x => x.CreationTime).FirstAsync(); + decimal oldValue = 1.3m; + if (newEntity is not null) + { + oldValue = newEntity.Value; + } + var currentValue = GetThirdPartyValue(); + var entity = new InterestRecordsEntity(currentValue, false, oldValue); + var output = await _interestRepository.InsertReturnEntityAsync(entity); + + return output; } /// /// 给用户申请银行卡 /// /// - public Task ApplyingBankCardAsync(Guid userId) + public async Task ApplyingBankCardAsync(Guid userId, int cardNumber) { - return Task.CompletedTask; + var entities = Enumerable.Range(1, cardNumber).Select(x => new BankCardEntity(userId)).ToList(); + await _repository.InsertManyAsync(entities); } /// - /// 给银行卡提款 + /// 进行银行卡提款 /// - /// + /// /// - public Task DrawMoneyAsync(Guid CardId) + public async Task DrawMoneyAsync(Guid cardId) { - return Task.CompletedTask; + var entity = await _repository.GetByIdAsync(cardId); + if (entity.BankCardState == BankCardStateEnum.Unused) + { + throw new UserFriendlyException("当前银行卡状态不能提款"); + } + + //这里其实不存在这个状态,只有等待状态,不需要去主动触发,前端判断即可 + if (entity.BankCardState == BankCardStateEnum.Full) + { + throw new UserFriendlyException("当前银行卡状态不能存款"); + } + + //可以提款 + if (entity.BankCardState == BankCardStateEnum.Wait) + { + decimal changeMoney = 0; + //判断是否存满时间 + if (entity.IsStorageFull()) + { + changeMoney = this.CurrentInterestRate * entity.StorageMoney; + } + else + { + changeMoney = entity.StorageMoney; + } + + //提款 + entity.SetDrawMoney(); + await _repository.UpdateAsync(entity); + + //打钱,该卡状态钱更新,并提款加到用户钱钱里 + await _localEventBus.PublishAsync(new MoneyChangeEventArgs(entity.UserId, changeMoney)); + + + + } } /// /// 给银行卡存款 /// - /// + /// /// /// - public Task DepositAsync(Guid CardId, decimal moneyNum) + public async Task DepositAsync(Guid cardId, decimal moneyNum) { - return Task.CompletedTask; + var entity = await _repository.GetByIdAsync(cardId); + if (entity.BankCardState != BankCardStateEnum.Unused) + { + throw new UserFriendlyException("当前银行卡状态不能存款"); + } + //存款 + entity.SetStorageMoney(moneyNum); + + await _repository.UpdateAsync(entity); + await _localEventBus.PublishAsync(new MoneyChangeEventArgs(entity.UserId, -moneyNum)); + } } diff --git a/Yi.Bbs.Vue3/src/apis/bankApi.js b/Yi.Bbs.Vue3/src/apis/bankApi.js new file mode 100644 index 00000000..517bc4e8 --- /dev/null +++ b/Yi.Bbs.Vue3/src/apis/bankApi.js @@ -0,0 +1,43 @@ +import request from "@/config/axios/service"; + +//得到利息趋势 +export function getInterestList() { + return request({ + url: "/bank/interest", + method: "get" + }); +} + + +// 获取用户的银行卡 +export function getBankCardList() { + return request({ + url: "/bank", + method: "get", + }); +} + +// 申请银行卡 +export function applyingBankCard() { + return request({ + url: "/bank/applying", + method: "post" + }); +} + +// 提款 +export function drawMoney(cardId) { + return request({ + url: `/bank/draw/${cardId}`, + method: "put", + data: data, + }); +} + +// 存款 +export function delUser(cardId,moneyNum) { + return request({ + url: `/bank/deposit/${cardId}/${moneyNum}`, + method: "put" + }); +} diff --git a/Yi.Bbs.Vue3/src/main.js b/Yi.Bbs.Vue3/src/main.js index cc9bedfc..da231070 100644 --- a/Yi.Bbs.Vue3/src/main.js +++ b/Yi.Bbs.Vue3/src/main.js @@ -8,8 +8,7 @@ import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import "element-plus/dist/index.css"; import "./assets/main.css"; import "@/assets/styles/index.scss"; // global css -import '@/assets/atom-one-dark.css' -import '@/assets/github-markdown.css' + import * as ElementPlusIconsVue from "@element-plus/icons-vue"; import directive from "./directive"; // directive diff --git a/Yi.Bbs.Vue3/src/views/bank/Index.vue b/Yi.Bbs.Vue3/src/views/bank/Index.vue index 0d67299d..118b8717 100644 --- a/Yi.Bbs.Vue3/src/views/bank/Index.vue +++ b/Yi.Bbs.Vue3/src/views/bank/Index.vue @@ -1,61 +1,90 @@ \ No newline at end of file