Pr@main@fix bugs (#41)

* fix: 修复提示问题

* fix: 上传文档限制

* feat: 问题管理

* fix: 修改分段正则,优化分段逻辑

* feat: 问题管理

* fix: word分段支持表格数据

* fix: 问题批量插入去重

* fix: 修复文档问题

* feat: 文档分页优化

* fix: 优化关联问题

* fix: 嵌入样式
This commit is contained in:
shaohuzhang1 2024-04-10 14:16:56 +08:00 committed by GitHub
parent e9d85b007c
commit fb7abb432f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 203 additions and 66 deletions

View File

@ -19,7 +19,7 @@ const guideHtml=`
</div>
`
const chatButtonHtml=
`<div class="maxkb-chat-button" ><svg width="48" height="56" viewBox="0 0 48 56" fill="none" xmlns="http://www.w3.org/2000/svg">
`<div class="maxkb-chat-button" ><svg style="vertical-align: middle;overflow: hidden;" width="48" height="56" viewBox="0 0 48 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_349_49711)">
<path d="M8 24C8 12.9543 16.9543 4 28 4H48V44H28C16.9543 44 8 35.0457 8 24Z" fill="url(#paint0_linear_349_49711)"/>
</g>
@ -164,7 +164,7 @@ function initMaxkbStyle(root){
}
#maxkb .maxkb-mask .maxkb-content {
width: 45px;
height: 50px;
height: 48px;
box-shadow: 1px 1px 1px 2000px rgba(0,0,0,.6);
border-radius: 50% 0 0 50%;
position: absolute;

View File

@ -11,14 +11,18 @@ import re
from typing import List
from docx import Document
from docx.table import Table
from docx.text.paragraph import Paragraph
from common.handle.base_split_handle import BaseSplitHandle
from common.util.split_model import SplitModel
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'), re.compile('(?<!#)## (?!#).*'),
re.compile("(?<!#)### (?!#).*"),
re.compile("(?<!#)#### (?!#).*"), re.compile("(?<!#)##### (?!#).*"),
re.compile("(?<!#)###### (?!#).*"), re.compile("(?<!\n)\n\n+")]
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'),
re.compile('(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'),
re.compile("(?<=\\n)(?<!#)### (?!#).*|(?<=^)(?<!#)### (?!#).*"),
re.compile("(?<=\\n)(?<!#)#### (?!#).*|(?<=^)(?<!#)#### (?!#).*"),
re.compile("(?<=\\n)(?<!#)##### (?!#).*|(?<=^)(?<!#)##### (?!#).*"),
re.compile("(?<=\\n)(?<!#)###### (?!#).*|(?<=^)(?<!#)###### (?!#).*")]
class DocSplitHandle(BaseSplitHandle):
@ -32,9 +36,31 @@ class DocSplitHandle(BaseSplitHandle):
return paragraph.text
return paragraph.text
@staticmethod
def table_to_md(table):
rows = table.rows
# 创建 Markdown 格式的表格
md_table = '| ' + ' | '.join([cell.text.replace("\n", '</br>') for cell in rows[0].cells]) + ' |\n'
md_table += '| ' + ' | '.join(['---' for i in range(len(rows[0].cells))]) + ' |\n'
for row in rows[1:]:
md_table += '| ' + ' | '.join([cell.text.replace("\n", '</br>') for cell in row.cells]) + ' |\n'
return md_table
def to_md(self, doc):
ps = doc.paragraphs
return "\n".join([self.paragraph_to_md(para) for para in ps])
elements = []
for element in doc.element.body:
if element.tag.endswith('tbl'):
# 处理表格
table = Table(element, doc)
elements.append(table)
elif element.tag.endswith('p'):
# 处理段落
paragraph = Paragraph(element, doc)
elements.append(paragraph)
return "\n".join(
[self.paragraph_to_md(element) if isinstance(element, Paragraph) else self.table_to_md(element) for element
in elements])
def handle(self, file, pattern_list: List, with_filter: bool, limit: int, get_buffer):
try:

View File

@ -14,10 +14,13 @@ import fitz
from common.handle.base_split_handle import BaseSplitHandle
from common.util.split_model import SplitModel
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'), re.compile('(?<!#)## (?!#).*'),
re.compile("(?<!#)### (?!#).*"),
re.compile("(?<!#)#### (?!#).*"), re.compile("(?<!#)##### (?!#).*"),
re.compile("(?<!#)###### (?!#).*"), re.compile("(?<!\n)\n\n+")]
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'),
re.compile('(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'),
re.compile("(?<=\\n)(?<!#)### (?!#).*|(?<=^)(?<!#)### (?!#).*"),
re.compile("(?<=\\n)(?<!#)#### (?!#).*|(?<=^)(?<!#)#### (?!#).*"),
re.compile("(?<=\\n)(?<!#)##### (?!#).*|(?<=^)(?<!#)##### (?!#).*"),
re.compile("(?<=\\n)(?<!#)###### (?!#).*|(?<=^)(?<!#)###### (?!#).*"),
re.compile("(?<!\n)\n\n+")]
def number_to_text(pdf_document, page_number):

View File

@ -14,10 +14,12 @@ from charset_normalizer import detect
from common.handle.base_split_handle import BaseSplitHandle
from common.util.split_model import SplitModel
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'), re.compile('(?<!#)## (?!#).*'),
re.compile("(?<!#)### (?!#).*"),
re.compile("(?<!#)#### (?!#).*"), re.compile("(?<!#)##### (?!#).*"),
re.compile("(?<!#)###### (?!#).*"), re.compile("(?<!\n)\n\n+")]
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'),
re.compile('(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'),
re.compile("(?<=\\n)(?<!#)### (?!#).*|(?<=^)(?<!#)### (?!#).*"),
re.compile("(?<=\\n)(?<!#)#### (?!#).*|(?<=^)(?<!#)#### (?!#).*"),
re.compile("(?<=\\n)(?<!#)##### (?!#).*|(?<=^)(?<!#)##### (?!#).*"),
re.compile("(?<=\\n)(?<!#)###### (?!#).*|(?<=^)(?<!#)###### (?!#).*")]
class TextSplitHandle(BaseSplitHandle):

View File

@ -295,7 +295,7 @@ class SplitModel:
"""
if len(self.content_level_pattern) == index:
return
level_content_list = parse_title_level(text, self.content_level_pattern, index)
level_content_list = parse_title_level(text, self.content_level_pattern, 0)
cursor = 0
for i in range(len(level_content_list)):
block, cursor = get_level_block(text, level_content_list, i, cursor)
@ -313,10 +313,15 @@ class SplitModel:
if end_index == 0:
return level_content_list
other_content = text[0:end_index]
if len(other_content.strip()) > 0:
level_content_list = [*level_content_list, *list(
map(lambda row: to_tree_obj(row, 'block'),
post_handler_paragraph(other_content, with_filter=self.with_filter, limit=self.limit)))]
children = self.parse_to_tree(text=other_content,
index=index)
if len(children) > 0:
level_content_list = [*level_content_list, *children]
else:
if len(other_content.strip()) > 0:
level_content_list = [*level_content_list, *list(
map(lambda row: to_tree_obj(row, 'block'),
post_handler_paragraph(other_content, with_filter=self.with_filter, limit=self.limit)))]
else:
if len(text.strip()) > 0:
level_content_list = [*level_content_list, *list(
@ -330,15 +335,16 @@ class SplitModel:
:param text: 文本数据
:return: 解析后数据 {content:段落数据,keywords:[段落关键词],parent_chain:['段落父级链路']}
"""
result_tree = self.parse_to_tree(text.replace('\r', '\n'), 0)
text = text.replace('\r', '\n')
result_tree = self.parse_to_tree(text, 0)
result = result_tree_to_paragraph(result_tree, [], [])
# 过滤段落内容不为空字符串的数据
result = [item for item in result if 'content' in item and len(item.get('content').strip()) > 0]
return [self.post_reset_paragraph(item) for item in result]
return [item for item in [self.post_reset_paragraph(row) for row in result] if
'content' in item and len(item.get('content').strip()) > 0]
def post_reset_paragraph(self, paragraph: Dict):
result = self.filter_title_special_characters(paragraph)
result = self.sub_title(result)
result = self.content_is_null(result)
return result
@staticmethod
@ -349,6 +355,15 @@ class SplitModel:
return {**paragraph, 'title': title[0:255], 'content': title[255:len(title)] + paragraph.get('content')}
return paragraph
@staticmethod
def content_is_null(paragraph: Dict):
if 'title' in paragraph:
title = paragraph.get('title')
content = paragraph.get('content')
if (content is None or len(content.strip()) == 0) and (title is not None and len(title) > 0):
return {'title': '', 'content': title}
return paragraph
@staticmethod
def filter_title_special_characters(paragraph: Dict):
title = paragraph.get('title') if 'title' in paragraph else ''
@ -361,9 +376,12 @@ class SplitModel:
title_special_characters_list = ['#', '\n', '\r', '\\s']
default_split_pattern = {
'md': [re.compile('(?<=^)# .*|(?<=\\n)# .*'), re.compile('(?<!#)## (?!#).*'), re.compile("(?<!#)### (?!#).*"),
re.compile("(?<!#)#### (?!#).*"), re.compile("(?<!#)##### (?!#).*"),
re.compile("(?<!#)###### (?!#).*"), re.compile("(?<!\n)\n\n+")],
'md': [re.compile('(?<=^)# .*|(?<=\\n)# .*'),
re.compile('(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'),
re.compile("(?<=\\n)(?<!#)### (?!#).*|(?<=^)(?<!#)### (?!#).*"),
re.compile("(?<=\\n)(?<!#)#### (?!#).*|(?<=^)(?<!#)#### (?!#).*"),
re.compile("(?<=\\n)(?<!#)##### (?!#).*|(?<=^)(?<!#)##### (?!#).*"),
re.compile("(?<=\\n)(?<!#)###### (?!#).*|(?<=^)(?<!#)###### (?!#).*")],
'default': [re.compile("(?<!\n)\n\n+")]
}

View File

@ -506,10 +506,12 @@ class DocumentSerializers(ApiMixin, serializers.Serializer):
class SplitPattern(ApiMixin, serializers.Serializer):
@staticmethod
def list():
return [{'key': "#", 'value': '(?<=^)# .*|(?<=\\n)# .*'}, {'key': '##', 'value': '(?<!#)## (?!#).*'},
{'key': '###', 'value': "(?<!#)### (?!#).*"}, {'key': '####', 'value': "(?<!#)#### (?!#).*"},
{'key': '#####', 'value': "(?<!#)##### (?!#).*"},
{'key': '######', 'value': "(?<!#)###### (?!#).*"},
return [{'key': "#", 'value': '(?<=^)# .*|(?<=\\n)# .*'},
{'key': '##', 'value': '(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'},
{'key': '###', 'value': "(?<=\\n)(?<!#)### (?!#).*|(?<=^)(?<!#)### (?!#).*"},
{'key': '####', 'value': "(?<=\\n)(?<!#)#### (?!#).*|(?<=^)(?<!#)#### (?!#).*"},
{'key': '#####', 'value': "(?<=\\n)(?<!#)##### (?!#).*|(?<=^)(?<!#)##### (?!#).*"},
{'key': '######', 'value': "(?<=\\n)(?<!#)###### (?!#).*|(?<=^)(?<!#)###### (?!#).*"},
{'key': '-', 'value': '(?<! )- .*'},
{'key': '空格', 'value': '(?<!\\s)\\s(?!\\s)'},
{'key': '分号', 'value': '(?<!)(?!)'}, {'key': '逗号', 'value': '(?<!)(?!)'},

View File

@ -60,13 +60,14 @@ class ProblemSerializers(ApiMixin, serializers.Serializer):
if with_valid:
self.is_valid(raise_exception=True)
problem_list = self.data.get('problem_list')
problem_list = list(set(problem_list))
dataset_id = self.data.get('dataset_id')
exists_problem_content_list = [problem.content for problem in
QuerySet(Problem).filter(dataset_id=dataset_id,
content__in=problem_list)]
problem_instance_list = [Problem(id=uuid.uuid1(), dataset_id=dataset_id, content=problem_content) for
problem_content in
self.data.get('problem_list') if
problem_list if
(not exists_problem_content_list.__contains__(problem_content) if
len(exists_problem_content_list) > 0 else True)]
@ -122,7 +123,7 @@ class ProblemSerializers(ApiMixin, serializers.Serializer):
self.is_valid(raise_exception=True)
problem_paragraph_mapping = QuerySet(ProblemParagraphMapping).filter(dataset_id=self.data.get("dataset_id"),
problem_id=self.data.get("problem_id"))
if problem_paragraph_mapping is None or len(problem_paragraph_mapping)==0:
if problem_paragraph_mapping is None or len(problem_paragraph_mapping) == 0:
return []
return native_search(
QuerySet(Paragraph).filter(id__in=[row.paragraph_id for row in problem_paragraph_mapping]),

View File

@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.7929C14.9255 1.5 15.0527 1.55268 15.1464 1.64645L19.8536 6.35355C19.9473 6.44732 20 6.5745 20 6.70711V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#34C724"/>
<path d="M9.27052 14.1558H10.1825C10.1545 13.9078 10.0865 13.6878 9.97852 13.4958C9.87052 13.3038 9.73252 13.1438 9.56452 13.0158C9.40052 12.8838 9.21252 12.7838 9.00052 12.7158C8.79252 12.6478 8.57052 12.6138 8.33452 12.6138C8.00652 12.6138 7.71052 12.6718 7.44652 12.7878C7.18652 12.9038 6.96652 13.0638 6.78652 13.2678C6.60652 13.4718 6.46852 13.7118 6.37252 13.9878C6.27652 14.2598 6.22852 14.5558 6.22852 14.8758C6.22852 15.1878 6.27652 15.4798 6.37252 15.7518C6.46852 16.0198 6.60652 16.2538 6.78652 16.4538C6.96652 16.6538 7.18652 16.8118 7.44652 16.9278C7.71052 17.0398 8.00652 17.0958 8.33452 17.0958C8.59852 17.0958 8.84052 17.0558 9.06052 16.9758C9.28052 16.8958 9.47252 16.7798 9.63652 16.6278C9.80052 16.4758 9.93252 16.2918 10.0325 16.0758C10.1325 15.8598 10.1945 15.6178 10.2185 15.3498H9.30652C9.27052 15.6378 9.17052 15.8698 9.00652 16.0458C8.84652 16.2218 8.62252 16.3098 8.33452 16.3098C8.12252 16.3098 7.94252 16.2698 7.79452 16.1898C7.64652 16.1058 7.52652 15.9958 7.43452 15.8598C7.34252 15.7238 7.27452 15.5718 7.23052 15.4038C7.19052 15.2318 7.17052 15.0558 7.17052 14.8758C7.17052 14.6878 7.19052 14.5058 7.23052 14.3298C7.27452 14.1538 7.34252 13.9978 7.43452 13.8618C7.52652 13.7218 7.64652 13.6118 7.79452 13.5318C7.94252 13.4478 8.12252 13.4058 8.33452 13.4058C8.45052 13.4058 8.56052 13.4258 8.66452 13.4658C8.77252 13.5018 8.86852 13.5538 8.95252 13.6218C9.03652 13.6898 9.10652 13.7698 9.16252 13.8618C9.21852 13.9498 9.25452 14.0478 9.27052 14.1558Z" fill="white"/>
<path d="M11.5038 15.5778H10.5918C10.5878 15.8418 10.6358 16.0698 10.7358 16.2618C10.8358 16.4538 10.9698 16.6118 11.1378 16.7358C11.3098 16.8598 11.5058 16.9498 11.7258 17.0058C11.9498 17.0658 12.1798 17.0958 12.4158 17.0958C12.7078 17.0958 12.9638 17.0618 13.1838 16.9938C13.4078 16.9258 13.5938 16.8318 13.7418 16.7118C13.8938 16.5878 14.0078 16.4418 14.0838 16.2738C14.1598 16.1058 14.1978 15.9238 14.1978 15.7278C14.1978 15.4878 14.1458 15.2918 14.0418 15.1398C13.9418 14.9838 13.8218 14.8598 13.6818 14.7678C13.5418 14.6758 13.3998 14.6098 13.2558 14.5698C13.1158 14.5258 13.0058 14.4958 12.9258 14.4798C12.6578 14.4118 12.4398 14.3558 12.2718 14.3118C12.1078 14.2678 11.9778 14.2238 11.8818 14.1798C11.7898 14.1358 11.7278 14.0878 11.6958 14.0358C11.6638 13.9838 11.6478 13.9158 11.6478 13.8318C11.6478 13.7398 11.6678 13.6638 11.7078 13.6038C11.7478 13.5438 11.7978 13.4938 11.8578 13.4538C11.9218 13.4138 11.9918 13.3858 12.0678 13.3698C12.1438 13.3538 12.2198 13.3458 12.2958 13.3458C12.4118 13.3458 12.5178 13.3558 12.6138 13.3758C12.7138 13.3958 12.8018 13.4298 12.8778 13.4778C12.9538 13.5258 13.0138 13.5918 13.0578 13.6758C13.1058 13.7598 13.1338 13.8658 13.1418 13.9938H14.0538C14.0538 13.7458 14.0058 13.5358 13.9098 13.3638C13.8178 13.1878 13.6918 13.0438 13.5318 12.9318C13.3718 12.8198 13.1878 12.7398 12.9798 12.6918C12.7758 12.6398 12.5618 12.6138 12.3378 12.6138C12.1458 12.6138 11.9538 12.6398 11.7618 12.6918C11.5698 12.7438 11.3978 12.8238 11.2458 12.9318C11.0938 13.0398 10.9698 13.1758 10.8738 13.3398C10.7818 13.4998 10.7358 13.6898 10.7358 13.9098C10.7358 14.1058 10.7718 14.2738 10.8438 14.4138C10.9198 14.5498 11.0178 14.6638 11.1378 14.7558C11.2578 14.8478 11.3938 14.9238 11.5458 14.9838C11.6978 15.0398 11.8538 15.0878 12.0138 15.1278C12.1698 15.1718 12.3238 15.2118 12.4758 15.2478C12.6278 15.2838 12.7638 15.3258 12.8838 15.3738C13.0038 15.4218 13.0998 15.4818 13.1718 15.5538C13.2478 15.6258 13.2858 15.7198 13.2858 15.8358C13.2858 15.9438 13.2578 16.0338 13.2018 16.1058C13.1458 16.1738 13.0758 16.2278 12.9918 16.2678C12.9078 16.3078 12.8178 16.3358 12.7218 16.3518C12.6258 16.3638 12.5358 16.3698 12.4518 16.3698C12.3278 16.3698 12.2078 16.3558 12.0918 16.3278C11.9758 16.2958 11.8738 16.2498 11.7858 16.1898C11.7018 16.1258 11.6338 16.0438 11.5818 15.9438C11.5298 15.8438 11.5038 15.7218 11.5038 15.5778Z" fill="white"/>
<path d="M16.7503 16.9998L18.1723 12.7158H17.2003L16.2343 15.7278H16.2223L15.2683 12.7158H14.3023L15.6883 16.9998H16.7503Z" fill="white"/>
<path d="M15 1.54492C15.054 1.56949 15.1037 1.6037 15.1464 1.64646L19.8536 6.35357C19.8963 6.39632 19.9305 6.44602 19.9551 6.50001H16C15.4477 6.50001 15 6.0523 15 5.50001V1.54492Z" fill="#2CA91F"/>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.7929C14.9255 1.5 15.0527 1.55268 15.1464 1.64645L19.8536 6.35355C19.9473 6.44732 20 6.5745 20 6.70711V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#3370FF"/>
<path d="M15 1.54492C15.054 1.56949 15.1037 1.6037 15.1464 1.64646L19.8536 6.35357C19.8963 6.39632 19.9305 6.44602 19.9551 6.50001H16C15.4477 6.50001 15 6.0523 15 5.50001V1.54492Z" fill="#2B5FD9"/>
<path d="M15.1218 17.9996L17.4138 9.43164H16.2738L14.5338 16.5596H14.5098L12.6138 9.43164H11.3778L9.45784 16.5596H9.43384L7.75384 9.43164H6.58984L8.78584 17.9996H9.97384L11.9538 10.7996H11.9778L13.9338 17.9996H15.1218Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 777 B

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.7929C14.9255 1.5 15.0527 1.55268 15.1464 1.64645L19.8536 6.35355C19.9473 6.44732 20 6.5745 20 6.70711V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#F54A45"/>
<path d="M15 1.54492C15.054 1.56949 15.1037 1.6037 15.1464 1.64646L19.8536 6.35357C19.8963 6.39632 19.9305 6.44602 19.9551 6.50001H16C15.4477 6.50001 15 6.0523 15 5.50001V1.54492Z" fill="#D03F3B"/>
<path d="M17.6091 15.2316C17.3608 14.9368 16.8517 14.7934 16.0526 14.7934C15.5881 14.7934 15.027 14.8425 14.3839 14.9392C12.6276 13.6551 12.1372 12.2384 12.1372 12.2384C12.1372 12.2384 12.4371 11.4747 12.4562 10.2274C12.4682 9.43896 12.3461 8.9071 12.0307 8.59811C11.908 8.478 11.7023 8.40039 11.5066 8.40039C11.3539 8.40039 11.2109 8.44525 11.0937 8.53102C10.1806 9.19913 11.1775 12.3487 11.2041 12.4326C10.7733 13.4931 10.2305 14.6165 9.6718 15.6037C9.49028 15.9244 9.50797 15.8994 9.35494 16.1602C9.35494 16.1602 7.80983 16.8859 7.06037 17.7773C6.63691 18.281 6.58338 18.621 6.60586 18.8801L6.60643 18.8858C6.6421 19.1909 7.03273 19.4688 7.42598 19.4688C7.44229 19.4688 7.45871 19.4683 7.47478 19.4673C7.87445 19.4426 8.31243 19.1586 8.81374 18.5991C9.14462 18.2297 9.57462 17.5798 10.0924 16.6668C11.5778 16.2442 12.8851 15.9432 13.9807 15.7716C14.7842 16.204 15.9795 16.6936 16.7932 16.6936C17.0661 16.6936 17.2857 16.638 17.4458 16.5282C17.6373 16.397 17.7187 16.2334 17.7692 15.9306C17.8198 15.6278 17.7494 15.3982 17.6091 15.2316ZM15.8737 15.6003C16.5879 15.6003 16.9745 15.7041 17.1732 15.7912C17.2345 15.8181 17.279 15.844 17.3106 15.8657C17.2547 15.9014 17.1446 15.9466 16.9456 15.9466C16.6156 15.9466 16.1826 15.8314 15.6544 15.6034C15.7295 15.6013 15.8027 15.6003 15.8737 15.6003ZM11.6412 9.03253C11.6417 9.03159 11.6422 9.03062 11.6429 9.02961C11.7961 9.11028 11.8676 9.67679 11.8532 10.0053C11.8339 10.4461 11.8293 10.6164 11.752 10.8872C11.5422 10.3226 11.5273 9.30775 11.6412 9.03253ZM11.6972 13.5014C12.0575 14.0864 12.5917 14.7201 13.1065 15.1725C12.1018 15.3848 11.1372 15.651 10.537 15.8581C11.1803 14.7595 11.655 13.6103 11.6972 13.5014ZM7.56217 18.5462C7.64933 18.401 7.88748 18.1197 8.49143 17.5757C8.07746 18.1983 7.77338 18.5373 7.46488 18.7488C7.49042 18.6821 7.52255 18.6122 7.56217 18.5462Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.7929C14.9255 1.5 15.0527 1.55268 15.1464 1.64645L19.8536 6.35355C19.9473 6.44732 20 6.5745 20 6.70711V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#8F959E"/>
<path d="M15 1.54492C15.054 1.56949 15.1037 1.6037 15.1464 1.64646L19.8536 6.35357C19.8963 6.39632 19.9305 6.44602 19.9551 6.50001H16C15.4477 6.50001 15 6.0523 15 5.50001V1.54492Z" fill="#646A73"/>
<path d="M14.288 9.86441C13.7422 9.34739 13.026 9.09082 12.1353 9.09082C11.1347 9.09082 10.3505 9.41162 9.78235 10.065C9.30108 10.6265 9.04179 11.1646 9.00471 12.013C9.00384 12.033 9.00309 12.0697 9.00247 12.1122C9.00043 12.2508 9.11287 12.3635 9.25147 12.3635H9.84253C9.98 12.3635 10.0914 12.2525 10.0936 12.1151C10.0943 12.0737 10.0951 12.038 10.0961 12.0189C10.1251 11.4328 10.278 11.1262 10.5508 10.7851C10.8953 10.3259 11.4006 10.0999 12.0943 10.0999C12.7134 10.0999 13.1776 10.2578 13.4979 10.5782C13.8033 10.8963 13.9625 11.3294 13.9625 11.8726C13.9625 12.2435 13.8281 12.5967 13.5549 12.948C13.4678 13.0568 13.3425 13.1862 12.9388 13.5899C12.3012 14.1474 11.9073 14.601 11.6993 15.0468C11.5282 15.3888 11.441 15.7775 11.441 16.1954V16.4772C11.441 16.6153 11.5529 16.7272 11.691 16.7272H12.2956C12.4336 16.7272 12.5456 16.6153 12.5456 16.4772V16.1954C12.5456 15.8413 12.6327 15.5237 12.8133 15.2141C12.9486 14.9841 13.1223 14.8038 13.4251 14.5389C14.0321 13.9897 14.3689 13.6625 14.5198 13.4705C14.8821 12.9923 15.0671 12.4446 15.0671 11.8454C15.0671 11.0185 14.8075 10.355 14.288 9.86441ZM11.7046 17.8181C11.5666 17.8181 11.4546 17.93 11.4546 18.0681V18.659C11.4546 18.7971 11.5666 18.909 11.7046 18.909H12.2956C12.4336 18.909 12.5456 18.7971 12.5456 18.659V18.0681C12.5456 17.93 12.4336 17.8181 12.2956 17.8181H11.7046Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -9,8 +9,9 @@
:placeholder="`请输入${quickCreateName}`"
class="w-500 mr-12"
autofocus
:maxlength="quickCreateMaxlength"
:maxlength="quickCreateMaxlength || '-'"
:show-word-limit="quickCreateMaxlength ? true : false"
@keydown.enter="submitHandle"
/>
<el-button type="primary" @click="submitHandle" :disabled="loading">创建</el-button>
@ -45,6 +46,9 @@ import { ref, nextTick, watch, computed, onMounted } from 'vue'
import { MsgError } from '@/utils/message'
defineOptions({ name: 'AppTable' })
import useStore from '@/stores'
const { common } = useStore()
const props = defineProps({
paginationConfig: {
type: Object,
@ -65,7 +69,8 @@ const props = defineProps({
quickCreateMaxlength: {
type: Number,
default: () => 0
}
},
storeKey: String
})
const emit = defineEmits(['changePage', 'sizeChange', 'creatQuick'])
@ -108,9 +113,15 @@ function quickCreateHandel() {
function handleSizeChange() {
emit('sizeChange')
if (props.storeKey) {
common.savePage(props.storeKey, props.paginationConfig)
}
}
function handleCurrentChange() {
emit('changePage')
if (props.storeKey) {
common.savePage(props.storeKey, props.paginationConfig)
}
}
defineExpose({})

View File

@ -19,7 +19,7 @@
v-model="writeValue"
placeholder="请输入"
autofocus
:maxlength="maxlength"
:maxlength="maxlength || '-'"
:show-word-limit="maxlength ? true : false"
></el-input>
</div>
@ -75,7 +75,7 @@ function submit() {
loading.value = false
}, 200)
}
function editNameHandle(row: any) {
function editNameHandle() {
writeValue.value = props.data
isEdit.value = true
}

View File

@ -1,13 +1,28 @@
import { defineStore } from 'pinia'
export interface commonTypes {
breadcrumb: any
paginationConfig: any | null
search: any
}
const useCommonStore = defineStore({
id: 'common',
state: () => ({
breadcrumb: null
state: (): commonTypes => ({
breadcrumb: null,
// 搜索和分页缓存
paginationConfig: {},
search: {}
}),
actions: {
saveBreadcrumb(data: any) {
this.breadcrumb = data
},
savePage(val: string, data: any) {
this.paginationConfig[val] = data
},
saveCondition(val: string, data: any) {
this.search[val] = data
}
}
})

View File

@ -31,14 +31,16 @@ export const randomId = function () {
*/
export function fileType(name: string) {
const suffix = name.split('.')
return suffix[suffix.length - 1]
return suffix[suffix.length - 1] === 'docx' ? 'doc' : suffix[suffix.length - 1]
}
/*
*/
export function getImgUrl(name: string) {
const type = fileType(name) || 'txt'
const typeList = ['txt', 'pdf', 'doc', 'csv', 'md']
const type = typeList.includes(fileType(name)) ? fileType(name) : 'unknow'
return new URL(`../assets/${type}-icon.svg`, import.meta.url).href
}

View File

@ -113,18 +113,18 @@ function clearStore() {
}
function submit() {
loading.value = true
const data = [] as any
const documents = [] as any
StepSecondRef.value?.paragraphList.map((item: any) => {
data.push({
documents.push({
name: item.name,
paragraphs: item.content
})
})
const obj = { ...baseInfo.value, data } as datasetData
const obj = { ...baseInfo.value, documents } as datasetData
if (id) {
//
document
.asyncPostDocument(id as string, data)
.asyncPostDocument(id as string, documents)
.then(() => {
MsgSuccess('提交成功')
clearStore()

View File

@ -29,7 +29,7 @@
</p>
<div class="upload__decoration">
<p>
支持格式TXTMarkdownPDFDOCDOCX每次最多上传50个文件每个文件不超过 10MB
支持格式TXTMarkdownPDFDOCDOCX每次最多上传50个文件每个文件不超过 100MB
</p>
<p>若使用高级分段建议上传前规范文件的分段标识</p>
</div>
@ -43,7 +43,7 @@
<el-card shadow="never" class="file-List-card">
<div class="flex-between">
<div class="flex">
<img :src="getImgUrl(item && item?.name)" alt="" />
<img :src="getImgUrl(item && item?.name)" alt="" width="40" />
<div class="ml-8">
<p>{{ item && item?.name }}</p>
<el-text type="info">{{ filesize(item && item?.size) || '0K' }}</el-text>

View File

@ -30,7 +30,7 @@
>
<div class="flex-between">
<div class="flex">
<img :src="getImgUrl(item && item?.name)" alt="" />
<img :src="getImgUrl(item && item?.name)" alt="" width="40"/>
<div class="ml-8">
<p>{{ item && item?.name }}</p>
<el-text type="info">{{ filesize(item && item?.char_length) }}</el-text>

View File

@ -48,6 +48,7 @@
@selection-change="handleSelectionChange"
v-loading="loading"
:row-key="(row: any) => row.id"
:storeKey="storeKey"
>
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column prop="name" label="文件名称" min-width="280">
@ -156,8 +157,8 @@
</LayoutContainer>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, onBeforeUnmount } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { useRouter, useRoute, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ElTable } from 'element-plus'
import documentApi from '@/api/document'
import ImportDocumentDialog from './component/ImportDocumentDialog.vue'
@ -172,7 +173,24 @@ const {
params: { id } // iddatasetID
} = route as any
const { dataset, document } = useStore()
const { common, dataset, document } = useStore()
const storeKey = 'documents'
onBeforeRouteUpdate((to: any, from: any) => {
common.savePage(storeKey, null)
common.saveCondition(storeKey, null)
})
onBeforeRouteLeave((to: any, from: any) => {
if (to.name !== 'Paragraph') {
common.savePage(storeKey, null)
common.saveCondition(storeKey, null)
} else {
common.saveCondition(storeKey, filterText.value)
}
})
const beforePagination = computed(() => common.paginationConfig[storeKey])
const beforeSearch = computed(() => common.search[storeKey])
const SyncWebDialogRef = ref()
const loading = ref(false)
@ -182,7 +200,7 @@ const documentData = ref<any[]>([])
const currentMouseId = ref(null)
const datasetDetail = ref<any>({})
const paginationConfig = reactive({
const paginationConfig = ref({
current_page: 1,
page_size: 10,
total: 0
@ -355,7 +373,7 @@ function cellMouseLeave() {
}
function handleSizeChange() {
paginationConfig.current_page = 1
paginationConfig.value.current_page = 1
getList()
}
@ -363,13 +381,13 @@ function getList(bool?: boolean) {
documentApi
.getDocument(
id as string,
paginationConfig,
paginationConfig.value,
filterText.value && { name: filterText.value },
bool ? undefined : loading
)
.then((res) => {
documentData.value = res.data.records
paginationConfig.total = res.data.total
paginationConfig.value.total = res.data.total
})
}
@ -380,12 +398,18 @@ function getDetail() {
}
function refresh() {
paginationConfig.current_page = 1
paginationConfig.value.current_page = 1
getList()
}
onMounted(() => {
getDetail()
if (beforePagination.value) {
paginationConfig.value = beforePagination.value
}
if (beforeSearch.value) {
filterText.value = beforeSearch.value
}
getList()
//
initInterval()

View File

@ -23,6 +23,7 @@
:remote-method="remoteMethod"
:loading="optionLoading"
@change="addProblemHandle"
@blur="isAddProblem = false"
class="mb-16"
>
<el-option

View File

@ -75,7 +75,9 @@ const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
const arr = form.value.data.split('\n')
const arr = form.value.data.split('\n').filter(function (item: string) {
return item !== ''
})
problem.asyncPostProblem(id, arr, loading).then((res: any) => {
MsgSuccess('创建成功')
emit('refresh')

View File

@ -6,7 +6,7 @@
<div>
<el-scrollbar>
<div class="p-8">
<el-form label-position="top" v-loading="loading">
<el-form label-position="top" v-loading="loading" @submit.prevent>
<el-form-item label="问题">
<ReadWrite
@change="editName"
@ -18,18 +18,13 @@
<el-form-item label="关联分段">
<template v-for="(item, index) in paragraphList" :key="index">
<CardBox
shadow="never"
:title="item.title || '-'"
class="paragraph-source-card cursor mb-8"
:showIcon="false"
@click.stop="editParagraph(item)"
>
<div class="active-button">
<span class="mr-4">
<el-tooltip effect="dark" content="编辑" placement="top">
<el-button type="primary" text @click.stop="editParagraph(item)">
<el-icon><EditPen /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="取消关联" placement="top">
<el-button type="primary" text @click.stop="disassociation(item)">
<AppIcon iconName="app-quxiaoguanlian"></AppIcon>

View File

@ -11,6 +11,7 @@
<el-scrollbar height="500" wrap-class="paragraph-scrollbar">
<div class="bold title align-center p-24 pb-0">选择文档</div>
<div class="p-8" style="padding-bottom: 8px">
<el-input v-model="filterDoc" placeholder="按 文档名称 搜索" prefix-icon="Search" />
<common-list
:data="documentList"
class="mt-8"
@ -107,6 +108,7 @@ const dialogVisible = ref<boolean>(false)
const loading = ref(false)
const documentList = ref<any[]>([])
const cloneDocumentList = ref<any[]>([])
const paragraphList = ref<any[]>([])
const currentProblemId = ref<String>('')
@ -116,6 +118,7 @@ const associationParagraph = ref<any[]>([])
const currentDocument = ref<String>('')
const search = ref('')
const searchType = ref('title')
const filterDoc = ref('')
const paginationConfig = reactive({
current_page: 1,
@ -166,8 +169,9 @@ function clickDocumentHandle(item: any) {
function getDocument() {
document.asyncGetAllDocument(id, loading).then((res: any) => {
cloneDocumentList.value = res.data
documentList.value = res.data
currentDocument.value = documentList.value?.length > 0 ? documentList.value[0].id : ''
currentDocument.value = cloneDocumentList.value?.length > 0 ? cloneDocumentList.value[0].id : ''
getParagraphList(currentDocument.value)
})
}
@ -204,6 +208,7 @@ function isAssociation(paragraphId: String) {
watch(dialogVisible, (bool) => {
if (!bool) {
documentList.value = []
cloneDocumentList.value = []
paragraphList.value = []
associationParagraph.value = []
@ -214,6 +219,14 @@ watch(dialogVisible, (bool) => {
}
})
watch(filterDoc, (val) => {
paragraphList.value = []
documentList.value = val
? cloneDocumentList.value.filter((item) => item.name.includes(val))
: cloneDocumentList.value
currentDocument.value = documentList.value?.length > 0 ? documentList.value[0].id : ''
})
const open = (problemId: string) => {
currentProblemId.value = problemId
getDocument()