Merge branch 'refs/heads/abp' into digital-collectibles

This commit is contained in:
橙子
2025-02-03 10:30:26 +08:00
20 changed files with 593 additions and 481 deletions

View File

@@ -75,6 +75,7 @@ public class YiTokenAuthorizationFilter : IDashboardAsyncAuthorizationFilter, IT
function sendToken() {
// 获取输入的 token
var token = document.getElementById("tokenInput").value;
token = token.replace('Bearer ','');
// 构建请求 URL
var url = "/hangfire";
// 发送 GET 请求
@@ -107,7 +108,7 @@ public class YiTokenAuthorizationFilter : IDashboardAsyncAuthorizationFilter, IT
<body style="text-align: center;">
<h1>Yi-hangfire</h1>
<h1>Token</h1>
<input type="text" id="tokenInput" placeholder="请输入 token" />
<textarea id="tokenInput" placeholder="请输入 token" style="width: 80%;height: 120px;margin: 0 10%;"></textarea>
<button onclick="sendToken()"></button>
</body>
</html>

View File

@@ -23,14 +23,13 @@ namespace Yi.Framework.ChatHub.Application.Services
/// <param name="chatContext"></param>
/// <returns></returns>
[Authorize]
[HttpPost]
public async Task ChatAsync([FromBody] List<AiChatContextDto> chatContext)
[HttpPost("ai-chat/chat/{model}")]
public async Task ChatAsync([FromRoute]string model, [FromBody] List<AiChatContextDto> chatContext)
{
const int maxChar = 10;
var contextId = Guid.NewGuid();
Queue<string> stringQueue = new Queue<string>();
await foreach (var aiResult in _aiManager.ChatAsStreamAsync(chatContext))
await foreach (var aiResult in _aiManager.ChatAsStreamAsync(model,chatContext))
{
stringQueue.Enqueue(aiResult);
@@ -42,7 +41,7 @@ namespace Yi.Framework.ChatHub.Application.Services
var str = stringQueue.Dequeue();
currentStr.Append(str);
}
await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(currentStr.ToString(), CurrentUser.Id!.Value, contextId));
await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(currentStr.ToString(), CurrentUser.Id!.Value, contextId),model);
}
}
@@ -52,9 +51,7 @@ namespace Yi.Framework.ChatHub.Application.Services
var str = stringQueue.Dequeue();
currentEndStr.Append(str);
}
await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(currentEndStr.ToString(), CurrentUser.Id!.Value, contextId));
//await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(null, CurrentUser.Id!.Value, contextId));
await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(currentEndStr.ToString(), CurrentUser.Id!.Value, contextId),model);
}
}
}

View File

@@ -24,19 +24,8 @@ namespace Yi.Framework.ChatHub.Domain.Managers
}
private OpenAIService OpenAIService { get; }
public async IAsyncEnumerable<string> ChatAsStreamAsync(List<AiChatContextDto> aiChatContextDtos)
public async IAsyncEnumerable<string> ChatAsStreamAsync(string model, List<AiChatContextDto> aiChatContextDtos)
{
//var temp = "站长正在接入ChatGpt,敬请期待~";
//for (var i = 0; i < temp.Length; i++)
//{
// await Task.Delay(200);
// yield return temp[i].ToString();
//}
if (aiChatContextDtos.Count == 0)
{
yield return null;
@@ -56,7 +45,7 @@ namespace Yi.Framework.ChatHub.Domain.Managers
var completionResult = OpenAIService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest
{
Messages = messages,
Model = Models.Gpt_4o_mini
Model =model
});
HttpStatusCode? error = null;

View File

@@ -31,7 +31,14 @@ namespace Yi.Framework.ChatHub.Domain.Managers
private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService<IRedisClient>();
private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDistributedCacheOptions>>().Value.KeyPrefix;
public async Task SendMessageAsync(MessageContext context)
/// <summary>
/// 发送消息
/// </summary>
/// <param name="context">消息内容</param>
/// <param name="relStr">关联字符</param>
/// <exception cref="NotImplementedException"></exception>
public async Task SendMessageAsync(MessageContext context,string relStr=null)
{
switch (context.MessageType)
{
@@ -39,20 +46,20 @@ namespace Yi.Framework.ChatHub.Domain.Managers
var userModel = await GetUserAsync(context.ReceiveId.Value);
if (userModel is not null)
{
await _hubContext.Clients.Client(userModel.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context);
await _hubContext.Clients.Client(userModel.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType,relStr, context);
}
break;
case MessageTypeEnum.Group:
throw new NotImplementedException();
break;
case MessageTypeEnum.All:
await _hubContext.Clients.All.SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context);
await _hubContext.Clients.All.SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType,relStr, context);
break;
case MessageTypeEnum.Ai:
var userModel2 = await GetUserAsync(context.ReceiveId.Value);
if (userModel2 is not null)
{
await _hubContext.Clients.Client(userModel2.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context);
await _hubContext.Clients.Client(userModel2.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType,relStr, context);
}
break;

View File

@@ -2,7 +2,7 @@
namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Role
{
public class UpdateDataScpoceInput
public class UpdateDataScopeInput
{
public Guid RoleId { get; set; }

View File

@@ -39,7 +39,7 @@ namespace Yi.Framework.Rbac.Application.Services.System
private ISqlSugarRepository<UserRoleEntity> _userRoleRepository;
public async Task UpdateDataScpoceAsync(UpdateDataScpoceInput input)
public async Task UpdateDataScopeAsync(UpdateDataScopeInput input)
{
//只有自定义的需要特殊处理
if (input.DataScope == DataScopeEnum.CUSTOM)

View File

@@ -20,7 +20,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
<PackageReference Include="Volo.Abp.DistributedLocking" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj" />
<ProjectReference Include="..\..\..\framework\Yi.Framework.SqlSugarCore.Abstractions\Yi.Framework.SqlSugarCore.Abstractions.csproj" />

View File

@@ -1,6 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using Medallion.Threading;
using Medallion.Threading.Redis;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Caching;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Domain;
using Volo.Abp.Imaging;
using Volo.Abp.Modularity;
@@ -20,7 +24,8 @@ namespace Yi.Framework.Rbac.Domain
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpDddDomainModule),
typeof(AbpCachingModule),
typeof(AbpImagingImageSharpModule)
typeof(AbpImagingImageSharpModule),
typeof(AbpDistributedLockingModule)
)]
public class YiFrameworkRbacDomainModule : AbpModule
{
@@ -36,6 +41,15 @@ namespace Yi.Framework.Rbac.Domain
//配置阿里云短信
Configure<AliyunOptions>(configuration.GetSection(nameof(AliyunOptions)));
//分布式锁
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer
.Connect(configuration["Redis:Configuration"]);
return new
RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
}
}

View File

@@ -1,8 +1,10 @@
using System.Xml.Linq;
using Mapster;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Volo.Abp.Application.Services;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Settings;
using Volo.Abp.Uow;
using Yi.Framework.Bbs.Application.Contracts.Dtos.Banner;
@@ -49,7 +51,7 @@ namespace Yi.Abp.Application.Services
throw new UserFriendlyException("业务异常");
throw new Exception("系统异常");
}
/// <summary>
/// SqlSugar
/// </summary>
@@ -138,6 +140,7 @@ namespace Yi.Abp.Application.Services
}
private static int RequestNumber { get; set; } = 0;
/// <summary>
/// 速率限制
/// </summary>
@@ -154,6 +157,7 @@ namespace Yi.Abp.Application.Services
public ISettingProvider _settingProvider { get; set; }
public ISettingManager _settingManager { get; set; }
/// <summary>
/// 系统配置模块
/// </summary>
@@ -175,5 +179,41 @@ namespace Yi.Abp.Application.Services
return result ?? string.Empty;
}
/// <summary>
/// 分布式送abp版本abp套了一层娃。但是纯粹鸡肋不建议使用这个
/// </summary>
public IAbpDistributedLock AbpDistributedLock { get; set; }
/// <summary>
/// 分布式锁推荐使用版本yyds分布式锁永远的神
/// </summary>
public IDistributedLockProvider DistributedLock { get; set; }
/// <summary>
/// 分布式锁
/// </summary>
/// <remarks>强烈吐槽一下abp正如他们所说abp的分布式锁单纯为了自己用一切还是以DistributedLock为主</remarks>>
/// <returns></returns>
public async Task<string> GetDistributedLockAsync()
{
var number = 0;
await Parallel.ForAsync(0, 100, async (i, cancellationToken) =>
{
await using (await DistributedLock.AcquireLockAsync("MyLockName"))
{
//执行1秒
number += 1;
}
});
var number2 = 0;
await Parallel.ForAsync(0, 100, async (i, cancellationToken) =>
{
//执行1秒
number2 += 1;
});
return $"加锁结果:{number},不加锁结果:{number2}";
}
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.CommandLineUtils;
@@ -39,12 +40,11 @@ namespace Yi.Abp.Tool.Commands
}
CheckFirstSlnPath(slnPath);
var dotnetSlnCommandPart1 = $"dotnet sln \"{slnPath}\" add \"{modulePath}\\{moduleName}.";
var dotnetSlnCommandPart2 = new List<string>() { "Application", "Application.Contracts", "Domain", "Domain.Shared", "SqlSugarCore" };
var paths = dotnetSlnCommandPart2.Select(x => $@"{modulePath}\{moduleName}." + x).ToArray();
var dotnetSlnCommandPart = new List<string>() { "Application", "Application.Contracts", "Domain", "Domain.Shared", "SqlSugarCore" };
var paths = dotnetSlnCommandPart.Select(x => Path.Combine(modulePath, $"{moduleName}.{x}")).ToArray();
CheckPathExist(paths);
var cmdCommands = dotnetSlnCommandPart2.Select(x => dotnetSlnCommandPart1 + x+"\"").ToArray();
var cmdCommands = dotnetSlnCommandPart.Select(x => $"dotnet sln \"{slnPath}\" add \"{Path.Combine(modulePath, $"{moduleName}.{x}")}\"").ToArray();
StartCmd(cmdCommands);
Console.WriteLine("恭喜~模块添加成功!");
@@ -81,15 +81,24 @@ namespace Yi.Abp.Tool.Commands
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c chcp 65001&{string.Join("&", cmdCommands)}",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false
};
// 判断操作系统
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
psi.FileName = "cmd.exe";
psi.Arguments = $"/c chcp 65001&{string.Join("&", cmdCommands)}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
psi.FileName = "/bin/bash";
psi.Arguments = $"-c \"{string.Join("; ", cmdCommands)}\"";
}
Process proc = new Process
{
StartInfo = psi

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.CommandLineUtils;
@@ -35,15 +36,24 @@ namespace Yi.Abp.Tool.Commands
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c chcp 65001&{string.Join("&", cmdCommands)}",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false
};
// 判断操作系统
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
psi.FileName = "cmd.exe";
psi.Arguments = $"/c chcp 65001&{string.Join("&", cmdCommands)}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
psi.FileName = "/bin/bash";
psi.Arguments = $"-c \"{string.Join("; ", cmdCommands)}\"";
}
Process proc = new Process
{
StartInfo = psi