feat: 完成对接接口
This commit is contained in:
@@ -15,14 +15,15 @@ using Yi.Framework.SqlSugarCore.Abstractions;
|
|||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Repositories
|
namespace Yi.Framework.SqlSugarCore.Repositories
|
||||||
{
|
{
|
||||||
public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity>, IRepository<TEntity> where TEntity : class, IEntity, new()
|
public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity>, IRepository<TEntity>
|
||||||
|
where TEntity : class, IEntity, new()
|
||||||
{
|
{
|
||||||
public ISqlSugarClient _Db => AsyncContext.Run(async () => await GetDbContextAsync());
|
public ISqlSugarClient _Db => AsyncContext.Run(async () => await GetDbContextAsync());
|
||||||
|
|
||||||
public ISugarQueryable<TEntity> _DbQueryable => _Db.Queryable<TEntity>();
|
public ISugarQueryable<TEntity> _DbQueryable => _Db.Queryable<TEntity>();
|
||||||
|
|
||||||
private readonly ISugarDbContextProvider<ISqlSugarDbContext> _dbContextProvider;
|
private readonly ISugarDbContextProvider<ISqlSugarDbContext> _dbContextProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步查询执行器
|
/// 异步查询执行器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -58,22 +59,26 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
|
|
||||||
#region Abp模块
|
#region Abp模块
|
||||||
|
|
||||||
public virtual async Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate,
|
||||||
|
bool includeDetails = true, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetFirstAsync(predicate);
|
return await GetFirstAsync(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate,
|
||||||
|
bool includeDetails = true, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetFirstAsync(predicate);
|
return await GetFirstAsync(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await this.DeleteAsync(predicate);
|
await this.DeleteAsync(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await this.DeleteAsync(predicate);
|
await this.DeleteAsync(predicate);
|
||||||
}
|
}
|
||||||
@@ -103,60 +108,71 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, CancellationToken cancellationToken = default)
|
public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate,
|
||||||
|
bool includeDetails = false, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetListAsync(predicate);
|
return await GetListAsync(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await InsertReturnEntityAsync(entity);
|
return await InsertReturnEntityAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await InsertRangeAsync(entities.ToList());
|
await InsertRangeAsync(entities.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await UpdateAsync(entity);
|
await UpdateAsync(entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await UpdateRangeAsync(entities.ToList());
|
await UpdateRangeAsync(entities.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await DeleteAsync(entity);
|
await DeleteAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await DeleteAsync(entities.ToList());
|
await DeleteAsync(entities.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
|
public virtual async Task<List<TEntity>> GetListAsync(bool includeDetails = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetListAsync();
|
return await GetListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
|
public virtual async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await this.CountAsync(_=>true);
|
return await this.CountAsync(_ => true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default)
|
public virtual async Task<List<TEntity>> GetPagedListAsync(int skipCount, int maxResultCount, string sorting,
|
||||||
|
bool includeDetails = false, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetPageListAsync(_ => true, skipCount, maxResultCount);
|
return await GetPageListAsync(_ => true, skipCount, maxResultCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region 内置DB快捷操作
|
#region 内置DB快捷操作
|
||||||
|
|
||||||
public virtual async Task<IDeleteable<TEntity>> AsDeleteable()
|
public virtual async Task<IDeleteable<TEntity>> AsDeleteable()
|
||||||
{
|
{
|
||||||
return (await GetDbSimpleClientAsync()).AsDeleteable();
|
return (await GetDbSimpleClientAsync()).AsDeleteable();
|
||||||
@@ -171,7 +187,7 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
return (await GetDbSimpleClientAsync()).AsInsertable(insertObj);
|
return (await GetDbSimpleClientAsync()).AsInsertable(insertObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IInsertable<TEntity>> AsInsertable(TEntity[] insertObjs)
|
public virtual async Task<IInsertable<TEntity>> AsInsertable(TEntity[] insertObjs)
|
||||||
{
|
{
|
||||||
return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs);
|
return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs);
|
||||||
@@ -211,9 +227,11 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs);
|
return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SimpleClient模块
|
#region SimpleClient模块
|
||||||
|
|
||||||
public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression)
|
public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).CountAsync(whereExpression);
|
return await (await GetDbSimpleClientAsync()).CountAsync(whereExpression);
|
||||||
@@ -230,7 +248,6 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObj);
|
return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteAsync(List<TEntity> deleteObjs)
|
public virtual async Task<bool> DeleteAsync(List<TEntity> deleteObjs)
|
||||||
@@ -250,13 +267,13 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).AsUpdateable().SetColumns(nameof(ISoftDelete.IsDeleted), true).Where(whereExpression).ExecuteCommandAsync() > 0;
|
return await (await GetDbSimpleClientAsync()).AsUpdateable()
|
||||||
|
.SetColumns(nameof(ISoftDelete.IsDeleted), true).Where(whereExpression).ExecuteCommandAsync() > 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteAsync(whereExpression);
|
return await (await GetDbSimpleClientAsync()).DeleteAsync(whereExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteByIdAsync(dynamic id)
|
public virtual async Task<bool> DeleteByIdAsync(dynamic id)
|
||||||
@@ -264,6 +281,11 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
||||||
{
|
{
|
||||||
var entity = await GetByIdAsync(id);
|
var entity = await GetByIdAsync(id);
|
||||||
|
if (entity is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//反射赋值
|
//反射赋值
|
||||||
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
|
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
|
||||||
return await UpdateAsync(entity);
|
return await UpdateAsync(entity);
|
||||||
@@ -284,6 +306,7 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//反射赋值
|
//反射赋值
|
||||||
entities.ForEach(e => ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e));
|
entities.ForEach(e => ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e));
|
||||||
return await UpdateRangeAsync(entities);
|
return await UpdateRangeAsync(entities);
|
||||||
@@ -292,7 +315,6 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(ids);
|
return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetByIdAsync(dynamic id)
|
public virtual async Task<TEntity> GetByIdAsync(dynamic id)
|
||||||
@@ -301,7 +323,6 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression)
|
public virtual async Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).GetFirstAsync(whereExpression);
|
return await (await GetDbSimpleClientAsync()).GetFirstAsync(whereExpression);
|
||||||
@@ -317,14 +338,19 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
return await (await GetDbSimpleClientAsync()).GetListAsync(whereExpression);
|
return await (await GetDbSimpleClientAsync()).GetListAsync(whereExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize)
|
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression,
|
||||||
|
int pageNum, int pageSize)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel() { PageIndex = pageNum, PageSize = pageSize });
|
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression,
|
||||||
|
new PageModel() { PageIndex = pageNum, PageSize = pageSize });
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize, Expression<Func<TEntity, object>>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
|
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression,
|
||||||
|
int pageNum, int pageSize, Expression<Func<TEntity, object>>? orderByExpression = null,
|
||||||
|
OrderByType orderByType = OrderByType.Asc)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType);
|
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression,
|
||||||
|
new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> whereExpression)
|
public virtual async Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
@@ -379,30 +405,31 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
|
|
||||||
public virtual async Task<bool> UpdateAsync(TEntity updateObj)
|
public virtual async Task<bool> UpdateAsync(TEntity updateObj)
|
||||||
{
|
{
|
||||||
if (typeof(TEntity).IsAssignableTo<IHasConcurrencyStamp>())//带版本号乐观锁更新
|
if (typeof(TEntity).IsAssignableTo<IHasConcurrencyStamp>()) //带版本号乐观锁更新
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int num = await (await GetDbSimpleClientAsync())
|
int num = await (await GetDbSimpleClientAsync())
|
||||||
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
|
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
|
||||||
return num>0;
|
return num > 0;
|
||||||
}
|
}
|
||||||
catch (VersionExceptions ex)
|
catch (VersionExceptions ex)
|
||||||
{
|
{
|
||||||
|
throw new AbpDbConcurrencyException(
|
||||||
throw new AbpDbConcurrencyException($"{ex.Message}[更新失败:ConcurrencyStamp不是最新版本],entityInfo:{updateObj}", ex);
|
$"{ex.Message}[更新失败:ConcurrencyStamp不是最新版本],entityInfo:{updateObj}", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
|
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression)
|
public virtual async Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns,
|
||||||
|
Expression<Func<TEntity, bool>> whereExpression)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(columns, whereExpression);
|
return await (await GetDbSimpleClientAsync()).UpdateAsync(columns, whereExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual async Task<bool> UpdateRangeAsync(List<TEntity> updateObjs)
|
public virtual async Task<bool> UpdateRangeAsync(List<TEntity> updateObjs)
|
||||||
{
|
{
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(updateObjs);
|
return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(updateObjs);
|
||||||
@@ -411,30 +438,36 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SqlSugarRepository<TEntity, TKey> : SqlSugarRepository<TEntity>, ISqlSugarRepository<TEntity, TKey>, IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>, new()
|
public class SqlSugarRepository<TEntity, TKey> : SqlSugarRepository<TEntity>, ISqlSugarRepository<TEntity, TKey>,
|
||||||
|
IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>, new()
|
||||||
{
|
{
|
||||||
public SqlSugarRepository(ISugarDbContextProvider<ISqlSugarDbContext> sugarDbContextProvider) : base(sugarDbContextProvider)
|
public SqlSugarRepository(ISugarDbContextProvider<ISqlSugarDbContext> sugarDbContextProvider) : base(
|
||||||
|
sugarDbContextProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteAsync(TKey id, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await DeleteByIdAsync(id);
|
await DeleteByIdAsync(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
|
public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await DeleteByIdsAsync(ids.Select(x => (object)x).ToArray());
|
await DeleteByIdsAsync(ids.Select(x => (object)x).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity?> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity?> FindAsync(TKey id, bool includeDetails = true,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetByIdAsync(id);
|
return await GetByIdAsync(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await GetByIdAsync(id);
|
return await GetByIdAsync(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,5 @@ public class SessionCreateAndUpdateInput
|
|||||||
{
|
{
|
||||||
public string SessionTitle { get; set; }
|
public string SessionTitle { get; set; }
|
||||||
public string SessionContent { get; set; }
|
public string SessionContent { get; set; }
|
||||||
public string Remark { get; set; }
|
public string? Remark { get; set; }
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ public class AiChatService : ApplicationService
|
|||||||
var history = new List<ChatMessage>();
|
var history = new List<ChatMessage>();
|
||||||
foreach (var aiChatContextDto in input.Messages)
|
foreach (var aiChatContextDto in input.Messages)
|
||||||
{
|
{
|
||||||
if (aiChatContextDto.Role == "ai")
|
if (aiChatContextDto.Role == "system")
|
||||||
{
|
{
|
||||||
history.Add(ChatMessage.CreateAssistantMessage(aiChatContextDto.Content));
|
history.Add(ChatMessage.CreateAssistantMessage(aiChatContextDto.Content));
|
||||||
}
|
}
|
||||||
@@ -100,23 +100,23 @@ public class AiChatService : ApplicationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gateWay = LazyServiceProvider.GetRequiredService<AiGateWayManager>();
|
var gateWay = LazyServiceProvider.GetRequiredService<AiGateWayManager>();
|
||||||
var completeChatResponse = gateWay.CompleteChatAsync(input.Model, history, cancellationToken);
|
// var completeChatResponse = gateWay.CompleteChatAsync(input.Model, history, cancellationToken);
|
||||||
await using var writer = new StreamWriter(response.Body, Encoding.UTF8, leaveOpen: true);
|
// await using var writer = new StreamWriter(response.Body, Encoding.UTF8, leaveOpen: true);
|
||||||
await foreach (var data in completeChatResponse)
|
// await foreach (var data in completeChatResponse)
|
||||||
{
|
// {
|
||||||
var model = MapToMessage(input.Model, data);
|
// var model = MapToMessage(input.Model, data);
|
||||||
var message = JsonConvert.SerializeObject(model, new JsonSerializerSettings
|
// var message = JsonConvert.SerializeObject(model, new JsonSerializerSettings
|
||||||
{
|
// {
|
||||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
// ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
await writer.WriteLineAsync($"data: {message}\n");
|
// await writer.WriteLineAsync($"data: {message}\n");
|
||||||
await writer.FlushAsync(cancellationToken); // 确保立即推送数据
|
// await writer.FlushAsync(cancellationToken); // 确保立即推送数据
|
||||||
}
|
// }
|
||||||
|
|
||||||
//断开连接
|
//断开连接
|
||||||
await writer.WriteLineAsync($"data: done\n");
|
// await writer.WriteLineAsync("data: done\n");
|
||||||
await writer.FlushAsync(cancellationToken); // 确保立即推送数据
|
// await writer.FlushAsync(cancellationToken); // 确保立即推送数据
|
||||||
|
|
||||||
if (CurrentUser.IsAuthenticated && input.SessionId.HasValue)
|
if (CurrentUser.IsAuthenticated && input.SessionId.HasValue)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ public class SessionAggregateRoot : FullAuditedAggregateRoot<Guid>
|
|||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
public string SessionTitle { get; set; }
|
public string SessionTitle { get; set; }
|
||||||
public string SessionContent { get; set; }
|
public string SessionContent { get; set; }
|
||||||
public string Remark { get; set; }
|
public string? Remark { get; set; }
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,8 @@ VITE_WEB_ENV = 'development'
|
|||||||
VITE_WEB_BASE_API = '/dev-api'
|
VITE_WEB_BASE_API = '/dev-api'
|
||||||
|
|
||||||
# 本地接口
|
# 本地接口
|
||||||
# VITE_API_URL = http://122.51.75.95:6039
|
VITE_API_URL = http://localhost:19001/api/app
|
||||||
VITE_API_URL=http://129.211.24.7:6039
|
#VITE_API_URL = http://ccnetcore.com:19001/api/app
|
||||||
# VITE_API_URL = https://ccnetcore.com
|
|
||||||
# VITE_API_URL = https://mp.pandarobot.chat
|
|
||||||
|
|
||||||
# SSO单点登录url
|
# SSO单点登录url
|
||||||
SSO_SEVER_URL='http://localhost:18001'
|
SSO_SEVER_URL='http://localhost:18001'
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ VITE_WEB_ENV = 'production'
|
|||||||
# 生产环境
|
# 生产环境
|
||||||
VITE_WEB_BASE_API = '/prod-api'
|
VITE_WEB_BASE_API = '/prod-api'
|
||||||
|
|
||||||
|
# 本地接口
|
||||||
|
VITE_API_URL = http://ccnetcore.com:19001/api/app
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
# VITE_API_URL = http://122.51.75.95:6039
|
|
||||||
# VITE_API_URL = http://129.211.24.7:6039
|
|
||||||
VITE_API_URL = https://mp.pandarobot.chat
|
|
||||||
# SSO单点登录url
|
# SSO单点登录url
|
||||||
SSO_SEVER_URL='https://ccnetcore.com'
|
SSO_SEVER_URL='https://ccnetcore.com'
|
||||||
# SSO单点登录项目标识
|
# SSO单点登录项目标识
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { ChatMessageVo, GetChatListParams, SendDTO } from './types';
|
|||||||
import { get, post } from '@/utils/request';
|
import { get, post } from '@/utils/request';
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
export const send = (data: SendDTO) => post<null>('/prod-api/ai-chat/send', data);
|
export const send = (data: SendDTO) => post<null>('/ai-chat/send', data);
|
||||||
// export const send = (data: SendDTO) => post<null>('/chat/send', data);
|
// export const send = (data: SendDTO) => post<null>('/chat/send', data);
|
||||||
|
|
||||||
// 新增对应会话聊天记录
|
// 新增对应会话聊天记录
|
||||||
@@ -13,5 +13,5 @@ export function addChat(data: ChatMessageVo) {
|
|||||||
// 获取当前会话的聊天记录
|
// 获取当前会话的聊天记录
|
||||||
export function getChatList(params: GetChatListParams) {
|
export function getChatList(params: GetChatListParams) {
|
||||||
// return get<ChatMessageVo[]>('/system/message/list', params);
|
// return get<ChatMessageVo[]>('/system/message/list', params);
|
||||||
return get<ChatMessageVo[]>('/prod-api/message', params);
|
return get<ChatMessageVo[]>('/message', params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import { get } from '@/utils/request';
|
|||||||
// 获取当前用户的模型列表
|
// 获取当前用户的模型列表
|
||||||
export function getModelList() {
|
export function getModelList() {
|
||||||
// return get<GetSessionListVO[]>('/system/model/modelList');
|
// return get<GetSessionListVO[]>('/system/model/modelList');
|
||||||
return get<GetSessionListVO[]>('/prod-api/ai-chat/model');
|
return get<GetSessionListVO[]>('/ai-chat/model');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ import { del, get, post, put } from '@/utils/request';
|
|||||||
// 获取会话列表
|
// 获取会话列表
|
||||||
export function get_session_list(params: GetSessionListParams) {
|
export function get_session_list(params: GetSessionListParams) {
|
||||||
// return get<ChatSessionVo[]>('/system/session/list', params);
|
// return get<ChatSessionVo[]>('/system/session/list', params);
|
||||||
return get<ChatSessionVo[]>('/prod-api/session', params);
|
return get<ChatSessionVo[]>('/session', params);
|
||||||
}
|
}
|
||||||
// 创建会话
|
// 创建会话
|
||||||
export function create_session(data: CreateSessionDTO) {
|
export function create_session(data: CreateSessionDTO) {
|
||||||
return post('/prod-api/session', data);
|
return post('/session', data);
|
||||||
}
|
}
|
||||||
// 更新会话
|
// 更新会话
|
||||||
export function update_session(data: ChatSessionVo) {
|
export function update_session(data: ChatSessionVo) {
|
||||||
return put('/prod-api/session', data);
|
return put(`/session/${data.id}`, data);
|
||||||
}
|
}
|
||||||
// 会话详情
|
// 会话详情
|
||||||
export function get_session(id: string) {
|
export function get_session(id: string) {
|
||||||
return get<ChatSessionVo>(`/prod-api/session/${id}`);
|
return get<ChatSessionVo>(`/session/${id}`);
|
||||||
}
|
}
|
||||||
// 删除会话
|
// 删除会话
|
||||||
export function delete_session(ids: string[]) {
|
export function delete_session(ids: string[]) {
|
||||||
return del(`/prod-api/session/${ids}`);
|
return del(`/session/${ids[0]}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ export interface GetSessionListParams {
|
|||||||
/**
|
/**
|
||||||
* 当前页数
|
* 当前页数
|
||||||
*/
|
*/
|
||||||
pageNum?: number;
|
skipCount?: number;
|
||||||
/**
|
/**
|
||||||
* 分页大小
|
* 分页大小
|
||||||
*/
|
*/
|
||||||
pageSize?: number;
|
maxResultCount?: number;
|
||||||
/**
|
/**
|
||||||
* 请求参数
|
* 请求参数
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ import { get } from '@/utils/request';
|
|||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
export function getUserInfo() {
|
export function getUserInfo() {
|
||||||
return get<any>('/prod-api/ai-chat/account');
|
return get<any>('/ai-chat/account');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ function handleThirdPartyLogin() {
|
|||||||
<div class="left-section">
|
<div class="left-section">
|
||||||
<div class="logo-wrap">
|
<div class="logo-wrap">
|
||||||
<img :src="logoPng" class="logo-img">
|
<img :src="logoPng" class="logo-img">
|
||||||
<span class="logo-text">YiXin-Ai</span>
|
<span class="logo-text">意心-Ai</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ad-banner">
|
<div class="ad-banner">
|
||||||
<SvgIcon name="p-bangong" class-name="animate-up-down" />
|
<SvgIcon name="p-bangong" class-name="animate-up-down" />
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ function handleDataChunk(chunk: AnyObject) {
|
|||||||
|
|
||||||
// 另一种思考中形式,content中有 <think></think> 的格式
|
// 另一种思考中形式,content中有 <think></think> 的格式
|
||||||
// 一开始匹配到 <think> 开始,匹配到 </think> 结束,并处理标签中的内容为思考内容
|
// 一开始匹配到 <think> 开始,匹配到 </think> 结束,并处理标签中的内容为思考内容
|
||||||
|
console.log(chunk.choices,"chunk.choices")
|
||||||
const parsedChunk = chunk.choices?.[0].delta.content;
|
const parsedChunk = chunk.choices?.[0].delta.content;
|
||||||
if (parsedChunk) {
|
if (parsedChunk) {
|
||||||
const thinkStart = parsedChunk.includes('<think>');
|
const thinkStart = parsedChunk.includes('<think>');
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
sessionId,
|
sessionId,
|
||||||
userId: userStore.userInfo?.userId as number,
|
userId: userStore.userInfo?.userId as number,
|
||||||
});
|
});
|
||||||
if (res.rows) {
|
if (res.data.items) {
|
||||||
setChatMap(sessionId, res.rows);
|
setChatMap(sessionId, res.data.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
|||||||
@@ -60,16 +60,15 @@ export const useSessionStore = defineStore('session', () => {
|
|||||||
try {
|
try {
|
||||||
const params: GetSessionListParams = {
|
const params: GetSessionListParams = {
|
||||||
userId: userStore.userInfo?.userId as number,
|
userId: userStore.userInfo?.userId as number,
|
||||||
pageNum: page,
|
skipCount: page,
|
||||||
pageSize: pageSize.value,
|
maxResultCount: pageSize.value,
|
||||||
isAsc: 'desc',
|
isAsc: 'desc',
|
||||||
orderByColumn: 'createTime',
|
orderByColumn: 'createTime',
|
||||||
};
|
};
|
||||||
|
|
||||||
const resArr = await get_session_list(params);
|
const resArr = await get_session_list(params);
|
||||||
|
|
||||||
// 预处理会话分组 并添加前缀图标
|
// 预处理会话分组 并添加前缀图标
|
||||||
const res = processSessions(resArr.rows);
|
const res = processSessions(resArr.data.items);
|
||||||
|
|
||||||
const allSessions = new Map(sessionList.value.map(item => [item.id, item])); // 现有所有数据
|
const allSessions = new Map(sessionList.value.map(item => [item.id, item])); // 现有所有数据
|
||||||
res.forEach(item => allSessions.set(item.id, { ...item })); // 更新/添加数据
|
res.forEach(item => allSessions.set(item.id, { ...item })); // 更新/添加数据
|
||||||
@@ -126,7 +125,7 @@ export const useSessionStore = defineStore('session', () => {
|
|||||||
// msg: "操作成功",
|
// msg: "操作成功",
|
||||||
// data: "1935711019560206338"
|
// data: "1935711019560206338"
|
||||||
// };
|
// };
|
||||||
console.log('create_session---res--',res)
|
console.log('create_session---res--', res);
|
||||||
// 创建会话后立刻查询列表会话
|
// 创建会话后立刻查询列表会话
|
||||||
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
|
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
|
||||||
const targetIndex = sessionList.value.findIndex(session => session.id === `${res.data}`);
|
const targetIndex = sessionList.value.findIndex(session => session.id === `${res.data}`);
|
||||||
@@ -138,13 +137,12 @@ export const useSessionStore = defineStore('session', () => {
|
|||||||
// 3. 刷新目标页数据
|
// 3. 刷新目标页数据
|
||||||
await requestSessionList(targetPage, true);
|
await requestSessionList(targetPage, true);
|
||||||
// 并将当前勾选信息设置为新增的会话信息
|
// 并将当前勾选信息设置为新增的会话信息
|
||||||
const newSessionRes = await get_session(`${res.data}`);
|
const newSessionRes = await get_session(`${res.data.id}`);
|
||||||
setCurrentSession(newSessionRes.data);
|
setCurrentSession(newSessionRes.data);
|
||||||
|
|
||||||
// 跳转聊天页
|
// 跳转聊天页
|
||||||
router.replace({
|
router.replace({
|
||||||
name: 'chatWithId',
|
name: 'chatWithId',
|
||||||
params: { id: `${res.data}` },
|
params: { id: `${res.data.id}` },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@@ -180,6 +178,7 @@ export const useSessionStore = defineStore('session', () => {
|
|||||||
// 删除会话(供组件调用)
|
// 删除会话(供组件调用)
|
||||||
const deleteSessions = async (ids: string[]) => {
|
const deleteSessions = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
|
//todo cc这里删除,返回空的body,结果炸了,报错堆栈都没有
|
||||||
await delete_session(ids);
|
await delete_session(ids);
|
||||||
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
|
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
|
||||||
const targetIndex = sessionList.value.findIndex(session => session.id === ids[0]);
|
const targetIndex = sessionList.value.findIndex(session => session.id === ids[0]);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface BaseResponse<T = any> {
|
|||||||
data: T;
|
data: T;
|
||||||
msg: string;
|
msg: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扩展请求函数类型声明
|
// 扩展请求函数类型声明
|
||||||
declare module 'hook-fetch' {
|
declare module 'hook-fetch' {
|
||||||
interface HookFetchDefaults {
|
interface HookFetchDefaults {
|
||||||
@@ -19,8 +20,7 @@ declare module 'hook-fetch' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const request = hookFetch.create<BaseResponse>({
|
export const request = hookFetch.create<BaseResponse>({
|
||||||
// baseURL: import.meta.env.VITE_API_URL,
|
baseURL: import.meta.env.VITE_WEB_BASE_API,
|
||||||
baseURL: '', // 留空或使用'/'
|
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
@@ -33,7 +33,6 @@ export const request = hookFetch.create<BaseResponse>({
|
|||||||
if (typeof response.result?.code === 'number') {
|
if (typeof response.result?.code === 'number') {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 非标准格式 → 包装为标准格式
|
// 非标准格式 → 包装为标准格式
|
||||||
return {
|
return {
|
||||||
...response,
|
...response,
|
||||||
|
|||||||
6
Yi.Ai.Vue3/types/components.d.ts
vendored
6
Yi.Ai.Vue3/types/components.d.ts
vendored
@@ -12,6 +12,9 @@ declare module 'vue' {
|
|||||||
DeepThinking: typeof import('./../src/components/DeepThinking/index.vue')['default']
|
DeepThinking: typeof import('./../src/components/DeepThinking/index.vue')['default']
|
||||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
|
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||||
|
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||||
@@ -22,6 +25,9 @@ declare module 'vue' {
|
|||||||
ElImage: typeof import('element-plus/es')['ElImage']
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
|
ElTable: typeof import('element-plus/es')['ElTable']
|
||||||
|
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
FilesSelect: typeof import('./../src/components/FilesSelect/index.vue')['default']
|
FilesSelect: typeof import('./../src/components/FilesSelect/index.vue')['default']
|
||||||
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
||||||
|
|||||||
1
Yi.Ai.Vue3/types/import_meta.d.ts
vendored
1
Yi.Ai.Vue3/types/import_meta.d.ts
vendored
@@ -6,6 +6,7 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_WEB_ENV: string;
|
readonly VITE_WEB_ENV: string;
|
||||||
readonly VITE_WEB_BASE_API: string;
|
readonly VITE_WEB_BASE_API: string;
|
||||||
readonly VITE_API_URL: string;
|
readonly VITE_API_URL: string;
|
||||||
|
readonly VITE_BUILD_COMPRESS: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface ImportMeta {
|
declare interface ImportMeta {
|
||||||
|
|||||||
@@ -25,13 +25,23 @@ export default defineConfig((cnf) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
server: {
|
server: {
|
||||||
|
port: 17001,
|
||||||
|
open: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
// 代理所有以 /prod-api 开头的请求
|
[env.VITE_WEB_BASE_API]: {
|
||||||
"/prod-api": {
|
target: env.VITE_API_URL,
|
||||||
target: "https://ccnetcore.com", // 接口域名
|
changeOrigin: true,
|
||||||
changeOrigin: true, // 改变源
|
rewrite: (path) => path.replace(`${[env.VITE_WEB_BASE_API]}`, ""),
|
||||||
secure: false, // 如果目标服务器使用 HTTPS 且证书无效,需要设置为 false
|
|
||||||
},
|
//查看真实代理url
|
||||||
|
bypass(req, res, options) {
|
||||||
|
//@ts-ignore
|
||||||
|
const proxyUrl = new URL(options.rewrite(req.url) || '',(options.target)as string)?.href || '';
|
||||||
|
console.log(proxyUrl);
|
||||||
|
req.headers['x-req-proxyUrl'] = proxyUrl
|
||||||
|
res.setHeader('x-res-proxyUrl',proxyUrl)
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user