diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Recharge/RechargeCreateInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Recharge/RechargeCreateInput.cs
new file mode 100644
index 00000000..a8354fb7
--- /dev/null
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Recharge/RechargeCreateInput.cs
@@ -0,0 +1,43 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Recharge;
+
+public class RechargeCreateInput
+{
+ ///
+ /// 用户ID
+ ///
+ [Required]
+ public Guid UserId { get; set; }
+
+ ///
+ /// 充值金额
+ ///
+ [Required]
+ [Range(0.01, double.MaxValue, ErrorMessage = "充值金额必须大于0")]
+ public decimal RechargeAmount { get; set; }
+
+ ///
+ /// 充值内容
+ ///
+ [Required]
+ [StringLength(500, ErrorMessage = "充值内容不能超过500个字符")]
+ public string Content { get; set; } = string.Empty;
+
+ ///
+ /// 到期时间(为空表示永久VIP)
+ ///
+ public DateTime? ExpireDateTime { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [StringLength(1000, ErrorMessage = "备注不能超过1000个字符")]
+ public string? Remark { get; set; }
+
+ ///
+ /// 联系方式
+ ///
+ [StringLength(200, ErrorMessage = "联系方式不能超过200个字符")]
+ public string? ContactInfo { get; set; }
+}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/RechargeService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/RechargeService.cs
index 5cd8247b..913ae912 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/RechargeService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/RechargeService.cs
@@ -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;
-
-///
-/// ai 充值表
-///
-public class RechargeService : ApplicationService
+namespace Yi.Framework.AiHub.Application.Services
{
- private readonly ISqlSugarRepository _repository;
-
- public RechargeService(ISqlSugarRepository repository)
+ public class RechargeService : ApplicationService
{
- _repository = repository;
- }
+ private readonly ISqlSugarRepository _repository;
+ private readonly ICurrentUser _currentUser;
+ private readonly IUserService _userService;
- ///
- /// 查询已登录的账户充值记录
- ///
- ///
- [Route("recharge/account")]
- [Authorize]
- public async Task> GetListByAccountAsync()
- {
- var userId = CurrentUser.Id;
- var entities = await _repository._DbQueryable.Where(x => x.UserId == userId)
- .OrderByDescending(x => x.CreationTime)
- .ToListAsync();
- var output = entities.Adapt>();
- return output;
+ public RechargeService(
+ ISqlSugarRepository repository,
+ ICurrentUser currentUser,
+ IUserService userService)
+ {
+ _repository = repository;
+ _currentUser = currentUser;
+ _userService = userService;
+ }
+
+ ///
+ /// 查询已登录的账户充值记录
+ ///
+ ///
+ [Route("recharge/account")]
+ [Authorize]
+ public async Task> GetListByAccountAsync()
+ {
+ var userId = CurrentUser.Id;
+ var entities = await _repository._DbQueryable.Where(x => x.UserId == userId)
+ .OrderByDescending(x => x.CreationTime)
+ .ToListAsync();
+ var output = entities.Adapt>();
+ return output;
+ }
+
+ ///
+ /// 给用户充值VIP
+ ///
+ /// 充值输入参数
+ ///
+ [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() { AiHubConst.VipRole, "default" });
+ }
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiRechargeManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiRechargeManager.cs
index ee9413fc..7f8a4fdc 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiRechargeManager.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiRechargeManager.cs
@@ -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
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IUserService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IUserService.cs
index 343765e4..315fdb13 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IUserService.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/IServices/IUserService.cs
@@ -8,5 +8,12 @@ namespace Yi.Framework.Rbac.Application.Contracts.IServices
///
public interface IUserService : IYiCrudAppService
{
+ ///
+ /// 通过角色代码给用户添加角色
+ ///
+ /// 用户ID
+ /// 角色代码
+ ///
+ Task AddUserRoleByRoleCodeAsync(Guid userId, List roleCodes);
}
}
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/UserService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/UserService.cs
index 33d97ddf..a4f5cc55 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/UserService.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/UserService.cs
@@ -241,5 +241,29 @@ namespace Yi.Framework.Rbac.Application.Services.System
{
return base.PostImportExcelAsync(input);
}
+
+ ///
+ /// 通过角色代码给用户添加角色
+ ///
+ /// 用户ID
+ ///
+ ///
+ public async Task AddUserRoleByRoleCodeAsync(Guid userId, List roleCodes)
+ {
+ // 根据角色代码查找角色ID
+ var roleRepository = LazyServiceProvider.LazyGetRequiredService>();
+ var roleIds = await roleRepository._DbQueryable
+ .Where(r => roleCodes.Contains(r.RoleCode) && r.State == true)
+ .Select(r=>r.Id)
+ .ToListAsync();
+
+ if (!roleIds.Any())
+ {
+ return;
+ }
+
+ // 使用UserManager给用户设置角色
+ await _userManager.GiveUserSetRoleAsync(new List { userId }, roleIds);
+ }
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/FileManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/FileManager.cs
index d82112d5..40f542cd 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/FileManager.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/FileManager.cs
@@ -32,14 +32,15 @@ public class FileManager : DomainService, IFileManager
///
public async Task> CreateAsync(IEnumerable files)
{
- if (files.Count() == 0)
+ var formFiles = files as IFormFile[] ?? files.ToArray();
+ if (!formFiles.Any())
{
throw new ArgumentException("文件上传为空!");
}
//批量插入
List entities = new();
- foreach (var file in files)
+ foreach (var file in formFiles)
{
FileAggregateRoot data = new(_guidGenerator.Create(), file.FileName, (decimal)file.Length / 1024);
data.CheckDirectoryOrCreate();
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/RoleManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/RoleManager.cs
index 3726eb00..9df14100 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/RoleManager.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/RoleManager.cs
@@ -26,19 +26,20 @@ namespace Yi.Framework.Rbac.Domain.Managers
{
//这个是需要事务的,在service中进行工作单元
await _roleMenuRepository.DeleteAsync(u => roleIds.Contains(u.RoleId));
+ //添加新的关系
+ List roleMenuEntity = new();
//遍历用户
foreach (var roleId in roleIds)
{
- //添加新的关系
- List roleMenuEntity = new();
+
foreach (var menu in menuIds)
{
roleMenuEntity.Add(new RoleMenuEntity() { RoleId = roleId, MenuId = menu });
}
- //一次性批量添加
- await _roleMenuRepository.InsertRangeAsync(roleMenuEntity);
+
}
-
+ //一次性批量添加
+ await _roleMenuRepository.InsertRangeAsync(roleMenuEntity);
}
///
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs
index 46ace5d8..ac8a4c87 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs
@@ -46,27 +46,25 @@ namespace Yi.Framework.Rbac.Domain.Managers
///
///
///
- public async Task GiveUserSetRoleAsync(List userIds, List roleIds)
+ public async Task GiveUserSetRoleAsync(List userIds, List? roleIds)
{
- //删除用户之前所有的用户角色关系(物理删除,没有恢复的必要)
+ //删除用户之前所有的用户角色关系
await _repositoryUserRole.DeleteAsync(u => userIds.Contains(u.UserId));
if (roleIds is not null)
{
+ //添加新的关系
+ List userRoleEntities = new();
//遍历用户
foreach (var userId in userIds)
{
- //添加新的关系
- List userRoleEntities = new();
-
foreach (var roleId in roleIds)
{
userRoleEntities.Add(new UserRoleEntity() { UserId = userId, RoleId = roleId });
}
-
- //一次性批量添加
- await _repositoryUserRole.InsertRangeAsync(userRoleEntities);
}
+ //一次性批量添加
+ await _repositoryUserRole.InsertRangeAsync(userRoleEntities);
}
}
@@ -77,25 +75,24 @@ namespace Yi.Framework.Rbac.Domain.Managers
///
///
///
- public async Task GiveUserSetPostAsync(List userIds, List postIds)
+ public async Task GiveUserSetPostAsync(List userIds, List? postIds)
{
//删除用户之前所有的用户角色关系(物理删除,没有恢复的必要)
await _repositoryUserPost.DeleteAsync(u => userIds.Contains(u.UserId));
if (postIds is not null)
{
+ //添加新的关系
+ List userPostEntities = new();
//遍历用户
foreach (var userId in userIds)
{
- //添加新的关系
- List userPostEntities = new();
foreach (var post in postIds)
{
userPostEntities.Add(new UserPostEntity() { UserId = userId, PostId = post });
}
-
- //一次性批量添加
- await _repositoryUserPost.InsertRangeAsync(userPostEntities);
}
+ //一次性批量添加
+ await _repositoryUserPost.InsertRangeAsync(userPostEntities);
}
}
@@ -137,10 +134,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
public async Task SetDefautRoleAsync(Guid userId)
{
var role = await _roleRepository.GetFirstAsync(x => x.RoleCode == UserConst.DefaultRoleCode);
- if (role is not null)
- {
- await GiveUserSetRoleAsync(new List { userId }, new List { role.Id });
- }
+ await GiveUserSetRoleAsync(new List { userId }, new List { role.Id });
}
private void ValidateUserName(UserAggregateRoot input)