feat: Added web page for configuring model information

This commit is contained in:
wizardchen
2025-08-10 17:04:39 +08:00
committed by lyingbug
parent 4498442fcc
commit bdabed6bfa
43 changed files with 5689 additions and 338 deletions

View File

@@ -0,0 +1,278 @@
import { get, post } from '../../utils/request';
// 初始化配置数据类型
export interface InitializationConfig {
llm: {
source: string;
modelName: string;
baseUrl?: string;
apiKey?: string;
};
embedding: {
source: string;
modelName: string;
baseUrl?: string;
apiKey?: string;
dimension?: number; // 添加embedding维度字段
};
rerank: {
modelName: string;
baseUrl: string;
apiKey?: string;
};
multimodal: {
enabled: boolean;
vlm?: {
modelName: string;
baseUrl: string;
apiKey?: string;
interfaceType?: string; // "ollama" or "openai"
};
cos?: {
secretId: string;
secretKey: string;
region: string;
bucketName: string;
appId: string;
pathPrefix?: string;
};
};
documentSplitting: {
chunkSize: number;
chunkOverlap: number;
separators: string[];
};
}
// 下载任务状态类型
export interface DownloadTask {
id: string;
modelName: string;
status: 'pending' | 'downloading' | 'completed' | 'failed';
progress: number;
message: string;
startTime: string;
endTime?: string;
}
// 系统初始化状态检查
export function checkInitializationStatus(): Promise<{ initialized: boolean }> {
return new Promise((resolve, reject) => {
get('/api/v1/initialization/status')
.then((response: any) => {
resolve(response.data || { initialized: false });
})
.catch((error: any) => {
console.warn('检查初始化状态失败,假设需要初始化:', error);
resolve({ initialized: false });
});
});
}
// 执行系统初始化
export function initializeSystem(config: InitializationConfig): Promise<any> {
return new Promise((resolve, reject) => {
console.log('开始系统初始化...', config);
post('/api/v1/initialization/initialize', config)
.then((response: any) => {
console.log('系统初始化完成', response);
// 设置本地初始化状态标记
localStorage.setItem('system_initialized', 'true');
resolve(response);
})
.catch((error: any) => {
console.error('系统初始化失败:', error);
reject(error);
});
});
}
// 检查Ollama服务状态
export function checkOllamaStatus(): Promise<{ available: boolean; version?: string; error?: string }> {
return new Promise((resolve, reject) => {
get('/api/v1/initialization/ollama/status')
.then((response: any) => {
resolve(response.data || { available: false });
})
.catch((error: any) => {
console.error('检查Ollama状态失败:', error);
resolve({ available: false, error: error.message || '检查失败' });
});
});
}
// 检查Ollama模型状态
export function checkOllamaModels(models: string[]): Promise<{ models: Record<string, boolean> }> {
return new Promise((resolve, reject) => {
post('/api/v1/initialization/ollama/models/check', { models })
.then((response: any) => {
resolve(response.data || { models: {} });
})
.catch((error: any) => {
console.error('检查Ollama模型状态失败:', error);
reject(error);
});
});
}
// 启动Ollama模型下载异步
export function downloadOllamaModel(modelName: string): Promise<{ taskId: string; modelName: string; status: string; progress: number }> {
return new Promise((resolve, reject) => {
post('/api/v1/initialization/ollama/models/download', { modelName })
.then((response: any) => {
resolve(response.data || { taskId: '', modelName, status: 'failed', progress: 0 });
})
.catch((error: any) => {
console.error('启动Ollama模型下载失败:', error);
reject(error);
});
});
}
// 查询下载进度
export function getDownloadProgress(taskId: string): Promise<DownloadTask> {
return new Promise((resolve, reject) => {
get(`/api/v1/initialization/ollama/download/progress/${taskId}`)
.then((response: any) => {
resolve(response.data);
})
.catch((error: any) => {
console.error('查询下载进度失败:', error);
reject(error);
});
});
}
// 获取所有下载任务
export function listDownloadTasks(): Promise<DownloadTask[]> {
return new Promise((resolve, reject) => {
get('/api/v1/initialization/ollama/download/tasks')
.then((response: any) => {
resolve(response.data || []);
})
.catch((error: any) => {
console.error('获取下载任务列表失败:', error);
reject(error);
});
});
}
// 获取当前系统配置
export function getCurrentConfig(): Promise<InitializationConfig & { hasFiles: boolean }> {
return new Promise((resolve, reject) => {
get('/api/v1/initialization/config')
.then((response: any) => {
resolve(response.data || {});
})
.catch((error: any) => {
console.error('获取当前配置失败:', error);
reject(error);
});
});
}
// 检查远程API模型
export function checkRemoteModel(modelConfig: {
modelName: string;
baseUrl: string;
apiKey?: string;
}): Promise<{
available: boolean;
message?: string;
}> {
return new Promise((resolve, reject) => {
post('/api/v1/initialization/remote/check', modelConfig)
.then((response: any) => {
resolve(response.data || {});
})
.catch((error: any) => {
console.error('检查远程模型失败:', error);
reject(error);
});
});
}
export function checkRerankModel(modelConfig: {
modelName: string;
baseUrl: string;
apiKey?: string;
}): Promise<{
available: boolean;
message?: string;
}> {
return new Promise((resolve, reject) => {
post('/api/v1/initialization/rerank/check', modelConfig)
.then((response: any) => {
resolve(response.data || {});
})
.catch((error: any) => {
console.error('检查Rerank模型失败:', error);
reject(error);
});
});
}
export function testMultimodalFunction(testData: {
image: File;
vlm_model: string;
vlm_base_url: string;
vlm_api_key?: string;
vlm_interface_type?: string;
cos_secret_id: string;
cos_secret_key: string;
cos_region: string;
cos_bucket_name: string;
cos_app_id: string;
cos_path_prefix?: string;
chunk_size: number;
chunk_overlap: number;
separators: string[];
}): Promise<{
success: boolean;
caption?: string;
ocr?: string;
processing_time?: number;
message?: string;
}> {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append('image', testData.image);
formData.append('vlm_model', testData.vlm_model);
formData.append('vlm_base_url', testData.vlm_base_url);
if (testData.vlm_api_key) {
formData.append('vlm_api_key', testData.vlm_api_key);
}
if (testData.vlm_interface_type) {
formData.append('vlm_interface_type', testData.vlm_interface_type);
}
formData.append('cos_secret_id', testData.cos_secret_id);
formData.append('cos_secret_key', testData.cos_secret_key);
formData.append('cos_region', testData.cos_region);
formData.append('cos_bucket_name', testData.cos_bucket_name);
formData.append('cos_app_id', testData.cos_app_id);
if (testData.cos_path_prefix) {
formData.append('cos_path_prefix', testData.cos_path_prefix);
}
formData.append('chunk_size', testData.chunk_size.toString());
formData.append('chunk_overlap', testData.chunk_overlap.toString());
formData.append('separators', JSON.stringify(testData.separators));
// 使用原生fetch因为需要发送FormData
fetch('/api/v1/initialization/multimodal/test', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then((data: any) => {
if (data.success) {
resolve(data.data || {});
} else {
resolve({ success: false, message: data.message || '测试失败' });
}
})
.catch((error: any) => {
console.error('多模态测试失败:', error);
reject(error);
});
});
}

View File

@@ -173,7 +173,12 @@ const getIcon = (path) => {
getIcon(route.name)
const gotopage = (path) => {
pathPrefix.value = path;
router.push(`/platform/${path}`);
// 如果是系统设置,跳转到初始化配置页面
if (path === 'settings') {
router.push('/initialization');
} else {
router.push(`/platform/${path}`);
}
getIcon(path)
}

View File

@@ -23,7 +23,7 @@ export default function () {
});
const getKnowled = (query = { page: 1, page_size: 35 }) => {
getKnowledgeBase(query)
.then((result: object) => {
.then((result: any) => {
let { data, total: totalResult } = result;
let cardList_ = data.map((item) => {
item["file_name"] = item.file_name.substring(
@@ -50,7 +50,7 @@ export default function () {
cardList.value[index].isMore = false;
moreIndex.value = -1;
delKnowledgeDetails(item.id)
.then((result) => {
.then((result: any) => {
if (result.success) {
MessagePlugin.info("知识删除成功!");
getKnowled();
@@ -76,17 +76,29 @@ export default function () {
return;
}
uploadKnowledgeBase({ file })
.then((result) => {
.then((result: any) => {
if (result.success) {
MessagePlugin.info("上传成功!");
getKnowled();
} else {
MessagePlugin.error("上传失败!");
// 检查错误码,如果是重复文件则显示特定提示
if (result.code === 'duplicate_file') {
MessagePlugin.error("文件已存在");
} else {
MessagePlugin.error(result.message || (result.error && result.error.message) || "上传失败!");
}
}
uploadInput.value.value = "";
})
.catch((err) => {
MessagePlugin.error("上传失败!");
.catch((err: any) => {
// 检查错误响应中的错误码
if (err.code === 'duplicate_file') {
MessagePlugin.error("文件已存在");
} else if (err.message) {
MessagePlugin.error(err.message);
} else {
MessagePlugin.error("上传失败!");
}
uploadInput.value.value = "";
});
} else {
@@ -101,7 +113,7 @@ export default function () {
id: "",
});
getKnowledgeDetails(item.id)
.then((result) => {
.then((result: any) => {
if (result.success && result.data) {
let { data } = result;
Object.assign(details, {
@@ -116,7 +128,7 @@ export default function () {
};
const getfDetails = (id, page) => {
getKnowledgeDetailsCon(id, page)
.then((result) => {
.then((result: any) => {
if (result.success && result.data) {
let { data, total: totalResult } = result;
if (page == 1) {

View File

@@ -1,4 +1,5 @@
import { createRouter, createWebHistory } from 'vue-router'
import { checkInitializationStatus } from '@/api/initialization'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -7,40 +8,82 @@ const router = createRouter({
path: "/",
redirect: "/platform",
},
{
path: "/initialization",
name: "initialization",
component: () => import("../views/initialization/InitializationConfig.vue"),
meta: { requiresInit: false } // 初始化页面不需要检查初始化状态
},
{
path: "/knowledgeBase",
name: "home",
component: () => import("../views/knowledge/KnowledgeBase.vue"),
meta: { requiresInit: true }
},
{
path: "/platform",
name: "Platform",
redirect: "/platform/knowledgeBase",
component: () => import("../views/platform/index.vue"),
meta: { requiresInit: true },
children: [
{
path: "knowledgeBase",
name: "knowledgeBase",
component: () => import("../views/knowledge/KnowledgeBase.vue"),
meta: { requiresInit: true }
},
{
path: "creatChat",
name: "creatChat",
component: () => import("../views/creatChat/creatChat.vue"),
meta: { requiresInit: true }
},
{
path: "chat/:chatid",
name: "chat",
component: () => import("../views/chat/index.vue"),
meta: { requiresInit: true }
},
{
path: "settings",
name: "settings",
component: () => import("../views/settings/Settings.vue"),
meta: { requiresInit: true }
},
],
},
],
});
// 路由守卫:检查系统初始化状态
router.beforeEach(async (to, from, next) => {
// 如果访问的是初始化页面,直接放行
if (to.meta.requiresInit === false) {
next();
return;
}
1
try {
// 检查系统是否已初始化
const { initialized } = await checkInitializationStatus();
if (initialized) {
// 系统已初始化,记录到本地存储并正常跳转
localStorage.setItem('system_initialized', 'true');
next();
} else {
// 系统未初始化,跳转到初始化页面
console.log('系统未初始化,跳转到初始化页面');
next('/initialization');
}
} catch (error) {
console.error('检查初始化状态失败:', error);
// 如果检查失败,默认认为需要初始化
next('/initialization');
}
});
export default router

File diff suppressed because it is too large Load Diff