114 lines
7.2 KiB
Plaintext
114 lines
7.2 KiB
Plaintext
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": "#1565c0", "title": "添加标签"},
|
||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "PopupWindow",
|
||
"popup_options": {"title": "为「" + display_name + "」添加标签", "width": "32%", "height": "auto",
|
||
"movable": True, "resizable": True, "modal": True},
|
||
"options": {"url": "./tag_form.dspy?doc_id=" + f["id"] + "&kb_id=" + kb_id}}]},
|
||
{"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
|