feat: 新增VIP充值接口并支持通过角色代码为用户分配角色
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Recharge;
|
||||
|
||||
public class RechargeCreateInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值金额
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Range(0.01, double.MaxValue, ErrorMessage = "充值金额必须大于0")]
|
||||
public decimal RechargeAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 充值内容
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(500, ErrorMessage = "充值内容不能超过500个字符")]
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 到期时间(为空表示永久VIP)
|
||||
/// </summary>
|
||||
public DateTime? ExpireDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[StringLength(1000, ErrorMessage = "备注不能超过1000个字符")]
|
||||
public string? Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系方式
|
||||
/// </summary>
|
||||
[StringLength(200, ErrorMessage = "联系方式不能超过200个字符")]
|
||||
public string? ContactInfo { get; set; }
|
||||
}
|
||||
@@ -1,41 +1,73 @@
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Users;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos.Recharge;
|
||||
using Yi.Framework.AiHub.Domain.Entities;
|
||||
using Yi.Framework.AiHub.Domain.Shared.Consts;
|
||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.AiHub.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
/// ai 充值表
|
||||
/// </summary>
|
||||
public class RechargeService : ApplicationService
|
||||
namespace Yi.Framework.AiHub.Application.Services
|
||||
{
|
||||
private readonly ISqlSugarRepository<AiRechargeAggregateRoot> _repository;
|
||||
|
||||
public RechargeService(ISqlSugarRepository<AiRechargeAggregateRoot> repository)
|
||||
public class RechargeService : ApplicationService
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
private readonly ISqlSugarRepository<AiRechargeAggregateRoot> _repository;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
/// <summary>
|
||||
/// 查询已登录的账户充值记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Route("recharge/account")]
|
||||
[Authorize]
|
||||
public async Task<List<RechargeGetListOutput>> GetListByAccountAsync()
|
||||
{
|
||||
var userId = CurrentUser.Id;
|
||||
var entities = await _repository._DbQueryable.Where(x => x.UserId == userId)
|
||||
.OrderByDescending(x => x.CreationTime)
|
||||
.ToListAsync();
|
||||
var output = entities.Adapt<List<RechargeGetListOutput>>();
|
||||
return output;
|
||||
public RechargeService(
|
||||
ISqlSugarRepository<AiRechargeAggregateRoot> repository,
|
||||
ICurrentUser currentUser,
|
||||
IUserService userService)
|
||||
{
|
||||
_repository = repository;
|
||||
_currentUser = currentUser;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询已登录的账户充值记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Route("recharge/account")]
|
||||
[Authorize]
|
||||
public async Task<List<RechargeGetListOutput>> GetListByAccountAsync()
|
||||
{
|
||||
var userId = CurrentUser.Id;
|
||||
var entities = await _repository._DbQueryable.Where(x => x.UserId == userId)
|
||||
.OrderByDescending(x => x.CreationTime)
|
||||
.ToListAsync();
|
||||
var output = entities.Adapt<List<RechargeGetListOutput>>();
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给用户充值VIP
|
||||
/// </summary>
|
||||
/// <param name="input">充值输入参数</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("recharge/vip")]
|
||||
public async Task RechargeVipAsync(RechargeCreateInput input)
|
||||
{
|
||||
// 创建充值记录
|
||||
var rechargeRecord = new AiRechargeAggregateRoot
|
||||
{
|
||||
UserId = input.UserId,
|
||||
RechargeAmount = input.RechargeAmount,
|
||||
Content = input.Content,
|
||||
ExpireDateTime = input.ExpireDateTime,
|
||||
Remark = input.Remark,
|
||||
ContactInfo = input.ContactInfo
|
||||
};
|
||||
|
||||
// 保存充值记录到数据库
|
||||
await _repository.InsertAsync(rechargeRecord);
|
||||
|
||||
// 使用UserService给用户添加VIP角色
|
||||
await _userService.AddUserRoleByRoleCodeAsync(input.UserId,
|
||||
new List<string>() { AiHubConst.VipRole, "default" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,19 +32,40 @@ public class AiRechargeManager : DomainService
|
||||
// 获取当前时间
|
||||
var currentTime = DateTime.Now;
|
||||
|
||||
// 查找过期的充值记录
|
||||
var expiredRecharges = await _rechargeRepository._DbQueryable
|
||||
.Where(x => x.ExpireDateTime.HasValue && x.ExpireDateTime.Value < currentTime)
|
||||
// 查找所有充值记录,按用户分组
|
||||
var allRecharges = await _rechargeRepository._DbQueryable
|
||||
.ToListAsync();
|
||||
|
||||
if (!expiredRecharges.Any())
|
||||
if (!allRecharges.Any())
|
||||
{
|
||||
_logger.LogInformation("没有找到任何充值记录");
|
||||
return;
|
||||
}
|
||||
|
||||
// 按用户分组,找出真正过期的用户
|
||||
var expiredUserIds = allRecharges
|
||||
.GroupBy(x => x.UserId)
|
||||
.Where(group =>
|
||||
{
|
||||
// 如果用户有任何一个过期时间为空的记录,说明是永久VIP,不过期
|
||||
if (group.Any(x => !x.ExpireDateTime.HasValue))
|
||||
return false;
|
||||
|
||||
// 找到用户最大的过期时间
|
||||
var maxExpireTime = group.Max(x => x.ExpireDateTime);
|
||||
|
||||
// 如果最大过期时间小于当前时间,说明用户已过期
|
||||
return maxExpireTime.HasValue && maxExpireTime.Value < currentTime;
|
||||
})
|
||||
.Select(group => group.Key)
|
||||
.ToList();
|
||||
|
||||
if (!expiredUserIds.Any())
|
||||
{
|
||||
_logger.LogInformation("没有找到过期的VIP用户");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取过期用户的ID列表
|
||||
var expiredUserIds = expiredRecharges.Select(x => x.UserId).Distinct().ToList();
|
||||
_logger.LogInformation($"找到 {expiredUserIds.Count} 个过期的VIP用户");
|
||||
|
||||
// 获取YiXinAi-Vip角色ID
|
||||
|
||||
Reference in New Issue
Block a user