feat(knowledgebase): 添加知识库头像功能
- 在知识库详情中增加头像字段 - 实现知识库头像的上传和显示功能 - 优化知识库编辑界面,支持头像修改 - 调整后端 API 和数据库以支持头像存储
This commit is contained in:
parent
bee2ed1625
commit
86256b3399
|
@ -1,19 +1,22 @@
|
|||
import traceback
|
||||
|
||||
from flask import request
|
||||
from services.knowledgebases.service import KnowledgebaseService
|
||||
from utils import success_response, error_response
|
||||
from utils import error_response, success_response
|
||||
|
||||
from .. import knowledgebase_bp
|
||||
|
||||
@knowledgebase_bp.route('', methods=['GET'])
|
||||
|
||||
@knowledgebase_bp.route("", methods=["GET"])
|
||||
def get_knowledgebase_list():
|
||||
"""获取知识库列表"""
|
||||
try:
|
||||
params = {
|
||||
'page': int(request.args.get('currentPage', 1)),
|
||||
'size': int(request.args.get('size', 10)),
|
||||
'name': request.args.get('name', ''),
|
||||
'sort_by': request.args.get("sort_by", "create_time"),
|
||||
'sort_order': request.args.get("sort_order", "desc")
|
||||
"page": int(request.args.get("currentPage", 1)),
|
||||
"size": int(request.args.get("size", 10)),
|
||||
"name": request.args.get("name", ""),
|
||||
"sort_by": request.args.get("sort_by", "create_time"),
|
||||
"sort_order": request.args.get("sort_order", "desc"),
|
||||
}
|
||||
result = KnowledgebaseService.get_knowledgebase_list(**params)
|
||||
return success_response(result)
|
||||
|
@ -22,87 +25,84 @@ def get_knowledgebase_list():
|
|||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/<string:kb_id>', methods=['GET'])
|
||||
|
||||
@knowledgebase_bp.route("/<string:kb_id>", methods=["GET"])
|
||||
def get_knowledgebase_detail(kb_id):
|
||||
"""获取知识库详情"""
|
||||
try:
|
||||
knowledgebase = KnowledgebaseService.get_knowledgebase_detail(
|
||||
kb_id=kb_id
|
||||
)
|
||||
knowledgebase = KnowledgebaseService.get_knowledgebase_detail(kb_id=kb_id)
|
||||
if not knowledgebase:
|
||||
return error_response('知识库不存在', code=404)
|
||||
return error_response("知识库不存在", code=404)
|
||||
return success_response(knowledgebase)
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('', methods=['POST'])
|
||||
|
||||
@knowledgebase_bp.route("", methods=["POST"])
|
||||
def create_knowledgebase():
|
||||
"""创建知识库"""
|
||||
try:
|
||||
data = request.json
|
||||
if not data.get('name'):
|
||||
return error_response('知识库名称不能为空', code=400)
|
||||
|
||||
if not data.get("name"):
|
||||
return error_response("知识库名称不能为空", code=400)
|
||||
|
||||
# 移除 created_by 参数
|
||||
kb = KnowledgebaseService.create_knowledgebase(**data)
|
||||
return success_response(kb, "创建成功", code=0)
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/<string:kb_id>', methods=['PUT'])
|
||||
|
||||
@knowledgebase_bp.route("/<string:kb_id>", methods=["PUT"])
|
||||
def update_knowledgebase(kb_id):
|
||||
"""更新知识库"""
|
||||
try:
|
||||
data = request.json
|
||||
kb = KnowledgebaseService.update_knowledgebase(
|
||||
kb_id=kb_id,
|
||||
**data
|
||||
)
|
||||
kb = KnowledgebaseService.update_knowledgebase(kb_id=kb_id, **data)
|
||||
if not kb:
|
||||
return error_response('知识库不存在', code=404)
|
||||
return error_response("知识库不存在", code=404)
|
||||
return success_response(kb)
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/<string:kb_id>', methods=['DELETE'])
|
||||
|
||||
@knowledgebase_bp.route("/<string:kb_id>", methods=["DELETE"])
|
||||
def delete_knowledgebase(kb_id):
|
||||
"""删除知识库"""
|
||||
try:
|
||||
result = KnowledgebaseService.delete_knowledgebase(
|
||||
kb_id=kb_id
|
||||
)
|
||||
result = KnowledgebaseService.delete_knowledgebase(kb_id=kb_id)
|
||||
if not result:
|
||||
return error_response('知识库不存在', code=404)
|
||||
return success_response(message='删除成功')
|
||||
return error_response("知识库不存在", code=404)
|
||||
return success_response(message="删除成功")
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/batch', methods=['DELETE'])
|
||||
|
||||
@knowledgebase_bp.route("/batch", methods=["DELETE"])
|
||||
def batch_delete_knowledgebase():
|
||||
"""批量删除知识库"""
|
||||
try:
|
||||
data = request.json
|
||||
if not data or not data.get('ids'):
|
||||
return error_response('请选择要删除的知识库', code=400)
|
||||
|
||||
result = KnowledgebaseService.batch_delete_knowledgebase(
|
||||
kb_ids=data['ids']
|
||||
)
|
||||
return success_response(message=f'成功删除 {result} 个知识库')
|
||||
if not data or not data.get("ids"):
|
||||
return error_response("请选择要删除的知识库", code=400)
|
||||
|
||||
result = KnowledgebaseService.batch_delete_knowledgebase(kb_ids=data["ids"])
|
||||
return success_response(message=f"成功删除 {result} 个知识库")
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/<string:kb_id>/documents', methods=['GET'])
|
||||
|
||||
@knowledgebase_bp.route("/<string:kb_id>/documents", methods=["GET"])
|
||||
def get_knowledgebase_documents(kb_id):
|
||||
"""获取知识库下的文档列表"""
|
||||
try:
|
||||
params = {
|
||||
'kb_id': kb_id,
|
||||
'page': int(request.args.get('currentPage', 1)),
|
||||
'size': int(request.args.get('size', 10)),
|
||||
'name': request.args.get('name', ''),
|
||||
'sort_by': request.args.get("sort_by", "create_time"),
|
||||
'sort_order': request.args.get("sort_order", "desc")
|
||||
"kb_id": kb_id,
|
||||
"page": int(request.args.get("currentPage", 1)),
|
||||
"size": int(request.args.get("size", 10)),
|
||||
"name": request.args.get("name", ""),
|
||||
"sort_by": request.args.get("sort_by", "create_time"),
|
||||
"sort_order": request.args.get("sort_order", "desc"),
|
||||
}
|
||||
result = KnowledgebaseService.get_knowledgebase_documents(**params)
|
||||
return success_response(result)
|
||||
|
@ -111,7 +111,8 @@ def get_knowledgebase_documents(kb_id):
|
|||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/<string:kb_id>/documents', methods=['POST'])
|
||||
|
||||
@knowledgebase_bp.route("/<string:kb_id>/documents", methods=["POST"])
|
||||
def add_documents_to_knowledgebase(kb_id):
|
||||
"""添加文档到知识库"""
|
||||
try:
|
||||
|
@ -119,89 +120,86 @@ def add_documents_to_knowledgebase(kb_id):
|
|||
data = request.json
|
||||
if not data:
|
||||
print("[ERROR] 请求数据为空")
|
||||
return error_response('请求数据不能为空', code=400)
|
||||
|
||||
file_ids = data.get('file_ids', [])
|
||||
return error_response("请求数据不能为空", code=400)
|
||||
|
||||
file_ids = data.get("file_ids", [])
|
||||
print(f"[DEBUG] 接收到的file_ids: {file_ids}, 类型: {type(file_ids)}")
|
||||
|
||||
|
||||
try:
|
||||
result = KnowledgebaseService.add_documents_to_knowledgebase(
|
||||
kb_id=kb_id,
|
||||
file_ids=file_ids
|
||||
)
|
||||
result = KnowledgebaseService.add_documents_to_knowledgebase(kb_id=kb_id, file_ids=file_ids)
|
||||
print(f"[DEBUG] 服务层处理成功,结果: {result}")
|
||||
return success_response(
|
||||
data=result,
|
||||
message="添加成功",
|
||||
code=201
|
||||
)
|
||||
return success_response(data=result, message="添加成功", code=201)
|
||||
except Exception as service_error:
|
||||
print(f"[ERROR] 服务层错误详情: {str(service_error)}")
|
||||
|
||||
|
||||
traceback.print_exc()
|
||||
return error_response(str(service_error), code=500)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] 路由层错误详情: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return error_response(str(e), code=500)
|
||||
|
||||
@knowledgebase_bp.route('/documents/<string:doc_id>', methods=['DELETE', 'OPTIONS'])
|
||||
|
||||
@knowledgebase_bp.route("/documents/<string:doc_id>", methods=["DELETE", "OPTIONS"])
|
||||
def delete_document(doc_id):
|
||||
"""删除文档"""
|
||||
# 处理 OPTIONS 预检请求
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
# 添加 CORS 相关头
|
||||
response.headers.add('Access-Control-Allow-Methods', 'DELETE')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "DELETE")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
|
||||
try:
|
||||
KnowledgebaseService.delete_document(doc_id)
|
||||
return success_response(message="删除成功")
|
||||
except Exception as e:
|
||||
return error_response(str(e))
|
||||
|
||||
@knowledgebase_bp.route('/documents/<doc_id>/parse', methods=['POST'])
|
||||
|
||||
@knowledgebase_bp.route("/documents/<doc_id>/parse", methods=["POST"])
|
||||
def parse_document(doc_id):
|
||||
"""开始解析文档"""
|
||||
# 处理 OPTIONS 预检请求
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
# 添加 CORS 相关头
|
||||
response.headers.add('Access-Control-Allow-Methods', 'POST')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "POST")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
|
||||
try:
|
||||
result = KnowledgebaseService.async_parse_document(doc_id)
|
||||
return success_response(data=result)
|
||||
except Exception as e:
|
||||
return error_response(str(e), code=500)
|
||||
|
||||
@knowledgebase_bp.route('/documents/<doc_id>/parse/progress', methods=['GET'])
|
||||
|
||||
@knowledgebase_bp.route("/documents/<doc_id>/parse/progress", methods=["GET"])
|
||||
def get_parse_progress(doc_id):
|
||||
"""获取文档解析进度"""
|
||||
# 处理 OPTIONS 预检请求
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
# 添加 CORS 相关头
|
||||
response.headers.add('Access-Control-Allow-Methods', 'GET')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "GET")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
|
||||
try:
|
||||
result = KnowledgebaseService.get_document_parse_progress(doc_id)
|
||||
if isinstance(result, dict) and 'error' in result:
|
||||
return error_response(result['error'], code=404)
|
||||
if isinstance(result, dict) and "error" in result:
|
||||
return error_response(result["error"], code=404)
|
||||
return success_response(data=result)
|
||||
except Exception as e:
|
||||
print(f"获取解析进度失败: {str(e)}")
|
||||
return error_response("解析进行中,请稍后重试", code=202)
|
||||
|
||||
|
||||
# 获取系统 Embedding 配置路由
|
||||
@knowledgebase_bp.route('/system_embedding_config', methods=['GET'])
|
||||
@knowledgebase_bp.route("/system_embedding_config", methods=["GET"])
|
||||
def get_system_embedding_config_route():
|
||||
"""获取系统级 Embedding 配置的API端点"""
|
||||
try:
|
||||
|
@ -209,69 +207,68 @@ def get_system_embedding_config_route():
|
|||
return success_response(data=config_data)
|
||||
except Exception as e:
|
||||
print(f"获取系统 Embedding 配置失败: {str(e)}")
|
||||
return error_response(message=f"获取配置失败: {str(e)}", code=500) # 返回通用错误信息
|
||||
return error_response(message=f"获取配置失败: {str(e)}", code=500) # 返回通用错误信息
|
||||
|
||||
|
||||
# 设置系统 Embedding 配置路由
|
||||
@knowledgebase_bp.route('/system_embedding_config', methods=['POST'])
|
||||
@knowledgebase_bp.route("/system_embedding_config", methods=["POST"])
|
||||
def set_system_embedding_config_route():
|
||||
"""设置系统级 Embedding 配置的API端点"""
|
||||
try:
|
||||
data = request.json
|
||||
if not data:
|
||||
return error_response('请求数据不能为空', code=400)
|
||||
return error_response("请求数据不能为空", code=400)
|
||||
|
||||
llm_name = data.get('llm_name', '').strip()
|
||||
api_base = data.get('api_base', '').strip()
|
||||
api_key = data.get('api_key', '').strip() # 允许空
|
||||
llm_name = data.get("llm_name", "").strip()
|
||||
api_base = data.get("api_base", "").strip()
|
||||
api_key = data.get("api_key", "").strip() # 允许空
|
||||
|
||||
if not llm_name or not api_base:
|
||||
return error_response('模型名称和 API 地址不能为空', code=400)
|
||||
return error_response("模型名称和 API 地址不能为空", code=400)
|
||||
|
||||
# 调用服务层进行处理(包括连接测试和数据库操作)
|
||||
success, message = KnowledgebaseService.set_system_embedding_config(
|
||||
llm_name=llm_name,
|
||||
api_base=api_base,
|
||||
api_key=api_key
|
||||
)
|
||||
success, message = KnowledgebaseService.set_system_embedding_config(llm_name=llm_name, api_base=api_base, api_key=api_key)
|
||||
|
||||
if success:
|
||||
return success_response(message=message)
|
||||
else:
|
||||
# 如果服务层返回失败(例如连接测试失败或数据库错误),将消息返回给前端
|
||||
return error_response(message=message, code=400) # 使用 400 表示操作失败
|
||||
return error_response(message=message, code=400) # 使用 400 表示操作失败
|
||||
|
||||
except Exception as e:
|
||||
# 捕获路由层或未预料的服务层异常
|
||||
print(f"设置系统 Embedding 配置失败: {str(e)}")
|
||||
return error_response(message=f"设置配置时发生内部错误: {str(e)}", code=500)
|
||||
|
||||
@knowledgebase_bp.route('/documents/<doc_id>/parse', methods=['POST'])
|
||||
def parse_document_async(doc_id): # 函数名改为 async 以区分
|
||||
|
||||
@knowledgebase_bp.route("/documents/<doc_id>/parse", methods=["POST"])
|
||||
def parse_document_async(doc_id): # 函数名改为 async 以区分
|
||||
"""开始异步解析单个文档"""
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
response.headers.add('Access-Control-Allow-Methods', 'POST')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "POST")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
try:
|
||||
result = KnowledgebaseService.parse_document(doc_id) # 调用同步版本
|
||||
result = KnowledgebaseService.parse_document(doc_id) # 调用同步版本
|
||||
if result.get("success"):
|
||||
return success_response(data={"message": f"文档 {doc_id} 同步解析完成。", "details": result})
|
||||
return success_response(data={"message": f"文档 {doc_id} 同步解析完成。", "details": result})
|
||||
else:
|
||||
return error_response(result.get("message", "解析失败"), code=500)
|
||||
return error_response(result.get("message", "解析失败"), code=500)
|
||||
|
||||
except Exception as e:
|
||||
return error_response(str(e), code=500)
|
||||
|
||||
|
||||
# 启动顺序批量解析路由
|
||||
@knowledgebase_bp.route('/<string:kb_id>/batch_parse_sequential/start', methods=['POST'])
|
||||
@knowledgebase_bp.route("/<string:kb_id>/batch_parse_sequential/start", methods=["POST"])
|
||||
def start_sequential_batch_parse_route(kb_id):
|
||||
"""异步启动知识库的顺序批量解析任务"""
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
response.headers.add('Access-Control-Allow-Methods', 'POST')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "POST")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
try:
|
||||
|
@ -286,14 +283,15 @@ def start_sequential_batch_parse_route(kb_id):
|
|||
traceback.print_exc()
|
||||
return error_response(f"启动顺序批量解析失败: {str(e)}", code=500)
|
||||
|
||||
|
||||
# 获取顺序批量解析进度路由
|
||||
@knowledgebase_bp.route('/<string:kb_id>/batch_parse_sequential/progress', methods=['GET'])
|
||||
@knowledgebase_bp.route("/<string:kb_id>/batch_parse_sequential/progress", methods=["GET"])
|
||||
def get_sequential_batch_parse_progress_route(kb_id):
|
||||
"""获取知识库的顺序批量解析任务进度"""
|
||||
if request.method == 'OPTIONS':
|
||||
if request.method == "OPTIONS":
|
||||
response = success_response({})
|
||||
response.headers.add('Access-Control-Allow-Methods', 'GET')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
|
||||
response.headers.add("Access-Control-Allow-Methods", "GET")
|
||||
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
||||
return response
|
||||
|
||||
try:
|
||||
|
@ -303,4 +301,4 @@ def get_sequential_batch_parse_progress_route(kb_id):
|
|||
except Exception as e:
|
||||
print(f"获取顺序批量解析进度路由处理失败 (KB ID: {kb_id}): {str(e)}")
|
||||
traceback.print_exc()
|
||||
return error_response(f"获取进度失败: {str(e)}", code=500)
|
||||
return error_response(f"获取进度失败: {str(e)}", code=500)
|
||||
|
|
|
@ -8,7 +8,6 @@ import shutil
|
|||
import tempfile
|
||||
import time
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
|
@ -61,7 +60,7 @@ def perform_parse(doc_id, doc_info, file_info, embedding_config, kb_info):
|
|||
if embedding_model_name == "netease-youdao/bce-embedding-base_v1":
|
||||
embedding_model_name = "BAAI/bge-m3"
|
||||
|
||||
embedding_api_base = embedding_config.get("api_base") if embedding_config and embedding_config.get("api_base") else "http://localhost:8000" # 默认基础 URL
|
||||
embedding_api_base = embedding_config.get("api_base") if embedding_config and embedding_config.get("api_base") else "http://localhost:11434" # 默认基础 URL
|
||||
|
||||
# 如果 API 基础地址为空字符串,设置为硅基流动的 API 地址
|
||||
if embedding_api_base == "":
|
||||
|
|
|
@ -105,7 +105,8 @@ class KnowledgebaseService:
|
|||
k.description,
|
||||
k.create_date,
|
||||
k.update_date,
|
||||
k.doc_num
|
||||
k.doc_num,
|
||||
k.avatar
|
||||
FROM knowledgebase k
|
||||
WHERE k.id = %s
|
||||
"""
|
||||
|
@ -334,6 +335,13 @@ class KnowledgebaseService:
|
|||
update_fields.append("permission = %s")
|
||||
params.append(data["permission"])
|
||||
|
||||
if "avatar" in data and data["avatar"]:
|
||||
avatar_base64 = data["avatar"]
|
||||
# 拼接上前缀
|
||||
full_avatar_url = f"data:image/png;base64,{avatar_base64}"
|
||||
update_fields.append("avatar = %s")
|
||||
params.append(full_avatar_url)
|
||||
|
||||
# 更新时间
|
||||
current_time = datetime.now()
|
||||
update_date = current_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
import { request } from "@/http/axios"
|
||||
|
||||
// 定义修改数据库界面中显示的信息
|
||||
interface KbDetailData {
|
||||
id: string
|
||||
name: string
|
||||
permission: string
|
||||
avatar?: string
|
||||
}
|
||||
|
||||
interface ApiDetailResponse {
|
||||
data: KbDetailData
|
||||
code: number
|
||||
message: string
|
||||
}
|
||||
|
||||
// 获取知识库列表
|
||||
export function getKnowledgeBaseListApi(params: {
|
||||
currentPage: number
|
||||
|
@ -16,7 +30,7 @@ export function getKnowledgeBaseListApi(params: {
|
|||
}
|
||||
|
||||
// 获取知识库详情
|
||||
export function getKnowledgeBaseDetailApi(id: string) {
|
||||
export function getKbDetailApi(id: string): Promise<ApiDetailResponse> {
|
||||
return request({
|
||||
url: `/api/v1/knowledgebases/${id}`,
|
||||
method: "get"
|
||||
|
@ -44,6 +58,7 @@ export function updateKnowledgeBaseApi(id: string, data: {
|
|||
description?: string
|
||||
language?: string
|
||||
permission?: string
|
||||
avatar?: string
|
||||
}) {
|
||||
return request({
|
||||
url: `/api/v1/knowledgebases/${id}`,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import type { SequentialBatchTaskProgress } from "@@/apis/kbs/document"
|
||||
import type { FormInstance } from "element-plus"
|
||||
import type { FormInstance, UploadFile, UploadProps } from "element-plus"
|
||||
import DocumentParseProgress from "@/layouts/components/DocumentParseProgress/index.vue"
|
||||
import {
|
||||
deleteDocumentApi,
|
||||
|
@ -14,9 +14,11 @@ import {
|
|||
batchDeleteKnowledgeBaseApi,
|
||||
createKnowledgeBaseApi,
|
||||
deleteKnowledgeBaseApi,
|
||||
getKbDetailApi,
|
||||
getKnowledgeBaseListApi,
|
||||
getSystemEmbeddingConfigApi,
|
||||
setSystemEmbeddingConfigApi
|
||||
setSystemEmbeddingConfigApi,
|
||||
updateKnowledgeBaseApi
|
||||
} from "@@/apis/kbs/knowledgebase"
|
||||
import { getTableDataApi } from "@@/apis/tables"
|
||||
import { usePagination } from "@@/composables/usePagination"
|
||||
|
@ -157,39 +159,91 @@ const editDialogVisible = ref(false)
|
|||
const editForm = reactive({
|
||||
id: "",
|
||||
name: "",
|
||||
permission: "me"
|
||||
permission: "me",
|
||||
avatar: ""
|
||||
})
|
||||
const editLoading = ref(false)
|
||||
|
||||
// 处理修改知识库
|
||||
function handleEdit(row: KnowledgeBaseData) {
|
||||
// // 处理修改知识库
|
||||
// function handleEdit(row: KnowledgeBaseData) {
|
||||
// editDialogVisible.value = true
|
||||
// editForm.id = row.id
|
||||
// editForm.name = row.name
|
||||
// editForm.permission = row.permission
|
||||
// }
|
||||
|
||||
// 用于获取完整数据
|
||||
async function handleEdit(row: KnowledgeBaseData) {
|
||||
editDialogVisible.value = true
|
||||
editForm.id = row.id
|
||||
editForm.name = row.name
|
||||
editForm.permission = row.permission
|
||||
editLoading.value = true
|
||||
try {
|
||||
const { data } = await getKbDetailApi(row.id)
|
||||
editForm.id = data.id
|
||||
editForm.name = data.name
|
||||
editForm.permission = row.permission
|
||||
// 如果后端返回的base64不带前缀,需要手动加上
|
||||
if (data.avatar && !data.avatar.startsWith("data:image")) {
|
||||
editForm.avatar = `data:image/jpeg;base64,${data.avatar}`
|
||||
} else {
|
||||
editForm.avatar = data.avatar || ""
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(`获取知识库详情失败: ${error?.message || "未知错误"}`)
|
||||
editDialogVisible.value = false // 如果失败,则关闭对话框
|
||||
} finally {
|
||||
editLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 提交修改
|
||||
function submitEdit() {
|
||||
editLoading.value = true
|
||||
// 调用修改知识库API
|
||||
axios.put(`/api/v1/knowledgebases/${editForm.id}`, {
|
||||
|
||||
// 准备要提交的数据
|
||||
const payload: { permission: string, avatar?: string } = {
|
||||
permission: editForm.permission
|
||||
})
|
||||
}
|
||||
|
||||
// 如果有新的头像数据,提取纯 Base64 部分
|
||||
if (editForm.avatar && editForm.avatar.startsWith("data:image")) {
|
||||
payload.avatar = editForm.avatar.split(",")[1]
|
||||
}
|
||||
|
||||
// 使用导入的 API 函数
|
||||
updateKnowledgeBaseApi(editForm.id, payload)
|
||||
.then(() => {
|
||||
ElMessage.success("知识库权限修改成功")
|
||||
ElMessage.success("知识库信息修改成功")
|
||||
editDialogVisible.value = false
|
||||
// 刷新知识库列表
|
||||
getTableData()
|
||||
getTableData() // 刷新知识库列表
|
||||
})
|
||||
.catch((error) => {
|
||||
ElMessage.error(`修改知识库权限失败: ${error?.message || "未知错误"}`)
|
||||
.catch((error: any) => {
|
||||
ElMessage.error(`修改知识库失败: ${error?.message || "未知错误"}`)
|
||||
})
|
||||
.finally(() => {
|
||||
editLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const handleAvatarChange: UploadProps["onChange"] = (uploadFile: UploadFile) => {
|
||||
if (!uploadFile.raw) return
|
||||
if (!uploadFile.raw.type.includes("image")) {
|
||||
ElMessage.error("请上传图片格式文件!")
|
||||
return false
|
||||
}
|
||||
// 上传文件大小限制
|
||||
const isLt2M = uploadFile.raw.size / 1024 / 1024 < 2
|
||||
if (!isLt2M) {
|
||||
ElMessage.error("上传头像图片大小不能超过 2MB!")
|
||||
return false
|
||||
}
|
||||
|
||||
const reader = new FileReader()
|
||||
reader.readAsDataURL(uploadFile.raw)
|
||||
reader.onload = () => {
|
||||
editForm.avatar = reader.result as string
|
||||
}
|
||||
}
|
||||
|
||||
// 存储多选的表格数据
|
||||
const multipleSelection = ref<KnowledgeBaseData[]>([])
|
||||
|
||||
|
@ -1404,6 +1458,21 @@ const userLoading = ref(false)
|
|||
<el-form-item label="知识库名称">
|
||||
<span>{{ editForm.name }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="知识库头像">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
action="#"
|
||||
:show-file-list="false"
|
||||
:on-change="handleAvatarChange"
|
||||
:auto-upload="false"
|
||||
accept="image/png, image/jpeg, image/gif, image/webp"
|
||||
>
|
||||
<img v-if="editForm.avatar" :src="editForm.avatar" class="avatar" alt="avatar">
|
||||
<el-icon v-else class="avatar-uploader-icon">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限设置">
|
||||
<el-select v-model="editForm.permission" placeholder="请选择权限">
|
||||
<el-option label="个人" value="me" />
|
||||
|
@ -1697,4 +1766,33 @@ const userLoading = ref(false)
|
|||
vertical-align: middle;
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 50%; /* 圆形 */
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
text-align: center;
|
||||
line-height: 120px; /* 垂直居中图标 */
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: block;
|
||||
object-fit: cover; /* 保证图片不变形 */
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue