Bladeren bron

关键词推荐更新

liuchengsen 3 weken geleden
bovenliggende
commit
252874487a
1 gewijzigde bestanden met toevoegingen van 74 en 3 verwijderingen
  1. 74 3
      static/index.html

+ 74 - 3
static/index.html

@@ -55,6 +55,15 @@
     .ext-link{color:#002FA7;text-decoration:underline;word-break:break-all}
     .ext-link:hover{color:#C41E3A}
     .ext-link:visited{color:#6a1b9a}
+    .brand-recs{margin-top:12px;padding-top:10px;border-top:1px dashed #e0c080}
+    .brand-recs-title{font-size:12px;color:#b8860b;margin-bottom:8px;font-weight:600}
+    .brand-card{display:block;background:linear-gradient(135deg,#fffdf5,#fff8e1);border:1px solid #f0d060;border-radius:10px;padding:12px 14px;margin-bottom:8px;text-decoration:none;transition:all .2s;cursor:pointer}
+    .brand-card:hover{background:linear-gradient(135deg,#fff8e1,#fff3c4);border-color:#d4a017;box-shadow:0 2px 8px rgba(180,130,20,.12);transform:translateY(-1px)}
+    .brand-card-name{font-size:14px;font-weight:700;color:#8b6914;margin-bottom:4px}
+    .brand-card-desc{font-size:12px;color:#999074;line-height:1.5}
+    .brand-card-arrow{float:right;font-size:13px;color:#c4a035;margin-left:8px}
+    .brand-more-btn{display:block;width:100%;padding:8px;margin-top:6px;background:#fffdf5;border:1px dashed #e0c080;border-radius:8px;font-size:12px;color:#b8860b;cursor:pointer;text-align:center;transition:all .15s}
+    .brand-more-btn:hover{background:#fff8e1;border-color:#d4a017}
     .input-area{display:flex;padding:10px 14px;background:#fff;border-top:1px solid #e0e0e0;gap:8px;flex-shrink:0;z-index:10}
         #previewArea{flex-shrink:0}
     .input-area input{flex:1;padding:10px 14px;border:1px solid #ddd;border-radius:24px;font-size:14px;outline:none;min-height:44px}
@@ -129,7 +138,7 @@
   <div class="input-area">
     <input type="file" id="imageInput" accept="image/*" onchange="onFilePicked('image')" style="display:none">
     <input id="userInput" placeholder="输入药品问题,或上传图片...">
-    <button class="btn btn-danger" id="sendBtn" onclick="send()">发送</button>
+    <button class="btntn-danger" id="sendBtn" onclick="send()">发送</button>
     <span style="display:flex;flex-direction:column;align-items:center;gap:2px;flex-shrink:0;cursor:pointer" onclick="document.getElementById('imageInput').click()"><button class="media-btn" type="button">+</button></span>
     <button class="btn btn-secondary" id="stopBtn" onclick="stopCurrent()" style="display:none">停止</button>
   </div>
@@ -295,6 +304,7 @@
   }
 
   var STREAMING=false,streamAbort=null,currentIntent='';
+  var sourcesData=[],brandRecsData=[];
   var pendingMedia=null;
 
   // ============================================================
@@ -460,6 +470,8 @@
       }
       if(!r.ok){contentDiv.innerHTML=md2html('请求失败: HTTP '+r.status);aiDiv.classList.remove('streaming');STREAMING=false;resetSendBtn();return}
       sourcesData=[];
+      brandRecsData=[];
+      brandRecsData=[];
       var reader=r.body.getReader(),decoder=new TextDecoder(),buffer='',fullText='',eventType='';
       while(true){
         var{ done, value }=await reader.read();
@@ -483,6 +495,10 @@
               try{var meta=JSON.parse(data);if(meta.sources&&meta.sources.length>0)sourcesData=meta.sources}catch(e){}
               continue;
             }
+            if(eventType==='brand_recommend'){
+              try{var br=JSON.parse(data);brandRecsData=br.recommendations||[];}catch(e){brandRecsData=[]}
+              continue;
+            }
             fullText+=data;
             contentDiv.innerHTML=md2html(fullText)+'<span class="cursor">|</span>';
             document.getElementById('chat').scrollTop=document.getElementById('chat').scrollHeight;
@@ -490,9 +506,9 @@
           }
         }
       }
-      contentDiv.innerHTML=md2html(fullText)+buildSourceTags();var c=contentDiv.querySelector('.cursor');if(c)c.remove();
+      contentDiv.innerHTML=md2html(fullText)+buildBrandRecs()+buildSourceTags();var c=contentDiv.querySelector('.cursor');if(c)c.remove();
     }catch(e){
-      if(e.name==='AbortError'){contentDiv.innerHTML=md2html(fullText+' <span style="color:var(--rd)">已停止</span>')+buildSourceTags();}
+      if(e.name==='AbortError'){contentDiv.innerHTML=md2html(fullText+' <span style="color:var(--rd)">已停止</span>')+buildBrandRecs()+buildSourceTags();}
       else{contentDiv.innerHTML=md2html('连接失败: '+esc(e.message));}
     }
     aiDiv.classList.remove('streaming');STREAMING=false;streamAbort=null;resetSendBtn();
@@ -573,6 +589,61 @@
     streamAsk(query,media,aiDiv,contentDiv);
   }
 
+  function buildBrandRecs(){
+    if(!brandRecsData||!brandRecsData.length)return'';
+    var SHOW_MAX=3;
+    var showRecs=brandRecsData.slice(0,SHOW_MAX);
+    var extraRecs=brandRecsData.slice(SHOW_MAX);
+    var h='<div class="brand-recs">';
+    h+='<div class="brand-recs-title">💊 品牌药品推荐</div>';
+    for(var i=0;i<showRecs.length;i++){
+      var r=showRecs[i];
+      var name=r.brand_name||'';
+      var desc=r.description||(r.function||'');
+      if(desc.length>120)desc=desc.substring(0,120)+'...';
+      var url=r.jump_url||'';
+      if(url){
+        h+='<a class="brand-card" href="'+escAttr(url)+'" target="_blank" rel="noopener">';
+        h+='<span class="brand-card-arrow">→</span>';
+        h+='<div class="brand-card-name">'+esc(name)+'</div>';
+        h+='<div class="brand-card-desc">'+esc(desc)+'</div>';
+        h+='</a>';
+      } else {
+        h+='<div class="brand-card" style="cursor:default">';
+        h+='<div class="brand-card-name">'+esc(name)+'</div>';
+        h+='<div class="brand-card-desc">'+esc(desc)+'</div>';
+        h+='</div>';
+      }
+    }
+    if(extraRecs.length>0){
+      var moreId='brandMore'+Date.now();
+      h+='<div id="'+moreId+'" style="display:none">';
+      for(var j=0;j<extraRecs.length;j++){
+        var er=extraRecs[j];
+        var ename=er.brand_name||'';
+        var edesc=er.description||(er.function||'');
+        if(edesc.length>120)edesc=edesc.substring(0,120)+'...';
+        var eurl=er.jump_url||'';
+        if(eurl){
+          h+='<a class="brand-card" href="'+escAttr(eurl)+'" target="_blank" rel="noopener">';
+          h+='<span class="brand-card-arrow">→</span>';
+          h+='<div class="brand-card-name">'+esc(ename)+'</div>';
+          h+='<div class="brand-card-desc">'+esc(edesc)+'</div>';
+          h+='</a>';
+        } else {
+          h+='<div class="brand-card" style="cursor:default">';
+          h+='<div class="brand-card-name">'+esc(ename)+'</div>';
+          h+='<div class="brand-card-desc">'+esc(edesc)+'</div>';
+          h+='</div>';
+        }
+      }
+      h+='</div>';
+      h+='<button class="brand-more-btn" onclick="var d=document.getElementById(\''+moreId+'\');var t=this;if(d.style.display===\'none\'){d.style.display=\'block\';t.textContent=\'▲ 收起 '+extraRecs.length+' 条推荐\'}else{d.style.display=\'none\';t.textContent=\'▼ 展开 '+extraRecs.length+' 条推荐\'}">▼ 展开 '+extraRecs.length+' 条推荐</button>';
+    }
+    h+='</div>';
+    return h;
+  }
+
   function buildSourceTags(){
     if(!sourcesData||!sourcesData.length)return'';
     // 按药名分组