Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bdd14da94 | ||
|
|
bdcf89bc35 | ||
|
|
8418cfa56e | ||
| 0a0b80cc1c | |||
| ac95d9b438 | |||
|
|
f82e97b4ef | ||
|
|
2268c115e3 | ||
|
|
d19afd6e8a | ||
|
|
72f84dce05 | ||
|
|
9222d5d4f4 | ||
|
|
af016b57e5 | ||
|
|
5263badb1a | ||
|
|
14600d3392 | ||
| b7cae0952e | |||
| bcdfc25af1 | |||
| 8db46fb36d | |||
|
|
cb73982ef0 | ||
|
|
02ac4e3961 | ||
|
|
b300c7df52 | ||
| 4fe894fb6f | |||
| 03710a37b1 | |||
|
|
ac181d208d | ||
|
|
49e9ded36a | ||
| 72a6b47e99 | |||
|
|
bfe3f95055 |
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -360,4 +360,6 @@ MigrationBackup/
|
|||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
output/
|
||||
logs/
|
||||
|
|
@ -44,7 +44,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.MiaoYu.Code", "src
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.MiaoYu.WebApi", "src\2-api\HuanMeng.MiaoYu.WebApi\HuanMeng.MiaoYu.WebApi.csproj", "{729950F2-71EE-42C0-8B46-295740DE20BA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuanMeng.Utility", "src\0-core\HuanMeng.Utility\HuanMeng.Utility.csproj", "{48E1532F-8B50-477C-BB78-8AEA89A167CE}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.Utility", "src\0-core\HuanMeng.Utility\HuanMeng.Utility.csproj", "{48E1532F-8B50-477C-BB78-8AEA89A167CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -1 +1,13 @@
|
|||
# HuanMengProject
|
||||
# HuanMengProject 开发文档
|
||||
|
||||
|
||||
### 项目说明
|
||||
```sh
|
||||
# Program.cs 文件说明
|
||||
# 输出的时候,将请求的参数转换成小写
|
||||
c.ParameterFilter<LowercaseParameterFilter>();
|
||||
c.RequestBodyFilter<LowercaseRequestFilter>();
|
||||
|
||||
//配置路由选项,使URL全部小写
|
||||
builder.Services.AddRouting(options => options.LowercaseUrls = true);
|
||||
```
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace XLib.DotNetCore.CacheHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 内存缓存帮助类
|
||||
/// </summary>
|
||||
public class MemoryCacheHelper
|
||||
{
|
||||
private static MemoryCache cache = new MemoryCache(new MemoryCacheOptions());
|
||||
|
||||
/// <summary>
|
||||
/// 获取缓存
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheName"></param>
|
||||
/// <returns></returns>
|
||||
public static T? GetCache<T>(string cacheName) where T : class, new()
|
||||
{
|
||||
|
||||
return cache.TryGetValue(cacheName, out var value) ? value as T : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置缓存
|
||||
/// </summary>
|
||||
/// <param name="cacheName"></param>
|
||||
/// <param name="val"></param>
|
||||
/// <param name="cacheTime">单位秒,默认1小时</param>
|
||||
public static void SetCache(string cacheName, object val, int cacheTime = 21000)
|
||||
{
|
||||
//数据量渐渐大了,每次因为很多都是同时缓存 所以在这里分流一下
|
||||
if (cacheTime == 21000)
|
||||
cacheTime = new Random().Next(21000, 43200);
|
||||
cache.Set(cacheName, val, TimeSpan.FromSeconds(cacheTime));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除缓存
|
||||
/// </summary>
|
||||
/// <param name="cacheName"></param>
|
||||
public static void DelCache(string? cacheName = null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(cacheName))
|
||||
cache.Remove(cacheName);
|
||||
else
|
||||
cache.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
namespace HuanMeng.DotNetCore.CustomExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加跨域
|
||||
/// </summary>
|
||||
public static class CorsExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加跨域
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="policyName"></param>
|
||||
public static void AddCustomCors(this IServiceCollection services, string policyName)
|
||||
{
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(policyName,
|
||||
builder =>
|
||||
{
|
||||
builder
|
||||
.AllowAnyOrigin()
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using HuanMeng.DotNetCore.Base;
|
|||
using HuanMeng.DotNetCore.JwtInfrastructure;
|
||||
using HuanMeng.DotNetCore.JwtInfrastructure.Interface;
|
||||
using HuanMeng.DotNetCore.MultiTenant;
|
||||
using HuanMeng.MiaoYu.Code.Cache;
|
||||
using HuanMeng.MiaoYu.Code.DataAccess;
|
||||
using HuanMeng.MiaoYu.Code.TencentUtile;
|
||||
using HuanMeng.MiaoYu.Code.Users.UserAccount;
|
||||
|
|
@ -13,6 +14,7 @@ using HuanMeng.MiaoYu.Model.Dto;
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
using System;
|
||||
|
|
@ -29,10 +31,12 @@ namespace HuanMeng.MiaoYu.Code.Base
|
|||
/// </summary>
|
||||
public class MiaoYuBase : BLLBase<DAO>
|
||||
{
|
||||
|
||||
public MiaoYuBase(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||
{
|
||||
|
||||
}
|
||||
#region 数据库
|
||||
private DAO _dao;
|
||||
/// <summary>
|
||||
/// dao 数据库
|
||||
|
|
@ -48,6 +52,7 @@ namespace HuanMeng.MiaoYu.Code.Base
|
|||
return _dao;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 租户信息
|
||||
/// <summary>
|
||||
|
|
@ -79,7 +84,7 @@ namespace HuanMeng.MiaoYu.Code.Base
|
|||
{
|
||||
get
|
||||
{
|
||||
if (_mapper == null)
|
||||
if (_HttpContextAccessor == null)
|
||||
{
|
||||
_HttpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
|
||||
}
|
||||
|
|
@ -179,25 +184,31 @@ namespace HuanMeng.MiaoYu.Code.Base
|
|||
var accessToken = HttpContextAccessor.HttpContext.GetTokenAsync("Bearer", "access_token").Result;
|
||||
if (string.IsNullOrEmpty(accessToken))
|
||||
{
|
||||
|
||||
_userInfo = new RequestUserInfo()
|
||||
{
|
||||
UserId = 0
|
||||
};
|
||||
}
|
||||
var (principal, jwtToken) = JwtAuthManager.DecodeJwtToken(accessToken);
|
||||
if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature))
|
||||
else
|
||||
{
|
||||
throw new SecurityTokenException("无效的token");
|
||||
var (principal, jwtToken) = JwtAuthManager.DecodeJwtToken(accessToken);
|
||||
if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature))
|
||||
{
|
||||
throw new SecurityTokenException("无效的token");
|
||||
}
|
||||
var userIdStr = principal.FindFirst("UserId")?.Value;
|
||||
if (string.IsNullOrEmpty(userIdStr))
|
||||
{
|
||||
throw new SecurityTokenException("无效的token");
|
||||
}
|
||||
var nickName = principal.FindFirst("NickName")?.Value;
|
||||
var userId = int.Parse(userIdStr);
|
||||
_userInfo = new RequestUserInfo()
|
||||
{
|
||||
UserId = userId,
|
||||
NickName = nickName
|
||||
};
|
||||
}
|
||||
var userIdStr = principal.FindFirst("UserId")?.Value;
|
||||
if (string.IsNullOrEmpty(userIdStr))
|
||||
{
|
||||
throw new SecurityTokenException("无效的token");
|
||||
}
|
||||
var nickName = principal.FindFirst("NickName")?.Value;
|
||||
var userId = int.Parse(userIdStr);
|
||||
_userInfo = new RequestUserInfo()
|
||||
{
|
||||
UserId = userId,
|
||||
NickName = nickName
|
||||
};
|
||||
}
|
||||
return _userInfo;
|
||||
}
|
||||
|
|
@ -214,5 +225,40 @@ namespace HuanMeng.MiaoYu.Code.Base
|
|||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 缓存实现类
|
||||
private MiaoYuCache? _miaoYuCache; //new MiaoYuCache(Dao, Mapper);
|
||||
/// <summary>
|
||||
/// 妙语实现类
|
||||
/// </summary>
|
||||
public MiaoYuCache MiaoYuCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_miaoYuCache == null)
|
||||
{
|
||||
//new MiaoYuDataEntityCache<T_Character>(Dao).DataList
|
||||
_miaoYuCache = new MiaoYuCache(Dao, Mapper);
|
||||
}
|
||||
return _miaoYuCache;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 日志
|
||||
private Logger<MiaoYuBase>? _logger;
|
||||
public Logger<MiaoYuBase> _Logger
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
if (_logger == null)
|
||||
{
|
||||
_logger = _serviceProvider.GetRequiredService<Logger<MiaoYuBase>>();
|
||||
}
|
||||
return _logger;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
56
src/0-core/HuanMeng.MiaoYu.Code/Cache/CharacterBaseCache.cs
Normal file
56
src/0-core/HuanMeng.MiaoYu.Code/Cache/CharacterBaseCache.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HuanMeng.MiaoYu.Code.DataAccess;
|
||||
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// 人物信息缓存
|
||||
/// </summary>
|
||||
public class CharacterInfoBaseCache
|
||||
{
|
||||
private IMemoryCache _memoryCache;
|
||||
private object _cacheLock = new object(); // 用于线程安全的锁
|
||||
private const string CharactersCacheKey = "Characters";
|
||||
private DAO _dao;
|
||||
|
||||
public CharacterInfoBaseCache(IMemoryCache memoryCache, DAO dao)
|
||||
{
|
||||
this._memoryCache = memoryCache;
|
||||
this._dao = dao;
|
||||
}
|
||||
|
||||
public List<T_Character> GetCharacterFromCache(int userId)
|
||||
{
|
||||
lock (_cacheLock) // 加锁以防止并发访问
|
||||
{
|
||||
if (!_memoryCache.TryGetValue(CharactersCacheKey , out List<T_Character> cachedCharacter))
|
||||
{
|
||||
// 如果缓存中没有数据,则从数据库中获取
|
||||
//var db = new YourDbContext();
|
||||
var character = _dao.daoDbMiaoYu.context.T_Character.ToList();
|
||||
if (character != null && character.Count > 0)
|
||||
{
|
||||
// 将数据放入缓存
|
||||
var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
.SetAbsoluteExpiration(TimeSpan.FromMinutes(30)) // 设置缓存过期时间
|
||||
.SetSlidingExpiration(TimeSpan.FromMinutes(5)); // 设置滑动过期时间
|
||||
_memoryCache.Set(CharactersCacheKey , character, cacheEntryOptions);
|
||||
|
||||
cachedCharacter = character;
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedCharacter = new List<T_Character>();
|
||||
}
|
||||
}
|
||||
return cachedCharacter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using XLib.DotNetCore.CacheHelper;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Cache
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class CommonDataEntityCache<T>(object lockObj, int cacheTime = 36000) where T : class
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract string key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 缓存数据
|
||||
/// </summary>
|
||||
protected List<T>? _dataList;
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public List<T> DataList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_dataList == null)
|
||||
{
|
||||
var tempDataList = MemoryCacheHelper.GetCache<List<T>>(key);
|
||||
if (tempDataList == null)
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
if (tempDataList == null)
|
||||
{
|
||||
tempDataList = GetDataList();
|
||||
MemoryCacheHelper.SetCache(key, tempDataList, cacheTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
_dataList = JsonConvert.DeserializeObject<List<T>>(JsonConvert.SerializeObject(tempDataList));
|
||||
}
|
||||
return _dataList ?? new List<T>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取缓存数据
|
||||
/// </summary>
|
||||
public abstract List<T> GetDataList();
|
||||
}
|
||||
}
|
||||
119
src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs
Normal file
119
src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
|
||||
using AutoMapper;
|
||||
|
||||
using HuanMeng.MiaoYu.Code.Cache.Special;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存类
|
||||
/// </summary>
|
||||
/// <param name="dao"></param>
|
||||
public partial class MiaoYuCache(DAO dao, IMapper mapper)
|
||||
{
|
||||
#region 角色缓存表
|
||||
/// <summary>
|
||||
/// 对话角色缓存表
|
||||
/// </summary>
|
||||
private static object CharacterLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 对话角色缓存表
|
||||
/// </summary>
|
||||
public MiaoYuDataEntityCache<T_Character>? Character { get; set; }
|
||||
/// <summary>
|
||||
/// 角色数据表
|
||||
/// </summary>
|
||||
public List<T_Character> CharactersList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Character == null)
|
||||
{
|
||||
Character = new MiaoYuDataEntityCache<T_Character>(dao, CharacterLock);
|
||||
}
|
||||
return Character.DataList ?? new List<T_Character>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 模型缓存表
|
||||
/// <summary>
|
||||
/// 模型缓存表
|
||||
/// </summary>
|
||||
private static object ModelConfigLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 模型缓存表
|
||||
/// </summary>
|
||||
public MiaoYuDataEntityCache<T_Model_Config>? ModelConfig { get; set; }
|
||||
/// <summary>
|
||||
/// 模型
|
||||
/// </summary>
|
||||
public List<T_Model_Config> ModelConfigList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ModelConfig == null)
|
||||
{
|
||||
ModelConfig = new MiaoYuDataEntityCache<T_Model_Config>(dao, ModelConfigLock);
|
||||
}
|
||||
return ModelConfig.DataList ?? new List<T_Model_Config>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 角色信息
|
||||
/// <summary>
|
||||
/// 角色缓存表
|
||||
/// </summary>
|
||||
public CharacterEntityCache? CharacterCache { get; set; }
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public List<CharacterCache> CharacterList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CharacterCache == null)
|
||||
{
|
||||
|
||||
CharacterCache = new CharacterEntityCache(dao, mapper);
|
||||
}
|
||||
return CharacterCache.DataList ?? new List<CharacterCache>();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 图片缓存表
|
||||
/// <summary>
|
||||
/// 图片缓存表
|
||||
/// </summary>
|
||||
private static object ImageConfigLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 图片缓存表
|
||||
/// </summary>
|
||||
public MiaoYuDataEntityCache<T_Image_Config>? ImageConfigCache { get; set; }
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public List<T_Image_Config> ImageConfigList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ImageConfigCache == null)
|
||||
{
|
||||
ImageConfigCache = new MiaoYuDataEntityCache<T_Image_Config>(dao, ImageConfigLock);
|
||||
}
|
||||
return ImageConfigCache.DataList ?? new List<T_Image_Config>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// 妙语数据库实体类缓存
|
||||
/// </summary>
|
||||
public class MiaoYuDataEntityCache<T>(DAO _dao, object lockObj, int cacheTime = 36000)
|
||||
: CommonDataEntityCache<T>(lockObj, cacheTime) where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存的key
|
||||
/// </summary>
|
||||
public override string key
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{_dao.daoDbMiaoYu.context.TenantInfo?.TenantId}:MiaoYu:{typeof(T).Name}";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<T> GetDataList()
|
||||
{
|
||||
var dbSet = _dao.daoDbMiaoYu.context.Set<T>();
|
||||
if (dbSet == null)
|
||||
{
|
||||
return new List<T>();
|
||||
}
|
||||
return dbSet.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
using AutoMapper;
|
||||
|
||||
using HuanMeng.MiaoYu.Code.DataAccess;
|
||||
using HuanMeng.MiaoYu.Code.Other;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Label;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Cache.Special
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="_dao"></param>
|
||||
public class CharacterEntityCache(DAO _dao, IMapper mapper) : MiaoYuDataEntityCache<CharacterCache>(_dao, CharacterCacheLock)
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁
|
||||
/// </summary>
|
||||
private static object CharacterCacheLock = new object();
|
||||
private static object ImageLock = new object();
|
||||
private static object T_Character_LabelLock = new object();
|
||||
private static object T_Character_Label_RelationLock = new object();
|
||||
/// <summary>
|
||||
/// 获取缓存数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<CharacterCache> GetDataList()
|
||||
{
|
||||
List<CharacterCache> characterCaches = new List<CharacterCache>();
|
||||
//读取角色表
|
||||
var characters = _dao.daoDbMiaoYu.context.T_Character.ToList();
|
||||
if (characters == null)
|
||||
{
|
||||
return characterCaches;
|
||||
}
|
||||
characterCaches = mapper.Map<List<CharacterCache>>(characters);
|
||||
string sqlString = $"select TOP 100 CharacterId,count(DISTINCT UserId ) UserCount from T_User_Char where isdelete=0 and TenantId='{_dao.daoDbMiaoYu.context.TenantInfo?.TenantId}' GROUP BY CharacterId";
|
||||
//获取查看次数
|
||||
var characteChatCounts = _dao.daoDbMiaoYu.SqlQueryList<CharacteChatCountModel>(sqlString);
|
||||
//查询配置表
|
||||
var modelConfigs = _dao.daoDbMiaoYu.context.T_Model_Config.ToList();
|
||||
var ImageConfigCache = new MiaoYuDataEntityCache<T_Image_Config>(_dao, ImageLock);
|
||||
var images = ImageConfigCache.DataList;
|
||||
//标签
|
||||
var labelCache = new MiaoYuDataEntityCache<T_Character_Label>(_dao, T_Character_LabelLock);
|
||||
var labels = labelCache.DataList;
|
||||
var labelRelationCache = new MiaoYuDataEntityCache<T_Character_Label_Relation>(_dao, T_Character_Label_RelationLock);
|
||||
var labelRelations = labelRelationCache.DataList;
|
||||
|
||||
foreach (var characterCache in characterCaches)
|
||||
{
|
||||
var modelConfig = modelConfigs.FirstOrDefault(it => it.Id == characterCache.ModelConfigId);
|
||||
if (modelConfig != null)
|
||||
{
|
||||
characterCache.ModelConfig = modelConfig;
|
||||
//查询图片
|
||||
characterCache.IconImage = images.GetImageUrl(characterCache.IconImg ?? 0);
|
||||
characterCache.BgImage = images.GetImageUrl(characterCache.BgImg ?? 0);
|
||||
var c = characteChatCounts.FirstOrDefault(it => it.CharacterId == characterCache.Id);
|
||||
if (c != null)
|
||||
{
|
||||
characterCache.LookCount = c.UserCount;
|
||||
}
|
||||
var characterLabelIds = labelRelations.Where(it => it.CharacterId == characterCache.Id).Select(it => it.CharacterLabelId).ToList();
|
||||
if (characterLabelIds.Count > 0)
|
||||
{
|
||||
var lab = labels.Where(it => characterLabelIds.Contains(it.Id)).ToList();
|
||||
var labs = mapper.Map<List<LabelDto>>(lab);
|
||||
characterCache.Label = labs;
|
||||
}
|
||||
else
|
||||
{
|
||||
characterCache.Label = new List<LabelDto>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//移除没有配置模型的类
|
||||
characterCaches.Where(it => it.ModelConfig == null).ToList().ForEach(characterCache =>
|
||||
{
|
||||
characterCaches.Remove(characterCache);
|
||||
});
|
||||
return characterCaches;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
99
src/0-core/HuanMeng.MiaoYu.Code/Character/CharacterBLL.cs
Normal file
99
src/0-core/HuanMeng.MiaoYu.Code/Character/CharacterBLL.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
|
||||
using AutoMapper;
|
||||
|
||||
using HuanMeng.DotNetCore.Base;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Chat;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Character
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色信息类
|
||||
/// </summary>
|
||||
public class CharacterBLL : MiaoYuBase
|
||||
{
|
||||
public CharacterBLL(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 首页获取角色列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<BaseResponse<List<CharacterInfoDto>>> GetHomeCharacter(RequestCharacterInfoPage requestCharacterInfo)
|
||||
{
|
||||
var index = requestCharacterInfo.Index ?? 0;
|
||||
var size = requestCharacterInfo.Size ?? 10;
|
||||
var charactersList = MiaoYuCache.CharacterList.OrderByDescending(it => it.LookCount)
|
||||
.Skip((index - 1) * size).Take(size).ToList();
|
||||
if (charactersList.Count == 0)
|
||||
{
|
||||
return new BaseResponse<List<CharacterInfoDto>>();
|
||||
}
|
||||
var list = Mapper.Map<List<CharacterInfoDto>>(charactersList);
|
||||
//不是游客
|
||||
if (_UserId != 0)
|
||||
{
|
||||
List<int> characterIds = list.Select(it => it.CharacterId).ToList();
|
||||
//获取亲密值
|
||||
var intimacys = await Dao.daoDbMiaoYu.context.T_Character_User_Intimacy.Where(it => it.UserId == _UserId
|
||||
&& characterIds.Contains(it.CharacterId)).ToListAsync();
|
||||
list.ForEach(it =>
|
||||
{
|
||||
it.Intimacy = intimacys.FirstOrDefault(item => item.CharacterId == it.CharacterId)?.IntimacyValue ?? 0;
|
||||
});
|
||||
}
|
||||
return new BaseResponse<List<CharacterInfoDto>>(ResonseCode.Success, "", list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色详情
|
||||
/// </summary>
|
||||
/// <param name="requestCharacterInfo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<BaseResponse<CharacterInfoDto>> GetCharacterInfo(RequestCharacterInfo requestCharacterInfo)
|
||||
{
|
||||
var charactersinfo = MiaoYuCache.CharacterList.FirstOrDefault(it => it.Id == requestCharacterInfo.CharacterId);
|
||||
if (charactersinfo == null)
|
||||
{
|
||||
return new BaseResponse<CharacterInfoDto>();
|
||||
}
|
||||
var info = Mapper.Map<CharacterInfoDto>(charactersinfo);
|
||||
//不是游客
|
||||
if (_UserId != 0)
|
||||
{
|
||||
//获取亲密值
|
||||
var intimacys = await Dao.daoDbMiaoYu.context.T_Character_User_Intimacy.Where(it => it.UserId == _UserId
|
||||
&& it.CharacterId == info.CharacterId).FirstOrDefaultAsync();
|
||||
info.Intimacy = intimacys?.IntimacyValue ?? 0;
|
||||
}
|
||||
return new BaseResponse<CharacterInfoDto>(ResonseCode.Success, "", info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取全部角色的Id
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public BaseResponse<List<int>> GetCharacters()
|
||||
{
|
||||
Random rng = new Random();
|
||||
var charactersIds = MiaoYuCache.CharacterList.Select(it => it.Id).OrderBy(x => rng.Next()).ToList();
|
||||
if (charactersIds == null)
|
||||
{
|
||||
charactersIds = new List<int>();
|
||||
}
|
||||
return new BaseResponse<List<int>>(ResonseCode.Success, "", charactersIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs
Normal file
67
src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using HuanMeng.DotNetCore.Base;
|
||||
using HuanMeng.MiaoYu.Code.Cache;
|
||||
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天类
|
||||
/// </summary>
|
||||
public class ChatBLL : MiaoYuBase
|
||||
{
|
||||
public ChatBLL(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除聊天记录
|
||||
/// </summary>
|
||||
/// <param name="id">聊天id</param>
|
||||
/// <param name="characterId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DelChatByIds(List<int> id, int characterId)
|
||||
{
|
||||
//var charactersList = MiaoYuCache.CharactersList;
|
||||
//List<T_Character> list = _characterCache.GetCharacterFromCache(characterId);
|
||||
//var chatsToDelete = await Dao.daoDbMiaoYu.context.T_Chat.Where(t => id.Contains(t.Id)).ToListAsync();
|
||||
//if (chatsToDelete.Count <= 0)
|
||||
//{
|
||||
// throw new Exception("");
|
||||
//}
|
||||
//var chatList = chatsToDelete.Where(t => t.UserId == _UserId && t.CharacterId == characterId && t.Type == 0).ToList();
|
||||
//if (chatList.Count > 0)
|
||||
//{
|
||||
// chatList.ForEach(t => t.Type = 2);
|
||||
//}
|
||||
//Dao.daoDbMiaoYu.context.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空聊天记录
|
||||
/// </summary>
|
||||
/// <param name="characterId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DelChat(int characterId)
|
||||
{
|
||||
//var tempList = await Dao.daoDbMiaoYu.context.T_Chat.Where(t => t.UserId == _UserId && t.CharacterId == characterId && t.IsDel == false).ToListAsync();
|
||||
//if (tempList.Count > 0)
|
||||
//{
|
||||
// tempList.ForEach(t => t.IsDel = true);
|
||||
//}
|
||||
//Dao.daoDbMiaoYu.context.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Contract;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// Claude3 通用参数
|
||||
/// </summary>
|
||||
public class BaseClaudeChatChatParams : BaseChatParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型
|
||||
/// </summary>
|
||||
public string Model { get; set; }
|
||||
/// <summary>
|
||||
/// 最大token数
|
||||
/// </summary>
|
||||
[JsonProperty("max_tokens")]
|
||||
public int MaxTokens { get; set; }
|
||||
/// <summary>
|
||||
/// 上下文
|
||||
/// </summary>
|
||||
public string System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public ClaudeChatMessage[] Messages { get; set; }
|
||||
}
|
||||
}
|
||||
130
src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChat.cs
Normal file
130
src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChat.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Contract;
|
||||
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using HuanMeng.MiaoYu.Code.Chat.Claude.Model;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// Claude3 https://docs.anthropic.com/en/api/messages ClaudeChatInfo
|
||||
/// </summary>
|
||||
public class ClaudeChat(ClaudeChatConfig claudeChatConfig, IHttpClientFactory factory) : IChat
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="chatParams"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task<BaseChatInfo> MessagesAsync(BaseChatParams chatParams)
|
||||
{
|
||||
var claudeChatChatParams = chatParams as ClaudeChatChatParams;
|
||||
if (claudeChatChatParams == null)
|
||||
{
|
||||
throw new ArgumentException("参数异常");
|
||||
}
|
||||
//添加默认值
|
||||
if (claudeChatChatParams.MaxTokens == 0)
|
||||
{
|
||||
claudeChatChatParams.MaxTokens = claudeChatConfig.MaxTokens;
|
||||
}
|
||||
//添加默认值
|
||||
if (!string.IsNullOrEmpty(claudeChatChatParams.Model))
|
||||
{
|
||||
claudeChatChatParams.Model = claudeChatChatParams.Model;
|
||||
}
|
||||
//去线程池里拿http线程
|
||||
using (var httpClient = factory.CreateClient())
|
||||
{
|
||||
// 设置请求头
|
||||
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
httpClient.DefaultRequestHeaders.Add("x-api-key", claudeChatConfig.ApiKey);
|
||||
httpClient.DefaultRequestHeaders.Add("anthropic-version", claudeChatConfig.AnthropicVersion);
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
string json = JsonConvert.SerializeObject(chatParams, settings);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var chatInfo = await response.Content.ReadFromJsonAsync<ClaudeChatResponse?>();
|
||||
return chatInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<string> MessagesStreamAsync(BaseChatParams chatParams)
|
||||
{
|
||||
var claudeChatChatParams = chatParams as ClaudeChatChatStreamParams;
|
||||
if (claudeChatChatParams == null)
|
||||
{
|
||||
throw new ArgumentException("参数异常");
|
||||
}
|
||||
//添加默认值
|
||||
if (claudeChatChatParams.MaxTokens == 0)
|
||||
{
|
||||
claudeChatChatParams.MaxTokens = claudeChatConfig.MaxTokens;
|
||||
}
|
||||
claudeChatChatParams.Stream = true;
|
||||
//添加默认值
|
||||
if (!string.IsNullOrEmpty(claudeChatChatParams.Model))
|
||||
{
|
||||
claudeChatChatParams.Model = claudeChatChatParams.Model;
|
||||
}
|
||||
//去线程池里拿http线程
|
||||
using (var httpClient = factory.CreateClient())
|
||||
{
|
||||
// 设置请求头
|
||||
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
httpClient.DefaultRequestHeaders.Add("x-api-key", claudeChatConfig.ApiKey);
|
||||
httpClient.DefaultRequestHeaders.Add("anthropic-version", claudeChatConfig.AnthropicVersion);
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
string json = JsonConvert.SerializeObject(chatParams, settings);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var chatInfo = await response.Content.ReadFromJsonAsync<ClaudeChatStreamResponse?>();
|
||||
if (chatInfo?.Type == "message_delta")
|
||||
{
|
||||
claudeChatChatParams.OutCharResponse.Usage.OutputTokens = chatInfo.Usage?.OutputTokens ?? 0;
|
||||
}
|
||||
else if (chatInfo?.Type == "content_block_start")
|
||||
{
|
||||
claudeChatChatParams.OutCharResponse = chatInfo?.Message ?? new ClaudeChatResponse();
|
||||
}
|
||||
else if (chatInfo?.Type == "content_block_delta")
|
||||
{
|
||||
var text = chatInfo?.Delta?.Text ?? "";
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
yield return text;
|
||||
}
|
||||
}
|
||||
claudeChatChatParams.OutObj.Add(chatInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Contract;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// Claude3 请求的参数
|
||||
/// </summary>
|
||||
public class ClaudeChatChatParams : BaseClaudeChatChatParams
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Claude.Model;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// 实时流
|
||||
/// </summary>
|
||||
public class ClaudeChatChatStreamParams : BaseClaudeChatChatParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 视频流
|
||||
/// </summary>
|
||||
public bool Stream { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回消息内容
|
||||
/// </summary>
|
||||
public ClaudeChatResponse OutCharResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<object> OutObj { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置类
|
||||
/// </summary>
|
||||
public class ClaudeChatConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型
|
||||
/// </summary>
|
||||
public string Model { get; set; }
|
||||
/// <summary>
|
||||
/// 最大token数
|
||||
/// </summary>
|
||||
public int MaxTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// api key
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型版本
|
||||
/// </summary>
|
||||
public string AnthropicVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求地址 = "api.gptsapi.net";
|
||||
/// </summary>
|
||||
public string RequestUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude
|
||||
{
|
||||
/// <summary>
|
||||
/// Claude发送消息内容
|
||||
/// </summary>
|
||||
public class ClaudeChatMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public string Role { get; set; }
|
||||
/// <summary>
|
||||
/// 内容
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public class ClaudeChatContent
|
||||
{
|
||||
/// <summary>
|
||||
/// 内容类型
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文本内容
|
||||
/// </summary>
|
||||
[JsonProperty("text")]
|
||||
public string Text { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Contract;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回内容
|
||||
/// </summary>
|
||||
public class ClaudeChatResponse : BaseChatInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息 ID
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型
|
||||
/// </summary>
|
||||
[JsonProperty("model")]
|
||||
public string Model { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息类型
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
[JsonProperty("content")]
|
||||
public ClaudeChatContent[] Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 停止原因
|
||||
/// </summary>
|
||||
[JsonProperty("stop_reason")]
|
||||
public string StopReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用情况
|
||||
/// </summary>
|
||||
[JsonProperty("usage")]
|
||||
public ClaudeChatUsage Usage { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using HuanMeng.MiaoYu.Code.Chat.Contract;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude.Model
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ClaudeChatStreamResponse : BaseChatStream
|
||||
{
|
||||
public int? Index { get; set; }
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容
|
||||
/// </summary>
|
||||
public ClaudeChatContent? Delta { get; set; }
|
||||
/// <summary>
|
||||
/// 结尾
|
||||
/// </summary>
|
||||
public ClaudeChatResponse? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用情况
|
||||
/// </summary>
|
||||
[JsonProperty("usage")]
|
||||
public ClaudeChatUsage Usage { get; set; }
|
||||
|
||||
}
|
||||
//delta
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Claude.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用情况
|
||||
/// </summary>
|
||||
public class ClaudeChatUsage
|
||||
{
|
||||
/// <summary>
|
||||
/// 输入的 token 数量
|
||||
/// </summary>
|
||||
[JsonProperty("input_tokens")]
|
||||
public int InputTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输出的 token 数量
|
||||
/// </summary>
|
||||
[JsonProperty("output_tokens")]
|
||||
public int OutputTokens { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天返回的实体类
|
||||
/// </summary>
|
||||
public class BaseChatInfo
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天请求参数
|
||||
/// </summary>
|
||||
public class BaseChatParams
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天实时流
|
||||
/// </summary>
|
||||
public class BaseChatStream
|
||||
{
|
||||
}
|
||||
}
|
||||
28
src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/IChat.cs
Normal file
28
src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/IChat.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Chat.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天接口
|
||||
/// </summary>
|
||||
public interface IChat
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="chatParams"></param>
|
||||
/// <returns></returns>
|
||||
Task<BaseChatInfo> MessagesAsync(BaseChatParams chatParams);
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="chatParams"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<string> MessagesStreamAsync(BaseChatParams chatParams);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,3 @@
|
|||
global using HuanMeng.MiaoYu.Code.Base;
|
||||
global using HuanMeng.MiaoYu.Code.Base;
|
||||
global using HuanMeng.MiaoYu.Code.DataAccess;
|
||||
global using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
|
|
|||
29
src/0-core/HuanMeng.MiaoYu.Code/Other/ImageExtend.cs
Normal file
29
src/0-core/HuanMeng.MiaoYu.Code/Other/ImageExtend.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Other
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片扩展类
|
||||
/// </summary>
|
||||
public static class ImageExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取图片地址
|
||||
/// </summary>
|
||||
/// <param name="configs"></param>
|
||||
/// <param name="imageId"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetImageUrl(this List<T_Image_Config> configs, int imageId)
|
||||
{
|
||||
if (imageId > 0 && configs != null && configs.Count > 0)
|
||||
{
|
||||
return configs.FirstOrDefault(it => it.ImageId == imageId)?.Url ?? "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,11 +38,56 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
|
|||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 人物表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Character> T_Character { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色标签表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Character_Label> T_Character_Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联角色和标签
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Character_Label_Relation> T_Character_Label_Relation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发现页类型分类
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Character_Type> T_Character_Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存储用户和角色之间的亲密值
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Character_User_Intimacy> T_Character_User_Intimacy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 聊天记录表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Chat> T_Chat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Image_Config> T_Image_Config { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public virtual DbSet<T_Model_Config> T_Model_Config { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_User> T_User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public virtual DbSet<T_User_Char> T_User_Char { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息表
|
||||
/// </summary>
|
||||
|
|
@ -63,6 +108,248 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
|
|||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<T_Character>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Charac__3214EC070A8D79B3");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("人物表"));
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.ValueGeneratedNever()
|
||||
.HasComment("人物id");
|
||||
entity.Property(e => e.BgImg).HasComment("背景图片");
|
||||
entity.Property(e => e.Biography)
|
||||
.HasMaxLength(500)
|
||||
.HasComment("人物简介");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Gender).HasComment("性别0男1女2其他");
|
||||
entity.Property(e => e.IconImg).HasComment("角色头像");
|
||||
entity.Property(e => e.ModelConfigId).HasComment("模型Id");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("人物名字");
|
||||
entity.Property(e => e.Prologue)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("开场白");
|
||||
entity.Property(e => e.System)
|
||||
.HasMaxLength(1000)
|
||||
.HasComment("人物初始设定");
|
||||
entity.Property(e => e.TenantId).HasComment("租户Id");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Visibility).HasComment("公开/私密 0公开 1私密");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Character_Label>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Charac__3214EC0777B5F217");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("角色标签表"));
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.ValueGeneratedNever()
|
||||
.HasComment("标签id");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.LabelName)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("标签名称");
|
||||
entity.Property(e => e.TenantId).HasComment("租户id");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Character_Label_Relation>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Charac__3214EC071FC16A53");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("关联角色和标签"));
|
||||
|
||||
entity.Property(e => e.Id).HasComment("人物和标签的关联id");
|
||||
entity.Property(e => e.CharacterId).HasComment("人物Id");
|
||||
entity.Property(e => e.CharacterLabelId).HasComment("人物标签id");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.TenantId).HasComment("租户id");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Character_Type>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Charac__3214EC070CC04F82");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("发现页类型分类"));
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.ValueGeneratedNever()
|
||||
.HasComment("类型id");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("类型名称");
|
||||
entity.Property(e => e.TenantId).HasComment("租户id");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Character_User_Intimacy>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Charac__3214EC079BEEBDEA");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("存储用户和角色之间的亲密值"));
|
||||
|
||||
entity.Property(e => e.Id).HasComment("亲密度id");
|
||||
entity.Property(e => e.CharacterId).HasComment("人物Id");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.IntimacyValue).HasComment("亲密值");
|
||||
entity.Property(e => e.TenantId).HasComment("租户id");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.UserId).HasComment("用户Id");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Chat>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Chat__3214EC079C2C8859");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("聊天记录表"));
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.ValueGeneratedNever()
|
||||
.HasComment("聊天id");
|
||||
entity.Property(e => e.CharacterId).HasComment("人物表Id");
|
||||
entity.Property(e => e.ClaudeId)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("聊天返回的Id");
|
||||
entity.Property(e => e.ClaudeModel)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("人物模型,聊天返回的模型");
|
||||
entity.Property(e => e.ClaudeType)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("聊天返回的消息的类型");
|
||||
entity.Property(e => e.Content)
|
||||
.HasMaxLength(1000)
|
||||
.HasComment("消息内容");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Input_tokens).HasComment("输入token");
|
||||
entity.Property(e => e.Output_tokens).HasComment("输出token");
|
||||
entity.Property(e => e.Role)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("user/assistant");
|
||||
entity.Property(e => e.SendDateDay).HasComment("发送消息,天");
|
||||
entity.Property(e => e.SendMessageDay).HasComment("发送消息时间戳");
|
||||
entity.Property(e => e.TenantId).HasComment("租户id");
|
||||
entity.Property(e => e.TimeStamp)
|
||||
.HasComment("发送时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Type).HasComment("0正常,1重新生成,2 删除");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("更新时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.UserId).HasComment("聊天内容");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Image_Config>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Image___3214EC072BCFE4E5");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("图片表"));
|
||||
|
||||
entity.Property(e => e.ImageId).HasComment("图片Id");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("图片名称");
|
||||
entity.Property(e => e.TenantId).HasComment("租户");
|
||||
entity.Property(e => e.Url)
|
||||
.HasMaxLength(500)
|
||||
.HasComment("图片地址");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_Model_Config>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_Model___3214EC074121E040");
|
||||
|
||||
entity.Property(e => e.AnthropicVersion)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("模型版本 anthropic-version");
|
||||
entity.Property(e => e.ApiKey)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("模型key x-api-key");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.MaxTokens).HasComment("模型运行最大的max_tokens");
|
||||
entity.Property(e => e.Model)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("模型model");
|
||||
entity.Property(e => e.ModelName)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("模型名称");
|
||||
entity.Property(e => e.TenantId).HasComment("租户");
|
||||
entity.Property(e => e.UpdateTime)
|
||||
.HasComment("修改时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Url)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("模型请求地址");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_User>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_User__3214EC073733108B");
|
||||
|
|
@ -106,6 +393,30 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
|
|||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_User_Char>(entity =>
|
||||
{
|
||||
entity.Property(e => e.CharacterId).HasComment("角色Id");
|
||||
entity.Property(e => e.CreateAt)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.IsDelete).HasComment("是否删除");
|
||||
entity.Property(e => e.ModelConfigId).HasComment("使用模型Id");
|
||||
entity.Property(e => e.SessionId).HasComment("会话Id");
|
||||
entity.Property(e => e.SessionName)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("会话名称");
|
||||
entity.Property(e => e.TenantId).HasComment("租户");
|
||||
entity.Property(e => e.UpdateAt)
|
||||
.HasComment("修改时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.UserId).HasComment("用户Id");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_User_Data>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.Id, e.UserId }).HasName("PK__T_User_D__E36C60C3D959FD89");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 人物表
|
||||
/// </summary>
|
||||
public partial class T_Character: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 人物id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物名字
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物简介
|
||||
/// </summary>
|
||||
public string? Biography { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开场白
|
||||
/// </summary>
|
||||
public string Prologue { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 模型Id
|
||||
/// </summary>
|
||||
public int ModelConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 公开/私密 0公开 1私密
|
||||
/// </summary>
|
||||
public bool Visibility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别0男1女2其他
|
||||
/// </summary>
|
||||
public int Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物初始设定
|
||||
/// </summary>
|
||||
public string? System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 背景图片
|
||||
/// </summary>
|
||||
public int? BgImg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色头像
|
||||
/// </summary>
|
||||
public int? IconImg { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 角色标签表
|
||||
/// </summary>
|
||||
public partial class T_Character_Label: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 标签id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 标签名称
|
||||
/// </summary>
|
||||
public string? LabelName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 关联角色和标签
|
||||
/// </summary>
|
||||
public partial class T_Character_Label_Relation: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 人物和标签的关联id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 人物Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物标签id
|
||||
/// </summary>
|
||||
public int CharacterLabelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 发现页类型分类
|
||||
/// </summary>
|
||||
public partial class T_Character_Type: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 存储用户和角色之间的亲密值
|
||||
/// </summary>
|
||||
public partial class T_Character_User_Intimacy: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 亲密度id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 人物Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 亲密值
|
||||
/// </summary>
|
||||
public int IntimacyValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 聊天记录表
|
||||
/// </summary>
|
||||
public partial class T_Chat: MultiTenantEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 聊天内容
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public string Content { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间
|
||||
/// </summary>
|
||||
public DateTime TimeStamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输入token
|
||||
/// </summary>
|
||||
public int Input_tokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输出token
|
||||
/// </summary>
|
||||
public int Output_tokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物表Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// user/assistant
|
||||
/// </summary>
|
||||
public string Role { get; set; } = null!;
|
||||
|
||||
public Guid SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息,天
|
||||
/// </summary>
|
||||
public long SendDateDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息时间戳
|
||||
/// </summary>
|
||||
public long SendMessageDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0正常,1重新生成,2 删除
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 聊天返回的消息的类型
|
||||
/// </summary>
|
||||
public string? ClaudeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 聊天返回的Id
|
||||
/// </summary>
|
||||
public string? ClaudeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物模型,聊天返回的模型
|
||||
/// </summary>
|
||||
public string? ClaudeModel { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
/// <summary>
|
||||
/// 图片表
|
||||
/// </summary>
|
||||
public partial class T_Image_Config: MultiTenantEntity
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 图片Id
|
||||
/// </summary>
|
||||
public int ImageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 图片地址
|
||||
/// </summary>
|
||||
public string Url { get; set; } = null!;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
public partial class T_Model_Config: MultiTenantEntity
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型名称
|
||||
/// </summary>
|
||||
public string ModelName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 模型model
|
||||
/// </summary>
|
||||
public string Model { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 模型运行最大的max_tokens
|
||||
/// </summary>
|
||||
public int MaxTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模型key x-api-key
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 模型请求地址
|
||||
/// </summary>
|
||||
public string Url { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 模型版本 anthropic-version
|
||||
/// </summary>
|
||||
public string AnthropicVersion { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
public partial class T_User_Char: MultiTenantEntity
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会话Id
|
||||
/// </summary>
|
||||
public Guid SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会话名称
|
||||
/// </summary>
|
||||
public string SessionName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用模型Id
|
||||
/// </summary>
|
||||
public int ModelConfigId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime UpdateAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否删除
|
||||
/// </summary>
|
||||
public bool IsDelete { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Character
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色聊天次数
|
||||
/// </summary>
|
||||
public class CharacteChatCountModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 聊天次数
|
||||
/// </summary>
|
||||
public int UserCount { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using AutoMapper;
|
||||
|
||||
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Label;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Character
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型
|
||||
/// </summary>
|
||||
[AutoMap(typeof(T_Character))]
|
||||
public class CharacterCache : T_Character
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型配置
|
||||
/// </summary>
|
||||
public T_Model_Config ModelConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多少人聊天过
|
||||
/// </summary>
|
||||
public int LookCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 背景图片
|
||||
/// </summary>
|
||||
public string BgImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户头像url
|
||||
/// </summary>
|
||||
public string IconImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public List<LabelDto> Label { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Character
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RequestCharacterInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Character
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求参数
|
||||
/// </summary>
|
||||
public class RequestCharacterInfoPage
|
||||
{
|
||||
/// <summary>
|
||||
/// 起始页
|
||||
/// </summary>
|
||||
public int? Index { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 页大小
|
||||
/// </summary>
|
||||
public int? Size { get; set; } = 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
139
src/0-core/HuanMeng.MiaoYu.Model/Dto/Chat/CharacterInfoDto.cs
Normal file
139
src/0-core/HuanMeng.MiaoYu.Model/Dto/Chat/CharacterInfoDto.cs
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
using AutoMapper;
|
||||
using AutoMapper.Configuration.Annotations;
|
||||
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Label;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Chat
|
||||
{
|
||||
public class CharacterInfo
|
||||
{
|
||||
public List<CharacterInfoDto> CharacterInfos { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 用户和人物信息
|
||||
/// </summary>
|
||||
[AutoMap(typeof(CharacterCache))]
|
||||
public class CharacterInfoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
[SourceMember(nameof(CharacterCache.IconImage))]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 亲密值
|
||||
/// </summary>
|
||||
public int Intimacy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物id
|
||||
/// </summary>
|
||||
[SourceMember(nameof(CharacterCache.Id))]
|
||||
public int CharacterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物名称
|
||||
/// </summary>
|
||||
[SourceMember(nameof(CharacterCache.Name))]
|
||||
public string CharacterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
|
||||
public int Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有多少人看过
|
||||
/// </summary>
|
||||
public int LookCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 背景图片
|
||||
/// </summary>
|
||||
[SourceMember(nameof(CharacterCache.BgImage))]
|
||||
public string BgUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 简介
|
||||
/// </summary>
|
||||
|
||||
public string Biography { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开场白
|
||||
/// </summary>
|
||||
public string Prologue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
[SourceMember(nameof(CharacterCache.Label))]
|
||||
public List<LabelDto> Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 余下聊天次数
|
||||
/// </summary>
|
||||
//public int RemainingChatCount { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 聊天列表信息
|
||||
/// </summary>
|
||||
public class ChatMessageDto
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Role { get; set; }
|
||||
public string Content { get; set; }
|
||||
public DateTime Timestamp { get; set; }
|
||||
public int MessageType { get; set; }
|
||||
public string UserIcon { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 聊天列表
|
||||
/// </summary>
|
||||
public class ChatListDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天列表
|
||||
/// </summary>
|
||||
public List<ChatMessageDto> ChatList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除聊天
|
||||
/// </summary>
|
||||
public class DelChat
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天记录id
|
||||
/// </summary>
|
||||
public List<int> Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 人物id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空聊天记录
|
||||
/// </summary>
|
||||
public class DelChatList
|
||||
{
|
||||
/// <summary>
|
||||
/// 人物id
|
||||
/// </summary>
|
||||
public int CharacterId { get; set; }
|
||||
}
|
||||
}
|
||||
32
src/0-core/HuanMeng.MiaoYu.Model/Dto/Label/LabelDto.cs
Normal file
32
src/0-core/HuanMeng.MiaoYu.Model/Dto/Label/LabelDto.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using AutoMapper;
|
||||
using AutoMapper.Configuration.Annotations;
|
||||
|
||||
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.Dto.Label
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 人物角色标签
|
||||
/// </summary>
|
||||
[AutoMap(typeof(T_Character_Label))]
|
||||
public class LabelDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// 标签名称
|
||||
/// </summary>
|
||||
[SourceMember(nameof(T_Character_Label.LabelName))]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,11 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<AnalysisLevel>latest</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
@ -19,7 +21,7 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using HuanMeng.StableDiffusion.TextGeneration.api;
|
||||
using HuanMeng.StableDiffusion.TextGeneration.api;
|
||||
using HuanMeng.StableDiffusion.TextGeneration.Models;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using HuanMeng.StableDiffusion.TextGeneration.Abstractions;
|
||||
using HuanMeng.StableDiffusion.TextGeneration.Abstractions;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
|
@ -30,6 +30,7 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api
|
|||
}
|
||||
public override async IAsyncEnumerable<string> SendMessageAsync()
|
||||
{
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
// 设置请求头
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ namespace HuanMeng.Utility.AssemblyHelper
|
|||
// 创建并填充 AssemblyInfo 对象的相关属性
|
||||
var assemblyInfo = new AssemblyInfo
|
||||
{
|
||||
Version = assembly.GetCustomAttributes<AssemblyVersionAttribute>().FirstOrDefault()?.Version ?? "",
|
||||
Version = assembly.GetName().Version.ToString(),
|
||||
FileVersion = assembly.GetCustomAttributes<AssemblyFileVersionAttribute>().FirstOrDefault()?.Version ?? "",
|
||||
AssemblyVersion = assembly.GetName().Version.ToString(),
|
||||
AssemblyVersion = assembly.GetCustomAttributes<AssemblyVersionAttribute>().FirstOrDefault()?.Version ?? "",
|
||||
InformationalVersion = assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().FirstOrDefault()?.InformationalVersion ?? "",
|
||||
//Company = assembly.GetCustomAttributes<AssemblyCompanyAttribute>().FirstOrDefault()?.Company ?? "",
|
||||
//Product = assembly.GetCustomAttributes<AssemblyProductAttribute>().FirstOrDefault()?.Product ?? "",
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace HuanMeng.Utility
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Code.Other
|
||||
namespace HuanMeng.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
|
|
@ -6,6 +6,7 @@ using HuanMeng.MiaoYu.Code.Users;
|
|||
using HuanMeng.MiaoYu.Model.Dto;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Account;
|
||||
using HuanMeng.MiaoYu.WebApi.Base;
|
||||
using HuanMeng.Utility;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
|
@ -24,15 +25,17 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
|
|||
[ApiController]
|
||||
public class AccountController : MiaoYuControllerBase
|
||||
{
|
||||
public AccountController(IServiceProvider _serviceProvider) : base(_serviceProvider)
|
||||
public AccountController(IServiceProvider _serviceProvider, ILogger<AccountController> logger) : base(_serviceProvider)
|
||||
{
|
||||
logger.LogInformation("aaaaa");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送手机号验证码
|
||||
/// 发送手机号验证码
|
||||
/// </summary>
|
||||
/// <param name="PhoneNumber">手机号</param>
|
||||
/// <param name="phone"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[HttpPost]
|
||||
public async Task<BaseResponse<bool>> SendPhoneNumber([FromBody] RequestPhoneNumberModel phone)
|
||||
{
|
||||
|
|
|
|||
108
src/2-api/HuanMeng.MiaoYu.WebApi/Controllers/ChatController.cs
Normal file
108
src/2-api/HuanMeng.MiaoYu.WebApi/Controllers/ChatController.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using HuanMeng.DotNetCore.Base;
|
||||
using HuanMeng.MiaoYu.Code.Character;
|
||||
using HuanMeng.MiaoYu.Code.Chat;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Character;
|
||||
using HuanMeng.MiaoYu.Model.Dto.Chat;
|
||||
using HuanMeng.MiaoYu.WebApi.Base;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace HuanMeng.MiaoYu.WebApi.Controllers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 首页聊天
|
||||
/// </summary>
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ChatController : MiaoYuControllerBase
|
||||
{
|
||||
private ChatBLL _chatBLL;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="_serviceProvider"></param>
|
||||
public ChatController(IServiceProvider _serviceProvider) : base(_serviceProvider)
|
||||
{
|
||||
_chatBLL = new ChatBLL(_serviceProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色Id
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public BaseResponse<List<int>> GetCharacterIdList()
|
||||
{
|
||||
CharacterBLL characterBLL = new CharacterBLL(ServiceProvider);
|
||||
var obj = characterBLL.GetCharacters();
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色人物信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public async Task<BaseResponse<CharacterInfoDto>> GetCharacterInfo([FromQuery] RequestCharacterInfo requestCharacterInfo)
|
||||
{
|
||||
CharacterBLL characterBLL = new CharacterBLL(ServiceProvider);
|
||||
var obj = await characterBLL.GetCharacterInfo(requestCharacterInfo);
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取聊天列表信息
|
||||
/// </summary>
|
||||
/// <param name="characterId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public async Task<BaseResponse<ChatListDto>> GetChatInfo(int characterId)
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<ChatListDto>("{\"ChatList\":[{\"Id\":\"1\",\"Role\":\"user\",\"Content\":\"Hello, how are you?\",\"Timestamp\":\"2022-03-01 12:00:00 \",\"MessageType\":0,\"UserIcon\":\"\"},{\"Id\":\"2\",\"Role\":\"assistant\",\"Content\":\"I'm fine, thanks!\",\"Timestamp\":\"2022-03-01 12:05:00 \",\"UserIcon\":\"\"}]}");
|
||||
return new BaseResponse<ChatListDto>(ResonseCode.Success, "", obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除聊天记录
|
||||
/// </summary>
|
||||
/// <param name="delChat"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<BaseResponse<bool>> DelChatByIds([FromBody] DelChat delChat)
|
||||
{
|
||||
if (delChat.Id == null || delChat.CharacterId == 0)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
//ChatBLL chatBLL = new ChatBLL(ServiceProvider);
|
||||
var obj = await _chatBLL.DelChatByIds(delChat.Id, delChat.CharacterId);
|
||||
return new BaseResponse<bool>(ResonseCode.Success, "", obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空聊天记录
|
||||
/// </summary>
|
||||
/// <param name="characterId">人物id</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<BaseResponse<bool>> DelChat([FromBody] DelChatList delChatList)
|
||||
{
|
||||
//ChatBLL chatBLL = new ChatBLL(ServiceProvider);
|
||||
var obj = await _chatBLL.DelChat(delChatList.CharacterId);
|
||||
return new BaseResponse<bool>(ResonseCode.Success, "", obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,10 @@
|
|||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,30 +9,42 @@ using HuanMeng.MiaoYu.Code.Users.UserAccount.VerificationCodeManager;
|
|||
using HuanMeng.MiaoYu.Code.JwtUtil;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using HuanMeng.Utility.AssemblyHelper;
|
||||
using HuanMeng.DotNetCore.CustomExtension;
|
||||
using HuanMeng.MiaoYu.Code.Cache;
|
||||
using HuanMeng.MiaoYu.Code.Chat;
|
||||
using Serilog;
|
||||
using HuanMeng.MiaoYu.Model.Dto;
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
//Log.Logger = new LoggerConfiguration()
|
||||
// .WriteTo.Console()
|
||||
// .WriteTo.File("../output/logs/log-.txt", rollingInterval: RollingInterval.Day)
|
||||
// .CreateLogger();
|
||||
builder.Host.UseSerilog((context, services, configuration) => configuration
|
||||
.ReadFrom.Configuration(context.Configuration)
|
||||
.ReadFrom.Services(services)
|
||||
.Enrich.FromLogContext());
|
||||
// 检索程序集信息
|
||||
AssemblyInfo assemblyInfo = AssemblyInfoHelper.GetAssemblyInfo();
|
||||
// Add services to the container.
|
||||
// Add services to the container.
|
||||
builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问
|
||||
#region 添加跨域
|
||||
var _myAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
options.AddPolicy(_myAllowSpecificOrigins,
|
||||
builder =>
|
||||
{
|
||||
//builder.AllowAnyHeader().AllowAnyMethod().
|
||||
//AllowAnyOrigin();
|
||||
//builder.AllowAnyHeader()
|
||||
// .AllowAnyMethod()
|
||||
// .SetIsOriginAllowed((host) => true)//限制允许跨域请求的特定源
|
||||
// .AllowCredentials();//允许跨域请求发送凭据,如 Cookies、HTTP 认证信息等。启用该配置可能会增加安全风险,因为浏览器会在请求头中包含凭据信息。因此,在设置 AllowCredentials 时,应该确保服务器端的安全性,并且仅允许受信任的源发送包含凭据的请求。
|
||||
builder.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyOrigin();// 许来自任意源的跨域请求
|
||||
}));
|
||||
builder.Services.AddCustomCors(_myAllowSpecificOrigins);
|
||||
#endregion
|
||||
#region automap
|
||||
var mapperDomain = AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("HuanMeng") || it.FullName.Contains("XLib.")).ToList();
|
||||
Type type = typeof(ResponseUserInfo);
|
||||
if (type != null)
|
||||
{
|
||||
Assembly assembly = Assembly.GetAssembly(type);
|
||||
if (!mapperDomain.Any(it => it.FullName == assembly.FullName))
|
||||
{
|
||||
mapperDomain.Add(assembly);
|
||||
}
|
||||
}
|
||||
|
||||
builder.Services.AddAutoMapper(mapperDomain);
|
||||
#endregion
|
||||
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("HuanMeng") || it.FullName.Contains("XLib.")).ToList());
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
|
|
@ -73,6 +85,8 @@ builder.Services.AddSwaggerGen(c =>
|
|||
c.ParameterFilter<LowercaseParameterFilter>();
|
||||
c.RequestBodyFilter<LowercaseRequestFilter>();
|
||||
});
|
||||
//配置路由选项,使URL全部小写
|
||||
builder.Services.AddRouting(options => options.LowercaseUrls = true);
|
||||
//添加多租户
|
||||
builder.AddMultiTenantMiaoYu();
|
||||
//添加腾讯云管理
|
||||
|
|
@ -81,6 +95,9 @@ builder.AddTencent();
|
|||
builder.AddMemoryVerificationCode();
|
||||
//添加jwt验证
|
||||
builder.AddJwtConfig();
|
||||
//builder.Services.AddMemoryCache();
|
||||
//builder.Services.AddScoped<CharacterInfoBaseCache>();
|
||||
////builder.Services.AddScoped<ChatBLL>();
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
|
@ -94,11 +111,11 @@ app.UseSwaggerUI(c =>
|
|||
c.DefaultModelsExpandDepth(3);
|
||||
c.DefaultModelExpandDepth(3);
|
||||
c.EnableFilter("true");
|
||||
//c.RoutePrefix = "swagger";
|
||||
//c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1");
|
||||
//c.RoutePrefix = string.Empty;
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "寰梦 API V1");
|
||||
});
|
||||
//}
|
||||
|
||||
app.UseSerilogRequestLogging();
|
||||
app.UseAuthorization();
|
||||
//自定义初始化
|
||||
//使用跨域
|
||||
|
|
|
|||
|
|
@ -8,6 +8,27 @@
|
|||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{ "Name": "Console" },
|
||||
{
|
||||
"Name": "File",
|
||||
"Args": {
|
||||
"path": "../output/logs/log-.txt",
|
||||
"rollingInterval": "Day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
|
||||
},
|
||||
//腾讯云配置
|
||||
"TencentCloud": {
|
||||
"SecretId": "AKIDLbhdP0Vs57yd7QZWu8A2jFbno8JKBUp6",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ var builder = WebApplication.CreateBuilder(args);
|
|||
// Add services to the container.
|
||||
builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
//注入数据库
|
||||
builder.Services.AddDbContext<TextGenerationTestContext>((options) =>
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user