diff --git a/wwwroot/knowledge_bases_list/search.ui b/wwwroot/knowledge_bases_list/search.ui index 46b8d1c..3ddfdd8 100644 --- a/wwwroot/knowledge_bases_list/search.ui +++ b/wwwroot/knowledge_bases_list/search.ui @@ -36,8 +36,12 @@ "id": "tag_filter", "options": {"spacing": "4px", "alignItems": "center", "wrap": true, "padding": "2px 0"}, "subwidgets": [ - {"widgettype": "Text", "options": {"text": "选择知识库后加载标签", "cfontsize": 11, "color": "#ccc"}} + {"widgettype": "Text", "options": {"text": "加载中...", "cfontsize": 11, "color": "#ccc"}} ] + }, + { + "widgettype": "Html", + "options": {"html": ""} } ] }, @@ -57,12 +61,6 @@ } ], "binds": [ - { - "wid": "kb_selector", - "event": "change", - "actiontype": "script", - "script": "var kb_id=this.resultValue()||'all';var tf=document.querySelector('#tag_filter');if(!tf)return;if(kb_id==='all'){tf.innerHTML='选择具体知识库后加载标签';return};fetch('/rag/knowledge_bases_list/tag_options.dspy?_webbricks_=1&kb_id='+encodeURIComponent(kb_id)).then(function(r){return r.json()}).then(function(tags){tf.innerHTML='';if(!tags||tags.length===0){tf.innerHTML='该知识库暂无标签';return};tags.forEach(function(t){var chip=document.createElement('span');chip.setAttribute('data-tid',t.value);chip.setAttribute('data-sel','0');chip.style.cssText='display:inline-block;padding:3px 10px;border-radius:12px;font-size:11px;cursor:pointer;margin:2px 4px;border:1px solid #ddd;background:#f5f5f5;color:#666;transition:all .2s';chip.textContent='#'+t.text;chip.onclick=function(){var el=this;var on=el.getAttribute('data-sel')==='1';el.setAttribute('data-sel',on?'0':'1');el.style.background=on?'#f5f5f5':'#e3f2fd';el.style.color=on?'#666':'#1565c0';el.style.borderColor=on?'#ddd':'#90caf9';};tf.appendChild(chip)})}).catch(function(){tf.innerHTML='加载标签失败'})" - }, { "wid": "search_bar", "event": "search", diff --git a/wwwroot/knowledge_bases_list/search_result.dspy b/wwwroot/knowledge_bases_list/search_result.dspy index 6fd7610..5ce5dc4 100644 --- a/wwwroot/knowledge_bases_list/search_result.dspy +++ b/wwwroot/knowledge_bases_list/search_result.dspy @@ -52,12 +52,16 @@ if tag_ids_str: try: async with get_sor_context(env, 'rag') as sor: placeholders = [] - nsq = {"kb_id": kb_id} + nsq = {} + kb_filter = "" + if kb_id and kb_id != "all": + kb_filter = "kb_id=${kb_id}$ AND " + nsq["kb_id"] = kb_id for i, tid in enumerate(wanted_tags): placeholders.append("${tid_" + str(i) + "}$") nsq["tid_" + str(i)] = tid sql = ("SELECT media_id FROM media_tags " - "WHERE kb_id=${kb_id}$ AND media_type='document' AND tag_id IN (" + ",".join(placeholders) + ") " + "WHERE " + kb_filter + "media_type='document' AND tag_id IN (" + ",".join(placeholders) + ") " "GROUP BY media_id HAVING COUNT(DISTINCT tag_id)=" + str(len(wanted_tags))) recs = await sor.sqlExe(sql, nsq) tag_doc_ids = set(r.media_id for r in recs) diff --git a/wwwroot/knowledge_bases_list/tag_options.dspy b/wwwroot/knowledge_bases_list/tag_options.dspy index d3d3b6e..a99e46f 100644 --- a/wwwroot/knowledge_bases_list/tag_options.dspy +++ b/wwwroot/knowledge_bases_list/tag_options.dspy @@ -1,12 +1,9 @@ import json -ns = params_kw.copy() -kb_id = ns.get('kb_id', '') -if not kb_id or kb_id == 'all': - return json.dumps([], ensure_ascii=False) env = request._run_ns +userorgid = await env.get_userorgid() async with get_sor_context(env, 'rag') as sor: recs = await sor.sqlExe( - "SELECT id, name, color FROM tags WHERE kb_id=${kb_id}$ ORDER BY created_at", - {"kb_id": kb_id}) + "SELECT id, name, color FROM tags WHERE org_id=${org_id}$ ORDER BY created_at", + {"org_id": userorgid}) items = [{"value": r.id, "text": r.name, "color": r.color or '#3b82f6'} for r in recs] return json.dumps(items, ensure_ascii=False)