6
This commit is contained in:
@@ -41,6 +41,7 @@ class DocumentService:
|
||||
kb_id: str,
|
||||
filename: str,
|
||||
content: bytes,
|
||||
category_id: str | None = None,
|
||||
) -> Document:
|
||||
"""上传文档。
|
||||
|
||||
@@ -111,6 +112,7 @@ class DocumentService:
|
||||
doc_token_hash=doc_token_hash,
|
||||
doc_token_encrypted=doc_token_encrypted,
|
||||
doc_token_hint=doc_token_hint,
|
||||
category_id=category_id,
|
||||
)
|
||||
|
||||
# 更新存储路径中的 document_id
|
||||
@@ -200,3 +202,87 @@ class DocumentService:
|
||||
|
||||
processor = LocalDocumentProcessor(self._session)
|
||||
processor.process(doc.id)
|
||||
|
||||
def create_text(
|
||||
self,
|
||||
user: User,
|
||||
kb_id: str,
|
||||
title: str,
|
||||
content: str,
|
||||
content_format: str = "markdown",
|
||||
category_id: str | None = None,
|
||||
) -> Document:
|
||||
"""创建文本内容文档(无需上传文件)。"""
|
||||
# 校验 KB 归属
|
||||
kb = self._kb_repo.get_by_id(kb_id)
|
||||
if kb is None or kb.user_id != user.id or kb.status == "DELETED":
|
||||
raise NotFoundError("知识库不存在。")
|
||||
|
||||
# 生成文档 token
|
||||
doc_token = generate_token()
|
||||
doc_token_hash = hash_token(doc_token)
|
||||
doc_token_encrypted = encrypt_token(doc_token)
|
||||
doc_token_hint = doc_token[-8:] if len(doc_token) >= 8 else doc_token
|
||||
|
||||
# 计算内容大小
|
||||
content_size = len(content.encode("utf-8"))
|
||||
|
||||
# 配额检查
|
||||
self._check_quota(user, content_size)
|
||||
|
||||
# 从内容提取摘要和关键词
|
||||
summary = self._extract_summary(content)
|
||||
keywords = self._extract_keywords(content)
|
||||
|
||||
# 创建文档记录
|
||||
doc = Document(
|
||||
knowledge_base_id=kb_id,
|
||||
user_id=user.id,
|
||||
category_id=category_id,
|
||||
original_filename=title,
|
||||
storage_path=None, # 文本内容不存储文件
|
||||
markdown_path=None,
|
||||
content=content,
|
||||
content_format=content_format,
|
||||
file_size=content_size,
|
||||
mime_type="text/markdown" if content_format == "markdown" else "text/plain",
|
||||
file_ext=".md" if content_format == "markdown" else ".txt",
|
||||
sha256=None,
|
||||
doc_token_hash=doc_token_hash,
|
||||
doc_token_encrypted=doc_token_encrypted,
|
||||
doc_token_hint=doc_token_hint,
|
||||
title=title,
|
||||
content_summary=summary,
|
||||
keywords=keywords,
|
||||
status="READY", # 文本内容直接就绪
|
||||
)
|
||||
self._session.add(doc)
|
||||
|
||||
# 扣减配额
|
||||
self._deduct_quota(user, content_size)
|
||||
|
||||
self._session.commit()
|
||||
return doc
|
||||
|
||||
def _extract_summary(self, content: str, max_len: int = 200) -> str:
|
||||
"""提取摘要。"""
|
||||
import re
|
||||
|
||||
text = re.sub(r"[#*_`\[\]()>]", "", content)
|
||||
text = re.sub(r"\s+", " ", text).strip()
|
||||
if len(text) <= max_len:
|
||||
return text
|
||||
return text[:max_len] + "..."
|
||||
|
||||
def _extract_keywords(self, content: str, top_k: int = 10) -> str:
|
||||
"""提取关键词。"""
|
||||
try:
|
||||
import jieba.analyse
|
||||
import re
|
||||
|
||||
text = re.sub(r"[#*_`\[\]()>]", "", content)
|
||||
text = re.sub(r"\s+", " ", text).strip()
|
||||
keywords = jieba.analyse.extract_tags(text, topK=top_k)
|
||||
return ",".join(keywords)
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user