109 lines
6.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

ns = params_kw.copy()
kb_id = ns.get('kb_id', '')
folder_id = ns.get('id', '')
folder_label = ns.get('label', '全部文件')
if folder_id == '__root__':
folder_id = ''
folder_label = '根目录'
db = DBPools()
dbname = get_module_dbname('rag')
rows = []
try:
async with db.sqlorContext(dbname) as sor:
if folder_id:
recs = await sor.sqlExe(
"SELECT id, file_name, file_type, file_size, file_path, status, chunk_count, created_at FROM documents WHERE kb_id=${kb_id}$ AND folder_id=${folder_id}$ ORDER BY created_at DESC",
{"kb_id": kb_id, "folder_id": folder_id})
else:
recs = await sor.sqlExe(
"SELECT id, file_name, file_type, file_size, file_path, status, chunk_count, created_at FROM documents WHERE kb_id=${kb_id}$ AND (folder_id IS NULL OR folder_id IN ('','__root__')) ORDER BY created_at DESC",
{"kb_id": kb_id})
for r in recs:
rows.append({
"id": r.id,
"file_name": r.file_name,
"file_type": r.file_type or '',
"file_size": r.file_size or 0,
"file_path": r.file_path or '',
"status": r.status or '',
"chunk_count": r.chunk_count or 0,
"created_at": str(r.created_at)[:16] if r.created_at else ''
})
except:
return {"widgettype": "Text", "options": {"text": "加载文件列表失败", "cfontsize": 14, "color": "#e74c3c", "halign": "center", "marginTop": "40px"}}
def fmt_size(sz):
if sz < 1024: return str(sz) + "B"
elif sz < 1024*1024: return str(round(sz/1024, 1)) + "KB"
else: return str(round(sz/(1024*1024), 1)) + "MB"
def trunc_name(name, maxlen=28):
if len(name) > maxlen:
return name[:maxlen-3] + "..."
return name
header = {
"widgettype": "HBox",
"options": {"width": "100%", "padding": "10px 0", "borderBottom": "1px solid #e0e0e0", "alignItems": "center"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "📄 " + folder_label, "cfontsize": 14, "fontWeight": "bold", "color": "#333"}},
{"widgettype": "Text", "options": {"text": "" + str(len(rows)) + " 个文件)", "cfontsize": 12, "color": "#999", "marginLeft": "8px"}},
{"widgettype": "Text", "options": {"text": "", "css": "filler"}},
{"widgettype": "Button", "options": {"label": "📊 分析结果", "cfontsize": 12, "bgcolor": "#ede7f6", "color": "#4527a0", "padding": "4px 12px", "borderRadius": "14px", "marginLeft": "8px"},
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "file_list_panel", "mode": "replace",
"options": {"url": "./analysis.dspy?kb_id=" + kb_id}}]}
]
}
file_widgets = [header]
if not rows:
file_widgets.append({
"widgettype": "Text", "options": {"text": "暂无文件", "cfontsize": 13, "color": "#aaa", "halign": "center", "marginTop": "40px"}
})
else:
for f in rows:
sc = "#50b86c"; st = "完成"
if f["status"] == "pending": sc = "#e6a23c"; st = "处理中"
elif f["status"] == "error": sc = "#f56c6c"; st = "失败"
file_url = f["file_path"]
if not file_url.startswith("/idfile"):
file_url = "/idfile" + file_url
del_url = "/rag/knowledge_bases_list/delete_file.dspy?_webbricks_=1&kb_id=" + kb_id + "&doc_id=" + f["id"] + "&folder_id=" + folder_id + "&folder_label=" + folder_label
display_name = trunc_name(f["file_name"])
row = {
"widgettype": "HBox",
"options": {"width": "100%", "padding": "6px 12px", "borderBottom": "1px solid #f0f0f0", "alignItems": "center"},
"subwidgets": [
{"widgettype": "Text", "options": {
"text": "📄 " + display_name, "cfontsize": 13, "color": "#333",
"cwidth": 28, "halign": "left", "overflow": "hidden",
"title": f["file_name"]
}},
{"widgettype": "Text", "options": {"text": f["file_type"].upper(), "cfontsize": 11, "color": "#999", "cwidth": 5, "halign": "center"}},
{"widgettype": "Text", "options": {"text": fmt_size(f["file_size"]), "cfontsize": 11, "color": "#999", "cwidth": 8, "halign": "right"}},
{"widgettype": "Text", "options": {"text": st, "cfontsize": 11, "color": sc, "cwidth": 6, "halign": "center"}},
{"widgettype": "Text", "options": {"text": f["created_at"], "cfontsize": 11, "color": "#999", "cwidth": 13, "halign": "center"}},
{
"widgettype": "HBox", "options": {"spacing": "6px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "👁", "cfontsize": 14, "css": "clickable", "color": "#4a90d9", "title": "查看"},
"binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "window.open(" + json.dumps(file_url) + ",'_blank')"}]},
{"widgettype": "Text", "options": {"text": "⬇", "cfontsize": 14, "css": "clickable", "color": "#50b86c", "title": "下载"},
"binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "var a=document.createElement('a');a.href=" + json.dumps(file_url) + ";a.download='';document.body.appendChild(a);a.click();document.body.removeChild(a)"}]},
{"widgettype": "Text", "options": {"text": "🗑", "cfontsize": 14, "css": "clickable", "color": "#f56c6c", "title": "删除"},
"binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "if(!confirm('确认删除 ' + decodeURIComponent(" + json.dumps(f["file_name"]) + ") + ' ? 不可恢复'))return;fetch(" + json.dumps(del_url) + ").then(function(r){return r.json()}).then(function(){var u='/rag/knowledge_bases_list/file_list.dspy?_webbricks_=1&kb_id='+encodeURIComponent(" + json.dumps(kb_id) + ")+'&id='+encodeURIComponent(" + json.dumps(folder_id) + ")+'&label='+encodeURIComponent(" + json.dumps(folder_label) + ");fetch(u).then(function(r){return r.json()}).then(function(d){var fp=bricks.getWidgetById('file_list_panel',bricks.app.root);if(fp){fp.clear_widgets();bricks.widgetBuild(d,fp).then(function(w){if(w)fp.add_widget(w)})}})})"}]}
]}
]}
file_widgets.append(row)
result = {"widgettype": "VBox", "options": {"width": "100%", "spacing": "0"}, "subwidgets": file_widgets}
return result