mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-18 23:01:32 +08:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f8ed109f9 | ||
|
|
3f969627a4 | ||
|
|
d92970819a | ||
|
|
23e756fa9b | ||
|
|
5f58126fbf | ||
|
|
dcfd0ffb8f | ||
|
|
17221d056c | ||
|
|
4a9dcfada4 | ||
|
|
bb6c2bb020 | ||
|
|
a8760a34de | ||
|
|
1e432a5782 | ||
|
|
cb861ef2bb | ||
|
|
7cee8fd87a | ||
|
|
8ce0e5d348 | ||
|
|
90bce7c89f | ||
|
|
b840d0bcce | ||
|
|
bfa6d28289 | ||
|
|
f6e6ca9747 | ||
|
|
75f8d39648 | ||
|
|
9a939eba5a | ||
|
|
4e93efe821 | ||
|
|
8bdbee80a0 | ||
|
|
6bdf5dcc03 | ||
|
|
0bf0a9d78a | ||
|
|
38e9fea601 | ||
|
|
d2366b3b46 | ||
|
|
3aff93083a | ||
|
|
eb998199db | ||
|
|
1dd794af1b | ||
|
|
08c9923e7e | ||
|
|
06b109ca87 | ||
|
|
9b039335c7 | ||
|
|
041378e5fd | ||
|
|
6dc5ae10e3 | ||
|
|
5807f4c283 | ||
|
|
8ef4445908 | ||
|
|
8a0609e970 | ||
|
|
9f33b5009b | ||
|
|
50e66db8a1 | ||
|
|
c3e83b569a | ||
|
|
85d1c5ea7e | ||
|
|
ec1d126a02 | ||
|
|
e857695e70 | ||
|
|
fa9b2051fe |
@@ -22,4 +22,5 @@ WORKDIR /app
|
||||
COPY --from=build /app/publish .
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
RUN echo 'Asia/Shanghai' >/etc/timezone
|
||||
RUN apt update && apt install -y libpugixml-dev libtbb-dev
|
||||
ENTRYPOINT ["dotnet", "AntSK.dll"]
|
||||
|
||||
@@ -89,7 +89,7 @@ version: '3.8'
|
||||
services:
|
||||
antsk:
|
||||
container_name: antsk
|
||||
image: registry.cn-hangzhou.aliyuncs.com/AIDotNet/antsk:v0.2.3
|
||||
image: registry.cn-hangzhou.aliyuncs.com/AIDotNet/antsk:v0.2.7
|
||||
ports:
|
||||
- 5000:5000
|
||||
networks:
|
||||
@@ -102,6 +102,7 @@ services:
|
||||
volumes:
|
||||
- ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录
|
||||
- D://model:/app/model
|
||||
- D://model:/root/.cache/modelscope/hub/AI-ModelScope #使用Llamafactory时需要挂载 否则初始化的环境重启后会丢失
|
||||
networks:
|
||||
antsk:
|
||||
```
|
||||
|
||||
@@ -3,9 +3,9 @@ version: '3.8'
|
||||
services:
|
||||
antsk:
|
||||
container_name: antsk
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.2.4
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.2.7
|
||||
# 如果需要pytorch环境需要使用下面这个镜像,镜像比较大
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.2.4
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.2.7
|
||||
ports:
|
||||
- 5000:5000
|
||||
networks:
|
||||
|
||||
@@ -18,9 +18,9 @@ services:
|
||||
- ./pg/data:/var/lib/postgresql/data
|
||||
antsk:
|
||||
container_name: antsk
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.2.4
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.2.7
|
||||
# 如果需要pytorch环境需要使用下面这个镜像,镜像比较大
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.2.4
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.2.7
|
||||
ports:
|
||||
- 5000:5000
|
||||
networks:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AntDesign.Charts" Version="0.5.1" />
|
||||
<PackageReference Include="AntDesign.ProLayout" Version="0.18.1" />
|
||||
<PackageReference Include="AntDesign.ProLayout" Version="0.18.2" />
|
||||
<PackageReference Include="BlazorComponents.Terminal" Version="0.6.0" />
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
|
||||
@@ -21,30 +21,32 @@
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="Markdig" Version="0.36.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.149" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.151" />
|
||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118" />
|
||||
<PackageReference Include="RestSharp" Version="110.2.0" />
|
||||
<PackageReference Include="NPOI" Version="2.7.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.6.3" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.6.3" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.6.3-alpha" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.7.1" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.7.1" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.7.1-alpha" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.35.240321.1" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="0.35.240321.1" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Qdrant" Version="0.35.240321.1" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Redis" Version="0.35.240321.1" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.AzureAISearch" Version="0.35.240321.1" />
|
||||
|
||||
<PackageReference Include="LLamaSharp" Version="0.11.1" />
|
||||
<PackageReference Include="LLamaSharp.Backend.Cpu" Version="0.11.1" />
|
||||
<PackageReference Include="LLamaSharp.Backend.Cuda12" Version="0.11.1" />
|
||||
<PackageReference Include="LLamaSharp.kernel-memory" Version="0.11.1" />
|
||||
<PackageReference Include="LLamaSharp.semantic-kernel" Version="0.11.1" />
|
||||
<PackageReference Include="LLamaSharp" Version="0.11.2" />
|
||||
<PackageReference Include="LLamaSharp.Backend.Cpu" Version="0.11.2" />
|
||||
<PackageReference Include="LLamaSharp.Backend.Cuda12" Version="0.11.2" />
|
||||
<PackageReference Include="LLamaSharp.kernel-memory" Version="0.11.2" />
|
||||
<PackageReference Include="LLamaSharp.semantic-kernel" Version="0.11.2" />
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AntSK.LLamaFactory\AntSK.LLamaFactory.csproj" />
|
||||
<ProjectReference Include="..\AntSk.LLM\AntSK.LLM.csproj" />
|
||||
<ProjectReference Include="..\AntSK.OCR\AntSK.OCR.csproj" />
|
||||
<ProjectReference Include="..\MiddleWare\AntSK.BackgroundTask\AntSK.BackgroundTask.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -69,6 +69,84 @@
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ExcelToDataTable(System.String,System.Boolean)">
|
||||
<summary>
|
||||
将excel导入到datatable
|
||||
</summary>
|
||||
<param name="filePath">excel路径</param>
|
||||
<param name="isColumnName">第一行是否是列名</param>
|
||||
<returns>返回datatable</returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ExcelToDataTable(System.IO.Stream,System.Boolean)">
|
||||
<summary>
|
||||
将excel导入到datatable
|
||||
</summary>
|
||||
<param name="stream">流</param>
|
||||
<param name="isColumnName">第一行是否是列名</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ExcelToList``1(System.IO.Stream)">
|
||||
<summary>
|
||||
excel转list
|
||||
</summary>
|
||||
<typeparam name="TResult"></typeparam>
|
||||
<param name="stream"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ExcelToList``1(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
excel转list-根据sheetName得到List
|
||||
</summary>
|
||||
<typeparam name="TResult"></typeparam>
|
||||
<param name="stream"></param>
|
||||
<param name="sheetName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ListToExcel``1(``0[],System.String)">
|
||||
<summary>
|
||||
List导出excel 二进制流
|
||||
</summary>
|
||||
<typeparam name="T">实体</typeparam>
|
||||
<param name="data">List</param>
|
||||
<param name="sheetName">sheetname 可不填,默认Sheet0</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.DataTableToExcel(System.Data.DataTable,System.String,System.String)">
|
||||
<summary>
|
||||
Dt导出excel 二进制流
|
||||
</summary>
|
||||
<param name="dt">datatable</param>
|
||||
<param name="strFile">strFile</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.ListWriteExcel``1(``0[],System.String,System.String)">
|
||||
<summary>
|
||||
List写入excel
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="data"></param>
|
||||
<param name="strFile">路径</param>
|
||||
<param name="sheetName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.DataTableWriteExcel(System.Data.DataTable,System.String,System.String)">
|
||||
<summary>
|
||||
dt写入excel
|
||||
</summary>
|
||||
<param name="dt">datatable</param>
|
||||
<param name="strFile">路径</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.ExeclHelper.SetCellDropdownList(NPOI.SS.UserModel.IWorkbook,NPOI.SS.UserModel.ISheet,System.Collections.Generic.List{System.String},System.String,System.Int32,System.Int32,System.Int32)">
|
||||
<summary>
|
||||
设置单元格下拉框(除去标题行)
|
||||
</summary>
|
||||
<param name="workbook"></param>
|
||||
<param name="sheet"></param>
|
||||
<param name="ddlList"></param>
|
||||
<param name="firstcol"></param>
|
||||
<param name="lastcol"></param>
|
||||
</member>
|
||||
<member name="T:AntSK.Domain.Domain.Model.Enum.AIType">
|
||||
<summary>
|
||||
AI类型
|
||||
@@ -104,6 +182,12 @@
|
||||
模型写死
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Other.KMExcelHandler.StepName">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Other.KMExcelHandler.InvokeAsync(Microsoft.KernelMemory.Pipeline.DataPipeline,System.Threading.CancellationToken)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="F:AntSK.Domain.Domain.Other.LLamaConfig.dicLLamaWeights">
|
||||
<summary>
|
||||
避免模型重复加载,本地缓存
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace AntSK.Domain.Common.DependencyInjection
|
||||
_repository.GetDB().CodeFirst.InitTables(type);
|
||||
}
|
||||
}
|
||||
//安装向量插件
|
||||
_repository.GetDB().Ado.ExecuteCommandAsync($"CREATE EXTENSION IF NOT EXISTS vector;");
|
||||
}
|
||||
return app;
|
||||
}
|
||||
|
||||
822
src/AntSK.Domain/Common/Excel/ExeclHelper.cs
Normal file
822
src/AntSK.Domain/Common/Excel/ExeclHelper.cs
Normal file
@@ -0,0 +1,822 @@
|
||||
using NPOI.HSSF.UserModel;
|
||||
using NPOI.SS.UserModel;
|
||||
using NPOI.SS.Util;
|
||||
using NPOI.XSSF.Streaming;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain
|
||||
{
|
||||
public class ExeclHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将excel导入到datatable
|
||||
/// </summary>
|
||||
/// <param name="filePath">excel路径</param>
|
||||
/// <param name="isColumnName">第一行是否是列名</param>
|
||||
/// <returns>返回datatable</returns>
|
||||
public static DataTable ExcelToDataTable(string filePath, bool isColumnName)
|
||||
{
|
||||
DataTable dataTable = null;
|
||||
FileStream fs = null;
|
||||
DataColumn column = null;
|
||||
DataRow dataRow = null;
|
||||
IWorkbook workbook = null;
|
||||
ISheet sheet = null;
|
||||
IRow row = null;
|
||||
ICell cell = null;
|
||||
int startRow = 0;
|
||||
try
|
||||
{
|
||||
using (fs = File.OpenRead(filePath))
|
||||
{
|
||||
// 2007版本
|
||||
if (filePath.Contains(".xlsx"))
|
||||
workbook = new XSSFWorkbook(fs);
|
||||
// 2003版本
|
||||
else if (filePath.Contains(".xls"))
|
||||
workbook = new HSSFWorkbook(fs);
|
||||
|
||||
if (workbook != null)
|
||||
{
|
||||
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
|
||||
dataTable = new DataTable();
|
||||
if (sheet != null)
|
||||
{
|
||||
int rowCount = sheet.LastRowNum;//总行数
|
||||
if (rowCount > 0)
|
||||
{
|
||||
IRow firstRow = sheet.GetRow(0);//第一行
|
||||
int cellCount = firstRow.LastCellNum;//列数
|
||||
|
||||
//构建datatable的列
|
||||
if (isColumnName)
|
||||
{
|
||||
startRow = 1;//如果第一行是列名,则从第二行开始读取
|
||||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||||
{
|
||||
cell = firstRow.GetCell(i);
|
||||
if (cell != null)
|
||||
{
|
||||
if (cell.StringCellValue != null)
|
||||
{
|
||||
column = new DataColumn(cell.StringCellValue);
|
||||
dataTable.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||||
{
|
||||
column = new DataColumn("column" + (i + 1));
|
||||
dataTable.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
|
||||
//填充行
|
||||
for (int i = startRow; i <= rowCount; ++i)
|
||||
{
|
||||
row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
|
||||
dataRow = dataTable.NewRow();
|
||||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||||
{
|
||||
cell = row.GetCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
dataRow[j] = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Blank:
|
||||
dataRow[j] = "";
|
||||
break;
|
||||
case CellType.Numeric:
|
||||
short format = cell.CellStyle.DataFormat;
|
||||
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
|
||||
if (format == 14 || format == 31 || format == 57 || format == 58)
|
||||
dataRow[j] = cell.DateCellValue;
|
||||
else
|
||||
dataRow[j] = cell.NumericCellValue;
|
||||
break;
|
||||
case CellType.String:
|
||||
dataRow[j] = cell.StringCellValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dataTable.Rows.Add(dataRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataTable;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (fs != null)
|
||||
{
|
||||
fs.Close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将excel导入到datatable
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="isColumnName">第一行是否是列名</param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ExcelToDataTable(Stream stream, bool isColumnName)
|
||||
{
|
||||
DataTable dataTable = null;
|
||||
DataColumn column = null;
|
||||
DataRow dataRow = null;
|
||||
IWorkbook workbook = new XSSFWorkbook(stream);
|
||||
ISheet sheet = null;
|
||||
IRow row = null;
|
||||
ICell cell = null;
|
||||
int startRow = 0;
|
||||
try
|
||||
{
|
||||
|
||||
if (workbook != null)
|
||||
{
|
||||
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
|
||||
dataTable = new DataTable();
|
||||
if (sheet != null)
|
||||
{
|
||||
int rowCount = sheet.LastRowNum;//总行数
|
||||
if (rowCount > 0)
|
||||
{
|
||||
IRow firstRow = sheet.GetRow(0);//第一行
|
||||
int cellCount = firstRow.LastCellNum;//列数
|
||||
|
||||
//构建datatable的列
|
||||
if (isColumnName)
|
||||
{
|
||||
startRow = 1;//如果第一行是列名,则从第二行开始读取
|
||||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||||
{
|
||||
cell = firstRow.GetCell(i);
|
||||
if (cell != null)
|
||||
{
|
||||
if (cell.StringCellValue != null)
|
||||
{
|
||||
column = new DataColumn(cell.StringCellValue);
|
||||
dataTable.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||||
{
|
||||
column = new DataColumn("column" + (i + 1));
|
||||
dataTable.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
|
||||
//填充行
|
||||
for (int i = startRow; i <= rowCount; ++i)
|
||||
{
|
||||
row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
|
||||
dataRow = dataTable.NewRow();
|
||||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||||
{
|
||||
cell = row.GetCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
dataRow[j] = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Blank:
|
||||
dataRow[j] = "";
|
||||
break;
|
||||
case CellType.Numeric:
|
||||
short format = cell.CellStyle.DataFormat;
|
||||
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
|
||||
if (format == 14 || format == 31 || format == 57 || format == 58)
|
||||
dataRow[j] = cell.DateCellValue;
|
||||
else
|
||||
dataRow[j] = cell.NumericCellValue;
|
||||
break;
|
||||
case CellType.String:
|
||||
dataRow[j] = cell.StringCellValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dataTable.Rows.Add(dataRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// excel转list
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="stream"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<TResult> ExcelToList<TResult>(Stream stream) where TResult : new()
|
||||
{
|
||||
var propertyInfos = typeof(TResult).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CustomAttributes.Count() > 0)
|
||||
.OrderBy(p => p.GetCustomAttribute<ExeclPropertyAttribute>().Order).ToArray();
|
||||
|
||||
List<TResult> list = new List<TResult>();
|
||||
|
||||
IWorkbook workbook = new XSSFWorkbook(stream);
|
||||
ISheet sheet = null;
|
||||
IRow row = null;
|
||||
ICell cell = null;
|
||||
int startRow = 1;
|
||||
try
|
||||
{
|
||||
|
||||
if (workbook != null)
|
||||
{
|
||||
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
|
||||
if (sheet != null)
|
||||
{
|
||||
int rowCount = sheet.LastRowNum;//总行数
|
||||
if (rowCount > 0)
|
||||
{
|
||||
IRow firstRow = sheet.GetRow(0);//第一行
|
||||
int cellCount = firstRow.LastCellNum;//列数
|
||||
|
||||
//填充行
|
||||
for (int i = startRow; i <= rowCount; ++i)
|
||||
{
|
||||
row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
bool emptyRow = true;//是否空行
|
||||
TResult dataModel = new TResult();
|
||||
|
||||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||||
{
|
||||
var execlPropertyAttribute = propertyInfos[j].GetCustomAttribute<ExeclPropertyAttribute>();
|
||||
|
||||
cell = row.GetCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Blank:
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
break;
|
||||
case CellType.Numeric:
|
||||
short format = cell.CellStyle.DataFormat;
|
||||
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
|
||||
if (format == 14 || format == 31 || format == 57 || format == 58)
|
||||
propertyInfos[j].SetValue(dataModel, cell.DateCellValue);
|
||||
else
|
||||
{
|
||||
if (execlPropertyAttribute.CellType == CellType.String)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue.ToString());
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CellType.String:
|
||||
propertyInfos[j].SetValue(dataModel, cell.StringCellValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell != null && !string.IsNullOrEmpty(cell.ToString().Trim()))
|
||||
{
|
||||
emptyRow = false;
|
||||
}
|
||||
}
|
||||
//非空数据行数据添加到DataTable
|
||||
if (!emptyRow)
|
||||
{
|
||||
list.Add(dataModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<TResult> ExcelToListFileName<TResult>(Stream stream, string fileName) where TResult : new()
|
||||
{
|
||||
var propertyInfos = typeof(TResult).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CustomAttributes.Count() > 0)
|
||||
.OrderBy(p => p.GetCustomAttribute<ExeclPropertyAttribute>().Order).ToArray();
|
||||
|
||||
List<TResult> list = new List<TResult>();
|
||||
|
||||
IWorkbook workbook = null;
|
||||
if (fileName.Contains(".xlsx"))
|
||||
workbook = new XSSFWorkbook(stream);
|
||||
// 2003版本
|
||||
else if (fileName.Contains(".xls"))
|
||||
workbook = new HSSFWorkbook(stream);
|
||||
ISheet sheet = null;
|
||||
IRow row = null;
|
||||
ICell cell = null;
|
||||
int startRow = 1;
|
||||
try
|
||||
{
|
||||
|
||||
if (workbook != null)
|
||||
{
|
||||
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
|
||||
if (sheet != null)
|
||||
{
|
||||
int rowCount = sheet.LastRowNum;//总行数
|
||||
if (rowCount > 0)
|
||||
{
|
||||
IRow firstRow = sheet.GetRow(0);//第一行
|
||||
int cellCount = firstRow.LastCellNum;//列数
|
||||
|
||||
//填充行
|
||||
for (int i = startRow; i <= rowCount; ++i)
|
||||
{
|
||||
row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
bool emptyRow = true;//是否空行
|
||||
TResult dataModel = new TResult();
|
||||
|
||||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||||
{
|
||||
var execlPropertyAttribute = propertyInfos[j].GetCustomAttribute<ExeclPropertyAttribute>();
|
||||
|
||||
cell = row.GetCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Blank:
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
break;
|
||||
case CellType.Numeric:
|
||||
short format = cell.CellStyle.DataFormat;
|
||||
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
|
||||
if (format == 14 || format == 31 || format == 57 || format == 58)
|
||||
propertyInfos[j].SetValue(dataModel, cell.DateCellValue);
|
||||
else
|
||||
{
|
||||
if (execlPropertyAttribute.CellType == CellType.String)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue.ToString());
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CellType.String:
|
||||
propertyInfos[j].SetValue(dataModel, cell.StringCellValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell != null && !string.IsNullOrEmpty(cell.ToString().Trim()))
|
||||
{
|
||||
emptyRow = false;
|
||||
}
|
||||
}
|
||||
//非空数据行数据添加到DataTable
|
||||
if (!emptyRow)
|
||||
{
|
||||
list.Add(dataModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// excel转list-根据sheetName得到List
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<TResult> ExcelToList<TResult>(Stream stream, string sheetName) where TResult : new()
|
||||
{
|
||||
var propertyInfos = typeof(TResult).GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.OrderBy(p => p.GetCustomAttribute<ExeclPropertyAttribute>().Order).ToArray();
|
||||
|
||||
List<TResult> list = new List<TResult>();
|
||||
|
||||
IWorkbook workbook = new XSSFWorkbook(stream);
|
||||
ISheet sheet = null;
|
||||
IRow row = null;
|
||||
ICell cell = null;
|
||||
int startRow = 1;
|
||||
try
|
||||
{
|
||||
|
||||
if (workbook != null)
|
||||
{
|
||||
sheet = workbook.GetSheet(sheetName);//根据sheet读取对应的DataTable
|
||||
if (sheet != null)
|
||||
{
|
||||
int rowCount = sheet.LastRowNum;//总行数
|
||||
if (rowCount > 0)
|
||||
{
|
||||
IRow firstRow = sheet.GetRow(0);//第一行
|
||||
int cellCount = firstRow.LastCellNum;//列数
|
||||
|
||||
//填充行
|
||||
for (int i = startRow; i <= rowCount; ++i)
|
||||
{
|
||||
row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
bool emptyRow = true;//是否空行
|
||||
|
||||
TResult dataModel = new TResult();
|
||||
|
||||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||||
{
|
||||
var execlPropertyAttribute = propertyInfos[j].GetCustomAttribute<ExeclPropertyAttribute>();
|
||||
|
||||
cell = row.GetCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Blank:
|
||||
propertyInfos[j].SetValue(dataModel, "");
|
||||
break;
|
||||
case CellType.Numeric:
|
||||
short format = cell.CellStyle.DataFormat;
|
||||
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
|
||||
if (format == 14 || format == 31 || format == 57 || format == 58)
|
||||
propertyInfos[j].SetValue(dataModel, cell.DateCellValue);
|
||||
else
|
||||
{
|
||||
if (execlPropertyAttribute.CellType == CellType.String)
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue.ToString());
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
propertyInfos[j].SetValue(dataModel, cell.NumericCellValue);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case CellType.String:
|
||||
propertyInfos[j].SetValue(dataModel, cell.StringCellValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell != null && !string.IsNullOrEmpty(cell.ToString().Trim()))
|
||||
{
|
||||
emptyRow = false;
|
||||
}
|
||||
}
|
||||
//非空数据行数据添加到DataTable
|
||||
if (!emptyRow)
|
||||
{
|
||||
list.Add(dataModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List导出excel 二进制流
|
||||
/// </summary>
|
||||
/// <typeparam name="T">实体</typeparam>
|
||||
/// <param name="data">List</param>
|
||||
/// <param name="sheetName">sheetname 可不填,默认Sheet0</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ListToExcel<T>(T[] data, string sheetName = "Sheet0")
|
||||
{
|
||||
IWorkbook workbook = null;
|
||||
IRow row = null;
|
||||
ISheet sheet = null;
|
||||
ICell cell = null;
|
||||
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.OrderBy(p => p.GetCustomAttribute<ExeclPropertyAttribute>().Order).ToArray();
|
||||
workbook = new XSSFWorkbook();
|
||||
sheet = workbook.CreateSheet(sheetName);//创建一个名称为Sheet0的表
|
||||
int rowCount = data.Count();//行数
|
||||
int columnCount = propertyInfos.Length;//列数
|
||||
//设置列头
|
||||
row = sheet.CreateRow(0);//excel第一行设为列头
|
||||
for (int c = 0; c < columnCount; c++)
|
||||
{
|
||||
cell = row.CreateCell(c);
|
||||
cell.SetCellValue(propertyInfos[c].GetCustomAttribute<ExeclPropertyAttribute>().DisplayName);
|
||||
}
|
||||
//设置每行每列的单元格,
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
{
|
||||
row = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < columnCount; j++)
|
||||
{
|
||||
cell = row.CreateCell(j);//excel第二行开始写入数据
|
||||
cell.SetCellValue(propertyInfos[j].GetValue(data[i])?.ToString());
|
||||
}
|
||||
}
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
workbook.Write(memoryStream);//向打开的这个xls文件中写入数据
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dt导出excel 二进制流
|
||||
/// </summary>
|
||||
/// <param name="dt">datatable</param>
|
||||
/// <param name="strFile">strFile</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] DataTableToExcel(DataTable dt, string strFile, string sheetName = "Sheet0")
|
||||
{
|
||||
bool result = false;
|
||||
IWorkbook workbook = null;
|
||||
FileStream fs = null;
|
||||
IRow row = null;
|
||||
ISheet sheet = null;
|
||||
ICell cell = null;
|
||||
|
||||
if (dt != null && dt.Rows.Count > 0)
|
||||
{
|
||||
workbook = new XSSFWorkbook();
|
||||
sheet = workbook.CreateSheet(sheetName);//创建一个名称为Sheet0的表
|
||||
int rowCount = dt.Rows.Count;//行数
|
||||
int columnCount = dt.Columns.Count;//列数
|
||||
|
||||
//设置列头
|
||||
row = sheet.CreateRow(0);//excel第一行设为列头
|
||||
for (int c = 0; c < columnCount; c++)
|
||||
{
|
||||
cell = row.CreateCell(c);
|
||||
cell.SetCellValue(dt.Columns[c].ColumnName);
|
||||
}
|
||||
|
||||
//设置每行每列的单元格,
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
{
|
||||
row = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < columnCount; j++)
|
||||
{
|
||||
cell = row.CreateCell(j);//excel第二行开始写入数据
|
||||
cell.SetCellValue(dt.Rows[i][j].ToString());
|
||||
}
|
||||
}
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
workbook.Write(memoryStream);//向打开的这个xls文件中写入数据
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List写入excel
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="strFile">路径</param>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool ListWriteExcel<T>(T[] data, string strFile, string sheetName = "Sheet0")
|
||||
{
|
||||
bool result = false;
|
||||
IWorkbook workbook = null;
|
||||
FileStream fs = null;
|
||||
IRow row = null;
|
||||
ISheet sheet = null;
|
||||
ICell cell = null;
|
||||
try
|
||||
{
|
||||
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.OrderBy(p => p.GetCustomAttribute<ExeclPropertyAttribute>().Order).ToArray();
|
||||
workbook = new XSSFWorkbook();
|
||||
sheet = workbook.CreateSheet(sheetName);//创建一个名称为Sheet0的表
|
||||
int rowCount = data.Count();//行数
|
||||
int columnCount = propertyInfos.Length;//列数
|
||||
//设置列头
|
||||
row = sheet.CreateRow(0);//excel第一行设为列头
|
||||
for (int c = 0; c < columnCount; c++)
|
||||
{
|
||||
cell = row.CreateCell(c);
|
||||
cell.SetCellValue(propertyInfos[c].GetCustomAttribute<ExeclPropertyAttribute>().DisplayName);
|
||||
}
|
||||
//设置每行每列的单元格,
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
{
|
||||
row = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < columnCount; j++)
|
||||
{
|
||||
cell = row.CreateCell(j);//excel第二行开始写入数据
|
||||
cell.SetCellValue(propertyInfos[j].GetValue(data[i])?.ToString());
|
||||
}
|
||||
}
|
||||
using (fs = File.OpenWrite(strFile))
|
||||
{
|
||||
workbook.Write(fs);//向打开的这个xls文件中写入数据
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (fs != null)
|
||||
{
|
||||
fs.Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// dt写入excel
|
||||
/// </summary>
|
||||
/// <param name="dt">datatable</param>
|
||||
/// <param name="strFile">路径</param>
|
||||
/// <returns></returns>
|
||||
public static bool DataTableWriteExcel(DataTable dt, string strFile, string sheetName = "Sheet0")
|
||||
{
|
||||
bool result = false;
|
||||
IWorkbook workbook = null;
|
||||
FileStream fs = null;
|
||||
IRow row = null;
|
||||
ISheet sheet = null;
|
||||
ICell cell = null;
|
||||
try
|
||||
{
|
||||
if (dt != null && dt.Rows.Count > 0)
|
||||
{
|
||||
workbook = new XSSFWorkbook();
|
||||
sheet = workbook.CreateSheet(sheetName);//创建一个名称为Sheet0的表
|
||||
int rowCount = dt.Rows.Count;//行数
|
||||
int columnCount = dt.Columns.Count;//列数
|
||||
|
||||
//设置列头
|
||||
row = sheet.CreateRow(0);//excel第一行设为列头
|
||||
for (int c = 0; c < columnCount; c++)
|
||||
{
|
||||
cell = row.CreateCell(c);
|
||||
cell.SetCellValue(dt.Columns[c].ColumnName);
|
||||
}
|
||||
|
||||
//设置每行每列的单元格,
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
{
|
||||
row = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < columnCount; j++)
|
||||
{
|
||||
cell = row.CreateCell(j);//excel第二行开始写入数据
|
||||
cell.SetCellValue(dt.Rows[i][j].ToString());
|
||||
}
|
||||
}
|
||||
using (fs = File.OpenWrite(strFile))
|
||||
{
|
||||
workbook.Write(fs);//向打开的这个xls文件中写入数据
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (fs != null)
|
||||
{
|
||||
fs.Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置单元格下拉框(除去标题行)
|
||||
/// </summary>
|
||||
/// <param name="workbook"></param>
|
||||
/// <param name="sheet"></param>
|
||||
/// <param name="ddlList"></param>
|
||||
/// <param name="firstcol"></param>
|
||||
/// <param name="lastcol"></param>
|
||||
public static void SetCellDropdownList(IWorkbook workbook, ISheet sheet, List<string> ddlList, string sheetname, int sheetIndex, int firstcol, int lastcol)
|
||||
{
|
||||
|
||||
# region 低版本Excel【HSSFWorkbook】设置下拉框
|
||||
//ISheet sheet2 = workbook.CreateSheet(sheetname);
|
||||
|
||||
////隐藏
|
||||
//workbook.SetSheetHidden(sheetIndex, 1);
|
||||
//int rowIndex = 0;
|
||||
//foreach (var item in ddlList)
|
||||
//{
|
||||
// IRow vrow = sheet2.CreateRow(rowIndex);
|
||||
// vrow.CreateCell(0).SetCellValue(item);
|
||||
|
||||
// rowIndex++;
|
||||
//}
|
||||
|
||||
////创建的下拉项的区域:
|
||||
//var rangeName = sheetname + "Range";
|
||||
//IName range = workbook.CreateName();
|
||||
//range.RefersToFormula = sheetname + "!$A$1:$A$" + rowIndex;
|
||||
//range.NameName = rangeName;
|
||||
//CellRangeAddressList regions = new CellRangeAddressList(1, 65535, firstcol, lastcol);
|
||||
|
||||
//DVConstraint constraint = DVConstraint.CreateFormulaListConstraint(rangeName);
|
||||
//HSSFDataValidation dataValidate = new HSSFDataValidation(regions, constraint);
|
||||
//dataValidate.CreateErrorBox("输入不合法", "请输入或选择下拉列表中的值。");
|
||||
//dataValidate.ShowPromptBox = true;
|
||||
//sheet.AddValidationData(dataValidate);
|
||||
#endregion
|
||||
|
||||
//高版本excel【XSSFWorkbook】 设置下拉框
|
||||
XSSFSheet sheetDDL = (XSSFSheet)workbook.CreateSheet(sheetname);
|
||||
workbook.SetSheetHidden(sheetIndex, 1); //隐藏下拉框数据sheet
|
||||
String[] datas = ddlList.ToArray(); //下拉框数据源
|
||||
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheetDDL);
|
||||
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)dvHelper.CreateExplicitListConstraint(datas);
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, firstcol, lastcol); //下拉设置列
|
||||
XSSFDataValidation validation = (XSSFDataValidation)dvHelper.CreateValidation(dvConstraint, addressList);
|
||||
|
||||
validation.SuppressDropDownArrow = true;
|
||||
validation.ShowErrorBox = true;
|
||||
validation.ShowPromptBox = true;
|
||||
sheet.AddValidationData(validation);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/AntSK.Domain/Common/Excel/ExeclPropertyAttribute.cs
Normal file
28
src/AntSK.Domain/Common/Excel/ExeclPropertyAttribute.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using NPOI.SS.UserModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain
|
||||
{
|
||||
public class ExeclPropertyAttribute : Attribute
|
||||
{
|
||||
public ExeclPropertyAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
public ExeclPropertyAttribute(string displayName, int order, CellType cellType = CellType.String)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
Order = order;
|
||||
CellType = cellType;
|
||||
}
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public CellType CellType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -28,5 +28,7 @@ namespace AntSK.Domain.Domain.Model.Constant
|
||||
历史聊天记录:{{ConversationSummaryPlugin.SummarizeConversation $history}}
|
||||
--------------------------
|
||||
用户问题: {{$input}}";
|
||||
|
||||
public const string KMExcelSplit = "*&antsk_excel&*";
|
||||
}
|
||||
}
|
||||
|
||||
17
src/AntSK.Domain/Domain/Model/Excel/KMSExcelModel.cs
Normal file
17
src/AntSK.Domain/Domain/Model/Excel/KMSExcelModel.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Excel
|
||||
{
|
||||
public class KMSExcelModel
|
||||
{
|
||||
[ExeclProperty("问题",0)]
|
||||
public string Question { get; set; }
|
||||
|
||||
[ExeclProperty("答案", 1)]
|
||||
public string Answer { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ namespace AntSK.Domain.Domain.Model
|
||||
{
|
||||
File = 1,
|
||||
Url = 2,
|
||||
Text = 3
|
||||
Text = 3,
|
||||
Excel=4
|
||||
}
|
||||
}
|
||||
|
||||
156
src/AntSK.Domain/Domain/Other/KMExcelHandler.cs
Normal file
156
src/AntSK.Domain/Domain/Other/KMExcelHandler.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.KernelMemory.AI.OpenAI;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.KernelMemory.DataFormats.Text;
|
||||
using Microsoft.KernelMemory.Diagnostics;
|
||||
using Microsoft.KernelMemory.Extensions;
|
||||
using Microsoft.KernelMemory.Pipeline;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Other
|
||||
{
|
||||
public class KMExcelHandler: IPipelineStepHandler
|
||||
{
|
||||
private readonly TextPartitioningOptions _options;
|
||||
private readonly IPipelineOrchestrator _orchestrator;
|
||||
private readonly ILogger<KMExcelHandler> _log;
|
||||
private readonly TextChunker.TokenCounter _tokenCounter;
|
||||
|
||||
public KMExcelHandler(
|
||||
string stepName,
|
||||
IPipelineOrchestrator orchestrator,
|
||||
TextPartitioningOptions? options = null,
|
||||
ILogger<KMExcelHandler>? log = null)
|
||||
{
|
||||
this.StepName = stepName;
|
||||
this._orchestrator = orchestrator;
|
||||
this._options = options ?? new TextPartitioningOptions();
|
||||
this._options.Validate();
|
||||
|
||||
this._log = log ?? DefaultLogger<KMExcelHandler>.Instance;
|
||||
this._tokenCounter = DefaultGPTTokenizer.StaticCountTokens;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string StepName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<(bool success, DataPipeline updatedPipeline)> InvokeAsync(
|
||||
DataPipeline pipeline, CancellationToken cancellationToken = default)
|
||||
{
|
||||
this._log.LogDebug("Partitioning text, pipeline '{0}/{1}'", pipeline.Index, pipeline.DocumentId);
|
||||
|
||||
if (pipeline.Files.Count == 0)
|
||||
{
|
||||
this._log.LogWarning("Pipeline '{0}/{1}': there are no files to process, moving to next pipeline step.", pipeline.Index, pipeline.DocumentId);
|
||||
return (true, pipeline);
|
||||
}
|
||||
|
||||
foreach (DataPipeline.FileDetails uploadedFile in pipeline.Files)
|
||||
{
|
||||
// Track new files being generated (cannot edit originalFile.GeneratedFiles while looping it)
|
||||
Dictionary<string, DataPipeline.GeneratedFileDetails> newFiles = new();
|
||||
|
||||
foreach (KeyValuePair<string, DataPipeline.GeneratedFileDetails> generatedFile in uploadedFile.GeneratedFiles)
|
||||
{
|
||||
var file = generatedFile.Value;
|
||||
if (file.AlreadyProcessedBy(this))
|
||||
{
|
||||
this._log.LogTrace("File {0} already processed by this handler", file.Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Partition only the original text
|
||||
if (file.ArtifactType != DataPipeline.ArtifactTypes.ExtractedText)
|
||||
{
|
||||
this._log.LogTrace("Skipping file {0} (not original text)", file.Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Use a different partitioning strategy depending on the file type
|
||||
List<string> partitions;
|
||||
List<string> sentences;
|
||||
BinaryData partitionContent = await this._orchestrator.ReadFileAsync(pipeline, file.Name, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Skip empty partitions. Also: partitionContent.ToString() throws an exception if there are no bytes.
|
||||
if (partitionContent.ToArray().Length == 0) { continue; }
|
||||
|
||||
switch (file.MimeType)
|
||||
{
|
||||
case MimeTypes.PlainText:
|
||||
{
|
||||
this._log.LogDebug("Partitioning text file {0}", file.Name);
|
||||
string content = partitionContent.ToString();
|
||||
var excelList = content.Split(KmsConstantcs.KMExcelSplit, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
sentences = excelList;
|
||||
partitions = excelList;
|
||||
break;
|
||||
}
|
||||
|
||||
case MimeTypes.MarkDown:
|
||||
{
|
||||
this._log.LogDebug("Partitioning text file {0}", file.Name);
|
||||
string content = partitionContent.ToString();
|
||||
var excelList = content.Split(KmsConstantcs.KMExcelSplit, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
sentences = excelList;
|
||||
partitions = excelList;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this._log.LogWarning("File {0} cannot be partitioned, type '{1}' not supported", file.Name, file.MimeType);
|
||||
// Don't partition other files
|
||||
continue;
|
||||
}
|
||||
|
||||
if (partitions.Count == 0) { continue; }
|
||||
|
||||
this._log.LogDebug("Saving {0} file partitions", partitions.Count);
|
||||
for (int partitionNumber = 0; partitionNumber < partitions.Count; partitionNumber++)
|
||||
{
|
||||
// TODO: turn partitions in objects with more details, e.g. page number
|
||||
string text = partitions[partitionNumber];
|
||||
int sectionNumber = 0; // TODO: use this to store the page number (if any)
|
||||
BinaryData textData = new(text);
|
||||
|
||||
int tokenCount = this._tokenCounter(text);
|
||||
this._log.LogDebug("Partition size: {0} tokens", tokenCount);
|
||||
|
||||
var destFile = uploadedFile.GetPartitionFileName(partitionNumber);
|
||||
await this._orchestrator.WriteFileAsync(pipeline, destFile, textData, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var destFileDetails = new DataPipeline.GeneratedFileDetails
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N"),
|
||||
ParentId = uploadedFile.Id,
|
||||
Name = destFile,
|
||||
Size = text.Length,
|
||||
MimeType = MimeTypes.PlainText,
|
||||
ArtifactType = DataPipeline.ArtifactTypes.TextPartition,
|
||||
PartitionNumber = partitionNumber,
|
||||
SectionNumber = sectionNumber,
|
||||
Tags = pipeline.Tags,
|
||||
ContentSHA256 = textData.CalculateSHA256(),
|
||||
};
|
||||
newFiles.Add(destFile, destFileDetails);
|
||||
destFileDetails.MarkProcessedBy(this);
|
||||
}
|
||||
|
||||
file.MarkProcessedBy(this);
|
||||
}
|
||||
|
||||
// Add new files to pipeline status
|
||||
foreach (var file in newFiles)
|
||||
{
|
||||
uploadedFile.GeneratedFiles.Add(file.Key, file.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return (true, pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,12 @@
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using AntSK.Domain.Domain.Model;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using AntSK.Domain.Domain.Model.Excel;
|
||||
using AntSK.Domain.Domain.Other;
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.KernelMemory.Handlers;
|
||||
using System.Text;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
@@ -56,7 +60,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
//导入文本
|
||||
{
|
||||
var importResult = _memory.ImportTextAsync(req.Text, fileid, new TagCollection() { { KmsConstantcs.KmsIdTag, req.KmsId } }
|
||||
, index: KmsConstantcs.KmsIndex).Result;
|
||||
, index: KmsConstantcs.KmsIndex).Result;
|
||||
//查询文档数量
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
req.KmsDetail.Url = req.Url;
|
||||
@@ -64,6 +68,37 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportType.Excel:
|
||||
using (var fs = File.OpenRead(req.FilePath))
|
||||
{
|
||||
var excelList= ExeclHelper.ExcelToList<KMSExcelModel>(fs);
|
||||
|
||||
_memory.Orchestrator.AddHandler<TextExtractionHandler>("extract_text");
|
||||
_memory.Orchestrator.AddHandler<KMExcelHandler>("antsk_excel_split");
|
||||
_memory.Orchestrator.AddHandler<GenerateEmbeddingsHandler>("generate_embeddings");
|
||||
_memory.Orchestrator.AddHandler<SaveRecordsHandler>("save_memory_records");
|
||||
|
||||
StringBuilder text = new StringBuilder();
|
||||
foreach (var item in excelList)
|
||||
{
|
||||
text.AppendLine(@$"Question:{item.Question}{Environment.NewLine}Answer:{item.Answer}{KmsConstantcs.KMExcelSplit}");
|
||||
}
|
||||
var importResult = _memory.ImportTextAsync(text.ToString(), fileid, new TagCollection() { { KmsConstantcs.KmsIdTag, req.KmsId } }
|
||||
, index: KmsConstantcs.KmsIndex,
|
||||
steps: new[]
|
||||
{
|
||||
"extract_text",
|
||||
"antsk_excel_split",
|
||||
"generate_embeddings",
|
||||
"save_memory_records"
|
||||
}
|
||||
).Result;
|
||||
req.KmsDetail.FileName = req.FileName;
|
||||
string fileGuidName = Path.GetFileName(req.FilePath);
|
||||
req.KmsDetail.FileGuidName = fileGuidName;
|
||||
req.KmsDetail.DataCount = excelList.Count();
|
||||
}
|
||||
break;
|
||||
}
|
||||
req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Success;
|
||||
_kmsDetails_Repositories.Update(req.KmsDetail);
|
||||
|
||||
@@ -8,6 +8,7 @@ using AntSK.Domain.Domain.Other;
|
||||
using AntSK.Domain.Options;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.OCR;
|
||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||
using LLama;
|
||||
using LLamaSharp.KernelMemory;
|
||||
@@ -16,6 +17,7 @@ using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.KernelMemory.DataFormats;
|
||||
using Microsoft.KernelMemory.FileSystem.DevTools;
|
||||
using Microsoft.KernelMemory.MemoryStorage;
|
||||
using Microsoft.KernelMemory.MemoryStorage.DevTools;
|
||||
@@ -104,13 +106,15 @@ namespace AntSK.Domain.Domain.Service
|
||||
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
|
||||
OverlappingTokens = kms.OverlappingTokens
|
||||
});
|
||||
//加载OCR
|
||||
WithOcr(memoryBuild, kms);
|
||||
//加载会话模型
|
||||
WithTextGenerationByAIType(memoryBuild, chatModel, chatHttpClient);
|
||||
//加载向量模型
|
||||
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
|
||||
//加载向量库
|
||||
WithMemoryDbByVectorDB(memoryBuild);
|
||||
|
||||
|
||||
_memory = memoryBuild.Build<MemoryServerless>();
|
||||
return _memory;
|
||||
}
|
||||
@@ -119,6 +123,14 @@ namespace AntSK.Domain.Domain.Service
|
||||
//}
|
||||
}
|
||||
|
||||
private static void WithOcr(IKernelMemoryBuilder memoryBuild, Kmss kms)
|
||||
{
|
||||
if (kms.IsOCR == 1)
|
||||
{
|
||||
memoryBuild.WithCustomImageOcr(new AntSKOcrEngine());
|
||||
}
|
||||
}
|
||||
|
||||
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory, AIModels embedModel,
|
||||
HttpClient embeddingHttpClient)
|
||||
{
|
||||
@@ -193,7 +205,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
memory.WithOpenAITextGeneration(new OpenAIConfig()
|
||||
{
|
||||
APIKey = "123",
|
||||
APIKey = "NotNull",
|
||||
TextModel = chatModel.ModelName
|
||||
}, null, chatHttpClient);
|
||||
break;
|
||||
@@ -262,7 +274,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
foreach (var memoryDb in memoryDbs)
|
||||
{
|
||||
var items = await memoryDb.GetListAsync(memoryIndex.Name, new List<MemoryFilter>() { new MemoryFilter().ByDocument(fileId) }, 100, true).ToListAsync();
|
||||
var items = await memoryDb.GetListAsync(memoryIndex.Name, new List<MemoryFilter>() { new MemoryFilter().ByDocument(fileId) }, 1000, true).ToListAsync();
|
||||
docTextList.AddRange(items.Select(item => new KMFile()
|
||||
{
|
||||
DocumentId = item.GetDocumentId(),
|
||||
@@ -319,7 +331,10 @@ namespace AntSK.Domain.Domain.Service
|
||||
"application/pdf",
|
||||
"application/json",
|
||||
"text/x-markdown",
|
||||
"text/markdown"
|
||||
"text/markdown",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/tiff"
|
||||
};
|
||||
|
||||
string[] exceptExts = [".md", ".pdf"];
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// 相似度
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "70")]
|
||||
public double Relevance { get; set; } = 70;
|
||||
public double Relevance { get; set; } = 70f;
|
||||
|
||||
/// <summary>
|
||||
/// 提问最大token数
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace AntSK.Domain.Repositories
|
||||
[SugarColumn(DefaultValue = "49")]
|
||||
public int OverlappingTokens { get; set; } = 49;
|
||||
|
||||
|
||||
[SugarColumn(DefaultValue = "0")]
|
||||
public int IsOCR { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
||||
19
src/AntSK.OCR/AntSK.OCR.csproj
Normal file
19
src/AntSK.OCR/AntSK.OCR.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.35.240321.1" />
|
||||
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.9.0.20240103" />
|
||||
<PackageReference Include="Sdcb.OpenCvSharp4.mini.runtime.debian.12-x64" Version="4.8.0.20231125" />
|
||||
<PackageReference Include="Sdcb.OpenVINO" Version="0.6.4" />
|
||||
<PackageReference Include="Sdcb.OpenVINO.PaddleOCR.Models.Online" Version="0.6.2" />
|
||||
<PackageReference Include="Sdcb.OpenVINO.PaddleOCR" Version="0.6.3" />
|
||||
<PackageReference Include="Sdcb.OpenVINO.runtime.ubuntu.22.04-x64" Version="2024.0.0" />
|
||||
<PackageReference Include="Sdcb.OpenVINO.runtime.win-x64" Version="2024.0.0" />
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
57
src/AntSK.OCR/AntSKOcrEngine.cs
Normal file
57
src/AntSK.OCR/AntSKOcrEngine.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Microsoft.KernelMemory.DataFormats;
|
||||
using Sdcb.OpenVINO.PaddleOCR;
|
||||
using Sdcb.OpenVINO.PaddleOCR.Models.Online;
|
||||
using Sdcb.OpenVINO.PaddleOCR.Models;
|
||||
using OpenCvSharp;
|
||||
using static Microsoft.KernelMemory.DataFormats.WebPages.WebScraper;
|
||||
|
||||
namespace AntSK.OCR
|
||||
{
|
||||
/// <summary>
|
||||
/// OCR
|
||||
/// </summary>
|
||||
public class AntSKOcrEngine : IOcrEngine
|
||||
{
|
||||
FullOcrModel model;
|
||||
public Task<string> ExtractTextFromImageAsync(Stream imageContent, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
model = OnlineFullModels.ChineseV4.DownloadAsync().Result;
|
||||
}
|
||||
using (PaddleOcrAll all = new(model)
|
||||
{
|
||||
AllowRotateDetection = true,
|
||||
Enable180Classification = true,
|
||||
})
|
||||
{
|
||||
Mat src = Cv2.ImDecode(StreamToByte(imageContent), ImreadModes.Color);
|
||||
PaddleOcrResult result = all.Run(src);
|
||||
return Task.FromResult(result.Text);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return Task.FromResult("");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] StreamToByte(Stream stream)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
byte[] buffer = new byte[1024]; //自定义大小,例如 1024
|
||||
int bytesRead;
|
||||
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
memoryStream.Write(buffer, 0, bytesRead);
|
||||
}
|
||||
byte[] bytes = memoryStream.ToArray();
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace AntSK.PyNet
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.Test", "AntSK.Test\An
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.LLamaFactory", "AntSK.LLamaFactory\AntSK.LLamaFactory.csproj", "{664DFA1F-68B7-49C7-B889-FA14D1756D3D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntSK.OCR", "AntSK.OCR\AntSK.OCR.csproj", "{6195F7AA-18C2-4372-85CA-11FC4B522686}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Settings", "Settings", "{EB227FAB-6060-4271-9A0A-6C99C7965126}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
NuGet.config = NuGet.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -54,6 +61,10 @@ Global
|
||||
{664DFA1F-68B7-49C7-B889-FA14D1756D3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{664DFA1F-68B7-49C7-B889-FA14D1756D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{664DFA1F-68B7-49C7-B889-FA14D1756D3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6195F7AA-18C2-4372-85CA-11FC4B522686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6195F7AA-18C2-4372-85CA-11FC4B522686}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6195F7AA-18C2-4372-85CA-11FC4B522686}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6195F7AA-18C2-4372-85CA-11FC4B522686}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using AntSK.Domain.Options;
|
||||
using AntSK.Domain;
|
||||
using AntSK.Domain.Domain.Model.Excel;
|
||||
using AntSK.Domain.Options;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AntSK.Controllers
|
||||
@@ -41,5 +43,17 @@ namespace AntSK.Controllers
|
||||
|
||||
return Ok(uploads);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载模板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> DownExcelTemplate()
|
||||
{
|
||||
var list = new List<KMSExcelModel>();
|
||||
var file = ExeclHelper.ListToExcel<KMSExcelModel>(list.ToArray(), "AntSK导入模板");
|
||||
return File(file, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "AntSK导入模板.xlsx");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AntSK.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class InitController : ControllerBase
|
||||
{
|
||||
private readonly IApps_Repositories _repository;
|
||||
|
||||
public InitController(IApps_Repositories repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化DB 和表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public IActionResult InitTable()
|
||||
{
|
||||
_repository.GetDB().DbMaintenance.CreateDatabase();
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(Apps));
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(Kmss));
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(KmsDetails));
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(Users));
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(Apis));
|
||||
_repository.GetDB().CodeFirst.InitTables(typeof(AIModels));
|
||||
//创建vector插件如果数据库没有则需要提供支持向量的数据库
|
||||
_repository.GetDB().Ado.ExecuteCommandAsync($"CREATE EXTENSION IF NOT EXISTS vector;");
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
@inherits AuthComponentBase
|
||||
|
||||
<GridRow Gutter="(16, 16)">
|
||||
<GridCol Span="12">
|
||||
<GridCol Span="14">
|
||||
<Card Style="height:75vh;overflow: auto;">
|
||||
<TitleTemplate>
|
||||
<Icon Type="setting" /> 选择应用
|
||||
@@ -30,7 +30,7 @@
|
||||
</Body>
|
||||
</Card>
|
||||
</GridCol>
|
||||
<GridCol Span="12">
|
||||
<GridCol Span="10">
|
||||
<Card Style="height: 75vh;overflow: auto;">
|
||||
<TitleTemplate>
|
||||
<Icon Type="search" /> 调试结果
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
await LoadData();
|
||||
LoadData();
|
||||
var msgs = await _localStorage.GetItemAsync<List<MessageInfo>>("msgs");
|
||||
if (msgs != null && msgs.Count > 0)
|
||||
{
|
||||
@@ -61,12 +61,12 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await LoadData();
|
||||
LoadData();
|
||||
}
|
||||
|
||||
private async Task LoadData()
|
||||
private void LoadData()
|
||||
{
|
||||
app =await _apps_Repositories.GetFirstAsync(p => p.Id == AppId);
|
||||
app = _apps_Repositories.GetFirst(p => p.Id == AppId);
|
||||
}
|
||||
|
||||
protected async Task OnClearAsync()
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
<FormItem Label="重叠部分(token)" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<AntDesign.InputNumber @bind-Value="context.OverlappingTokens" PlaceHolder="重叠部分"></AntDesign.InputNumber>
|
||||
</FormItem>
|
||||
<FormItem Label="是否开启OCR" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Switch @bind-Value="@isOcr" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem Label=" " Style="margin-top:32px" WrapperCol="LayoutModel._submitFormLayout.WrapperCol">
|
||||
<Button Type="primary" HtmlType="submit">
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace AntSK.Pages.KmsPage
|
||||
|
||||
private List<AIModels> _chatList { get; set; }
|
||||
private List<AIModels> _embeddingList { get; set; }
|
||||
|
||||
private bool isOcr { get; set; }
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@@ -36,6 +38,7 @@ namespace AntSK.Pages.KmsPage
|
||||
{
|
||||
//查看
|
||||
_kmsModel = await _kmss_Repositories.GetFirstAsync(p => p.Id == KmsId);
|
||||
isOcr = _kmsModel.IsOCR == 1;
|
||||
}
|
||||
}
|
||||
private void HandleSubmit()
|
||||
@@ -51,6 +54,10 @@ namespace AntSK.Pages.KmsPage
|
||||
_ = Message.Error("行切片需小于段落切片!", 2);
|
||||
return;
|
||||
}
|
||||
if (isOcr)
|
||||
{
|
||||
_kmsModel.IsOCR = 1;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(KmsId))
|
||||
{
|
||||
|
||||
84
src/AntSK/Pages/KmsPage/Components/KmsTest.razor
Normal file
84
src/AntSK/Pages/KmsPage/Components/KmsTest.razor
Normal file
@@ -0,0 +1,84 @@
|
||||
@namespace AntSK.Pages.KmsPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using AntSK.Domain.Domain.Model.Dto
|
||||
@using AntSK.Domain.Domain.Interface
|
||||
@using AntSK.Domain.Domain.Model.Constant
|
||||
@using Microsoft.KernelMemory
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<GridContent>
|
||||
<Row Gutter="24">
|
||||
<Col Lg="7" Md="24">
|
||||
<TextArea @bind-Value="_msg" MinRows="8"/>
|
||||
<Button Type="@ButtonType.Primary" Style="margin-top:10px;" OnClick="Search">搜索</Button>
|
||||
</Col>
|
||||
<Col Lg="17" Md="24">
|
||||
<AntList DataSource="@_data" TItem="RelevantSource">
|
||||
<ListItem>
|
||||
<ListItemMeta Description="@context.Text">
|
||||
<TitleTemplate>
|
||||
<a>@("文件:" + context.SourceName + " 相似度:" + context.Relevance)</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
</ListItem>
|
||||
</AntList>
|
||||
|
||||
</Col>
|
||||
</Row>
|
||||
</GridContent>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string KmsId { get; set; }
|
||||
|
||||
[Inject]
|
||||
IKMService _kMService { get; set; }
|
||||
[Inject]
|
||||
IKmsDetails_Repositories _kmsDetails_Repositories { get; set; }
|
||||
private MemoryServerless _memory { get; set; }
|
||||
private List<RelevantSource> _data = new List<RelevantSource>();
|
||||
private string _msg;
|
||||
private Dictionary<string, string> fileNameDic = new Dictionary<string, string>();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_memory=_kMService.GetMemoryByKMS(KmsId);
|
||||
}
|
||||
|
||||
private async Task Search()
|
||||
{
|
||||
_data.Clear();
|
||||
var filters = new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, KmsId);
|
||||
var searchResult = await _memory.SearchAsync(_msg, index: KmsConstantcs.KmsIndex, filters: [filters]);
|
||||
|
||||
_data.AddRange(
|
||||
searchResult.Results.SelectMany(item => item.Partitions.Select(part => new RelevantSource()
|
||||
{
|
||||
SourceName = GetFileName(item.SourceName),
|
||||
Text = part.Text,
|
||||
Relevance = part.Relevance
|
||||
})).Take(10).ToList()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private string GetFileName(string fileGuidName)
|
||||
{
|
||||
if (fileNameDic.ContainsKey(fileGuidName))
|
||||
{
|
||||
return fileNameDic[fileGuidName];
|
||||
}
|
||||
|
||||
var fileDetail = _kmsDetails_Repositories.GetFirst(p => p.FileGuidName == fileGuidName);
|
||||
if (fileDetail == null)
|
||||
{
|
||||
return fileGuidName;
|
||||
}
|
||||
var fileName = fileDetail.FileName;
|
||||
fileNameDic.Add(fileGuidName, fileName);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,100 +6,112 @@
|
||||
@using AntSK.Services.Auth
|
||||
@inherits AuthComponentBase
|
||||
|
||||
<div>
|
||||
<PageContainer Title="知识库文档">
|
||||
<ChildContent>
|
||||
<div class="standardList">
|
||||
<Card Class="listCard"
|
||||
Title="知识库文档"
|
||||
Style="margin-top: 24px;"
|
||||
BodyStyle="padding: 0 32px 40px 32px">
|
||||
|
||||
<Extra>
|
||||
<Button Type="@ButtonType.Primary" Style="position: absolute; right:360px; margin-bottom: 8px;" OnClick="Refresh">刷新 </Button>
|
||||
<Dropdown Style="position: absolute; right: 20px; margin-bottom: 8px;" Trigger="@(new Trigger[] { Trigger.Click })">
|
||||
<Overlay>
|
||||
<Menu>
|
||||
@(_fileUpload(() => FileShowModal()))
|
||||
@(_urlUpload(() => UrlShowModal()))
|
||||
@(_textUpload(() => TextShowModal()))
|
||||
</Menu>
|
||||
</Overlay>
|
||||
<Card Class="tabsCard">
|
||||
<CardTabs>
|
||||
<Tabs DefaultActiveKey="1">
|
||||
<TabPane Key="1">
|
||||
<TabTemplate>知识库文档</TabTemplate>
|
||||
<ChildContent>
|
||||
<div class="standardList">
|
||||
<Card Class="listCard"
|
||||
Title="知识库文档"
|
||||
>
|
||||
|
||||
<Extra>
|
||||
<Button Type="@ButtonType.Primary" Style="position: absolute; right:360px; margin-bottom: 8px;" OnClick="Refresh">刷新 </Button>
|
||||
<Dropdown Style="position: absolute; right: 20px; margin-bottom: 8px;" Trigger="@(new Trigger[] { Trigger.Click })">
|
||||
<Overlay>
|
||||
<Menu>
|
||||
@(_fileUpload(() => FileShowModal()))
|
||||
@(_urlUpload(() => UrlShowModal()))
|
||||
@(_textUpload(() => TextShowModal()))
|
||||
@(_excelUpload(() => ExcelShowModal()))
|
||||
</Menu>
|
||||
</Overlay>
|
||||
<ChildContent>
|
||||
<Button>导入 <Icon Type="down" /></Button>
|
||||
</ChildContent>
|
||||
</Dropdown>
|
||||
<div class="extraContent" style="margin-right:100px;">
|
||||
<Search Class="extraContentSearch" Placeholder="搜索文档" @bind-Value="_model.Id" />
|
||||
</div>
|
||||
|
||||
</Extra>
|
||||
<ChildContent>
|
||||
<Button>导入 <Icon Type="down" /></Button>
|
||||
</ChildContent>
|
||||
</Dropdown>
|
||||
<div class="extraContent" style="margin-right:100px;">
|
||||
<Search Class="extraContentSearch" Placeholder="搜索文档" @bind-Value="_model.Id" />
|
||||
</div>
|
||||
|
||||
</Extra>
|
||||
<ChildContent>
|
||||
<AntList TItem="KmsDetails"
|
||||
DataSource="_data"
|
||||
ItemLayout="ListItemLayout.Horizontal">
|
||||
<ListItem Actions="@(new[] {
|
||||
<AntList TItem="KmsDetails"
|
||||
DataSource="_data"
|
||||
ItemLayout="ListItemLayout.Horizontal" Size="small">
|
||||
<ListItem Actions="@(new[] {
|
||||
detail(()=> FileDetail(context.Id)) ,
|
||||
delete(async ()=>await DeleteFile(context.Id)) ,
|
||||
})">
|
||||
<ListItemMeta Description="@context.Id">
|
||||
<TitleTemplate>
|
||||
<div>文件ID</div>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<ListItemMeta Description="@context.Type">
|
||||
<TitleTemplate>
|
||||
<div>文件类型</div>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
@if (@context.Type == "file")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="@context.FileName">
|
||||
<TitleTemplate>
|
||||
<a>文件名称</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
else if (@context.Type == "url")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="@context.Url">
|
||||
<TitleTemplate>
|
||||
<a href="@context.Url" target="_blank">Url</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
else if (@context.Type == "text")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="……">
|
||||
<TitleTemplate>
|
||||
<a>文本内容</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
<ListItemMeta Avatar="" Description="@context.DataCount.ToString()">
|
||||
<TitleTemplate>
|
||||
<a>文档切片数量</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<ListItemMeta Avatar="" Description="@context.Status.ToString()">
|
||||
<TitleTemplate>
|
||||
<a>状态</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<div class="listContent">
|
||||
<div class="listContentItem">
|
||||
<span>创建时间</span>
|
||||
<p>@context.CreateTime.ToString("yyyy-MM-dd HH:mm")</p>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
</AntList>
|
||||
</ChildContent>
|
||||
</Card>
|
||||
</div>
|
||||
</ChildContent>
|
||||
</PageContainer>
|
||||
</div>
|
||||
<ListItemMeta Description="@context.Id">
|
||||
<TitleTemplate>
|
||||
<div>文件ID</div>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<ListItemMeta Description="@context.Type">
|
||||
<TitleTemplate>
|
||||
<div>文件类型</div>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
@if (@context.Type == "file" || @context.Type == "excel")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="@context.FileName">
|
||||
<TitleTemplate>
|
||||
<a>文件名称</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
else if (@context.Type == "url")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="@context.Url">
|
||||
<TitleTemplate>
|
||||
<a href="@context.Url" target="_blank">Url</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
else if (@context.Type == "text")
|
||||
{
|
||||
<ListItemMeta Avatar="" Description="……">
|
||||
<TitleTemplate>
|
||||
<a>文本内容</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
}
|
||||
<ListItemMeta Avatar="" Description="@context.DataCount.ToString()">
|
||||
<TitleTemplate>
|
||||
<a>文档切片数量</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<ListItemMeta Avatar="" Description="@context.Status.ToString()">
|
||||
<TitleTemplate>
|
||||
<a>状态</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<div class="listContent">
|
||||
<div class="listContentItem">
|
||||
<span>创建时间</span>
|
||||
<p>@context.CreateTime.ToString("yyyy-MM-dd HH:mm")</p>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
</AntList>
|
||||
</ChildContent>
|
||||
</Card>
|
||||
</div>
|
||||
</ChildContent>
|
||||
</TabPane>
|
||||
<TabPane Key="2">
|
||||
<TabTemplate>搜索测试</TabTemplate>
|
||||
<ChildContent>
|
||||
<KmsTest KmsId="@KmsId"></KmsTest>
|
||||
</ChildContent>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</CardTabs>
|
||||
</Card>
|
||||
|
||||
<Modal Title="链接读取"
|
||||
Visible="@_urlVisible"
|
||||
@@ -147,15 +159,46 @@
|
||||
<Icon Type="inbox" />
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
@if (km.IsOCR == 1)
|
||||
{
|
||||
<p class="ant-upload-hint">
|
||||
支持 txt、word、pdf、md、excel、ppt、jpeg、png、tiff 等文件。
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="ant-upload-hint">
|
||||
支持 txt、word、pdf、md、excel、ppt 等文件。
|
||||
</p>
|
||||
}
|
||||
|
||||
</Upload>
|
||||
</Modal>
|
||||
|
||||
<Modal Title="Excel导入"
|
||||
Visible="@_excelVisible"
|
||||
OnOk="@ExcelHandleOk"
|
||||
OnCancel="@ExcelHandleCancel"
|
||||
ConfirmLoading="@_excelConfirmLoading">
|
||||
<a href="api/File/DownExcelTemplate" target="_blank">下载模板</a>
|
||||
<Upload Action="@("api/File/UploadFile")"
|
||||
Name="file"
|
||||
Drag
|
||||
Multiple
|
||||
Accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
BeforeUpload="iKMService.BeforeUpload"
|
||||
OnSingleCompleted="iKMService.OnSingleCompleted">
|
||||
<p class="ant-upload-drag-icon">
|
||||
<Icon Type="inbox" />
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
<p class="ant-upload-hint">
|
||||
支持txt、word、pdf、md、excel、ppt等文件。
|
||||
支持excel文件。
|
||||
</p>
|
||||
</Upload>
|
||||
</Modal>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
RenderFragment _fileUpload(Action clickAction) =>@<MenuItem>
|
||||
<a target="_blank" rel="noopener noreferrer" @onclick="@clickAction">
|
||||
文件导入
|
||||
@@ -174,6 +217,12 @@
|
||||
</a>
|
||||
</MenuItem>;
|
||||
|
||||
RenderFragment _excelUpload(Action clickAction) =>@<MenuItem>
|
||||
<a target="_blank" rel="noopener noreferrer" @onclick="@clickAction">
|
||||
Excel导入
|
||||
</a>
|
||||
</MenuItem>;
|
||||
|
||||
RenderFragment detail(Action clickAction) => @<a key="detail" @onclick="@clickAction">详情</a>;
|
||||
RenderFragment delete(Action clickAction) => @<a key="edit" @onclick="@clickAction">删除</a>;
|
||||
}
|
||||
|
||||
@@ -19,35 +19,6 @@ namespace AntSK.Pages.KmsPage
|
||||
[Parameter]
|
||||
public string KmsId { get; set; }
|
||||
|
||||
private readonly KmsDetails _model = new KmsDetails();
|
||||
|
||||
private bool _urlVisible = false;
|
||||
private bool _urlConfirmLoading = false;
|
||||
|
||||
private bool _fileVisible = false;
|
||||
private bool _fileConfirmLoading = false;
|
||||
|
||||
private bool _textVisible = false;
|
||||
private bool _textConfirmLoading = false;
|
||||
|
||||
private List<FileInfoModel> fileList = new List<FileInfoModel>();
|
||||
|
||||
private Form<UrlModel> _urlForm;
|
||||
private UrlModel urlModel = new UrlModel();
|
||||
|
||||
private Form<TextModel> _textForm;
|
||||
private TextModel textModel = new TextModel();
|
||||
|
||||
private readonly IDictionary<string, ProgressStatus> _pStatus = new Dictionary<string, ProgressStatus>
|
||||
{
|
||||
{"active", ProgressStatus.Active},
|
||||
{"exception", ProgressStatus.Exception},
|
||||
{"normal", ProgressStatus.Normal},
|
||||
{"success", ProgressStatus.Success}
|
||||
};
|
||||
|
||||
private List<KmsDetails> _data = new List<KmsDetails>();
|
||||
|
||||
[Inject]
|
||||
protected IConfirmService _confirmService { get; set; }
|
||||
|
||||
@@ -71,11 +42,49 @@ namespace AntSK.Pages.KmsPage
|
||||
[Inject]
|
||||
protected IHttpService _httpService { get; set; }
|
||||
|
||||
private Kmss km;
|
||||
|
||||
private readonly KmsDetails _model = new KmsDetails();
|
||||
|
||||
private bool _urlVisible = false;
|
||||
private bool _urlConfirmLoading = false;
|
||||
|
||||
private bool _fileVisible = false;
|
||||
private bool _fileConfirmLoading = false;
|
||||
|
||||
private bool _textVisible = false;
|
||||
private bool _textConfirmLoading = false;
|
||||
|
||||
private bool _excelVisible = false;
|
||||
private bool _excelConfirmLoading = false;
|
||||
|
||||
private List<FileInfoModel> fileList = new List<FileInfoModel>();
|
||||
|
||||
private Form<UrlModel> _urlForm;
|
||||
private UrlModel urlModel = new UrlModel();
|
||||
|
||||
private Form<TextModel> _textForm;
|
||||
private TextModel textModel = new TextModel();
|
||||
|
||||
private readonly IDictionary<string, ProgressStatus> _pStatus = new Dictionary<string, ProgressStatus>
|
||||
{
|
||||
{"active", ProgressStatus.Active},
|
||||
{"exception", ProgressStatus.Exception},
|
||||
{"normal", ProgressStatus.Normal},
|
||||
{"success", ProgressStatus.Success}
|
||||
};
|
||||
|
||||
private List<KmsDetails> _data = new List<KmsDetails>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_data = await _kmsDetails_Repositories.GetListAsync(p => p.KmsId == KmsId);
|
||||
var km = _kmss_Repositories.GetFirst(p => p.Id == KmsId);
|
||||
km = _kmss_Repositories.GetFirst(p => p.Id == KmsId);
|
||||
//使用知识库设置的参数,
|
||||
_memory = iKMService.GetMemoryByKMS(km.Id);
|
||||
}
|
||||
@@ -212,19 +221,47 @@ namespace AntSK.Pages.KmsPage
|
||||
_fileVisible = true;
|
||||
}
|
||||
|
||||
private void OnSingleCompleted(UploadInfo fileinfo)
|
||||
#endregion File
|
||||
|
||||
#region Excel
|
||||
private async Task ExcelHandleOk(MouseEventArgs e)
|
||||
{
|
||||
if (fileinfo.File.State == UploadState.Success)
|
||||
try
|
||||
{
|
||||
//文件列表
|
||||
fileList.Add(new FileInfoModel()
|
||||
foreach (var item in iKMService.FileList)
|
||||
{
|
||||
FileName = fileinfo.File.FileName,
|
||||
FilePath = fileinfo.File.Url = fileinfo.File.Response
|
||||
});
|
||||
var result = await _httpService.PostAsync(NavigationManager.BaseUri + "api/KMS/ImportKMSTask", new ImportKMSTaskDTO()
|
||||
{
|
||||
ImportType = ImportType.Excel,
|
||||
KmsId = KmsId,
|
||||
FilePath = item.Url,
|
||||
FileName = item.FileName
|
||||
});
|
||||
}
|
||||
_data = await _kmsDetails_Repositories.GetListAsync(p => p.KmsId == KmsId);
|
||||
//上传文档
|
||||
_excelVisible = false;
|
||||
iKMService.FileList.Clear();
|
||||
_ = _message.Info("加入队列,进入后台处理中!", 2);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExcelHandleCancel(MouseEventArgs e)
|
||||
{
|
||||
_excelVisible = false;
|
||||
}
|
||||
|
||||
private void ExcelShowModal()
|
||||
{
|
||||
_excelVisible = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void FileDetail(string fileid)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/kms/detaillist/{KmsId}/{fileid}");
|
||||
@@ -256,7 +293,5 @@ namespace AntSK.Pages.KmsPage
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion File
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,30 @@
|
||||
|
||||
|
||||
<Button Type="@ButtonType.Primary" OnClick="NavigateBack">返回</Button>
|
||||
<AntList DataSource="@_data" TItem="KMFile">
|
||||
<Divider />
|
||||
<AntList DataSource="@_data" TItem="KMFile" ItemLayout="ListItemLayout.Horizontal" Grid="LayoutModel._listGridType">
|
||||
<ListItem >
|
||||
<ListItemMeta Description="@context.Text">
|
||||
<TitleTemplate>
|
||||
<a>@context.LastUpdate</a>
|
||||
</TitleTemplate>
|
||||
</ListItemMeta>
|
||||
<Card Hoverable Bordered Class="card" Style="max-height:247px;" Actions="(new[] {
|
||||
info(()=> Info(context.Text)) ,
|
||||
})">
|
||||
<CardMeta>
|
||||
<DescriptionTemplate>
|
||||
<Paragraph class="item" Ellipsis Style="display: -webkit-box; -webkit-line-clamp: 3;-webkit-box-orient: vertical;overflow: hidden; text-overflow: ellipsis;white-space: normal;height:65px;">
|
||||
<!--todo: Ellipsis not working-->
|
||||
@context.Text
|
||||
</Paragraph>
|
||||
</DescriptionTemplate>
|
||||
</CardMeta>
|
||||
</Card>
|
||||
</ListItem>
|
||||
</AntList>
|
||||
|
||||
@code {
|
||||
<Modal Visible="_infolVisible" Footer="null" Closable Title="详情" OnCancel="OnCancelLog" DestroyOnClose Width="1000" MaxBodyHeight="600">
|
||||
<Paragraph>
|
||||
@_infoText
|
||||
</Paragraph>
|
||||
</Modal>
|
||||
|
||||
@code {
|
||||
RenderFragment info(Action clickAction) =>@<a key="info" @onclick="@clickAction">查看</a>;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ namespace AntSK.Pages.KmsPage
|
||||
|
||||
private List<KMFile> _data = new List<KMFile>();
|
||||
|
||||
private bool _infolVisible=false;
|
||||
private string _infoText = "";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@@ -26,5 +29,16 @@ namespace AntSK.Pages.KmsPage
|
||||
{
|
||||
NavigationManager.NavigateTo($"/kms/detail/{KmsId}");
|
||||
}
|
||||
|
||||
private void Info(string text)
|
||||
{
|
||||
_infoText = text;
|
||||
_infolVisible = true;
|
||||
}
|
||||
|
||||
private void OnCancelLog()
|
||||
{
|
||||
_infolVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
@context.Describe
|
||||
</span>
|
||||
<br />
|
||||
<span style="color:#c6c6c6">行切片:@context.MaxTokensPerLine 段落切片:@context.MaxTokensPerParagraph 重叠:@context.OverlappingTokens</span>
|
||||
<span style="color:#c6c6c6">段落切片:@context.MaxTokensPerParagraph 行切片:@context.MaxTokensPerLine 重叠:@context.OverlappingTokens</span>
|
||||
</Paragraph>
|
||||
</DescriptionTemplate>
|
||||
</CardMeta>
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace AntSK.Pages.Setting.AIModel
|
||||
switch (aiType)
|
||||
{
|
||||
case AIType.LLamaFactory:
|
||||
_aiModel.EndPoint = "http://localhost:8080/";
|
||||
_aiModel.EndPoint = "http://localhost:8000/";
|
||||
_aiModel.AIModelType=AIModelType.Chat;
|
||||
break;
|
||||
case AIType.StableDiffusion:
|
||||
|
||||
@@ -65,15 +65,14 @@ builder.Services.AddBackgroundTaskBroker().AddHandler<ImportKMSTaskReq, BackGrou
|
||||
{
|
||||
NativeLibraryConfig
|
||||
.Instance
|
||||
.WithCuda(false)
|
||||
.WithLogs(true);
|
||||
.WithCuda(false);
|
||||
}
|
||||
else if (LLamaSharpOption.RunType.ToUpper() == "GPU")
|
||||
{
|
||||
NativeLibraryConfig
|
||||
.Instance
|
||||
.WithCuda(true)
|
||||
.WithLogs(true);
|
||||
.WithAvx(NativeLibraryConfig.AvxLevel.Avx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user