liuchengsen 1 сар өмнө
parent
commit
2c9037e462
1 өөрчлөгдсөн 29 нэмэгдсэн , 14 устгасан
  1. 29 14
      static/index.html

+ 29 - 14
static/index.html

@@ -5,9 +5,10 @@
   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
   <title>AI 药典助手</title>
   <style>
-    :root{--bk:#002FA7;--bk-l:#E8EDF8;--rd:#C41E3A;--rd-l:#FDEAEE;--bg:#F5F6FA;--card:#fff;--text:#1a1a2e;--sub:#888;--radius:12px}
+    :root{--app-height:100vh;--bk:#002FA7;--bk-l:#E8EDF8;--rd:#C41E3A;--rd-l:#FDEAEE;--bg:#F5F6FA;--card:#fff;--text:#1a1a2e;--sub:#888;--radius:12px}
     *{margin:0;padding:0;box-sizing:border-box}
-    body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;background:var(--bg);height:100dvh;display:flex;flex-direction:column;overflow:hidden}
+    html{width:100%;height:100%;overflow:hidden}
+    body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;background:var(--bg);width:100%;height:var(--app-height);min-height:100%;display:flex;flex-direction:column;overflow:hidden}
     .header{background:linear-gradient(135deg,var(--bk),#1a3fbf);color:#fff;padding:12px 14px;text-align:center;flex-shrink:0;position:relative;overflow:hidden;z-index:10}
     .header::after{content:'';position:absolute;top:-40px;right:-30px;width:120px;height:120px;background:var(--rd);border-radius:50%;opacity:.15}
     .header h1{font-size:17px;font-weight:700;position:relative;z-index:1}
@@ -16,7 +17,7 @@
     .nav{display:flex;background:#fff;border-bottom:1px solid #e0e0e0;flex-shrink:0;z-index:10}
     .nav-btn{flex:1;padding:12px;text-align:center;font-size:13px;color:var(--sub);cursor:pointer;border:none;background:none;border-bottom:2px solid transparent;transition:all .2s;min-height:44px}
     .nav-btn.active{color:var(--bk);border-bottom-color:var(--bk);font-weight:600}
-    .chat{flex:1;overflow-y:auto;padding:12px 14px;display:flex;flex-direction:column;gap:12px;-webkit-overflow-scrolling:touch}
+    .chat{flex:1;min-height:0;overflow-y:auto;padding:12px 14px;display:flex;flex-direction:column;gap:12px;-webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior-y:contain}
         #tabChat,#tabDrugs{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden}
     .msg{max-width:85%;padding:10px 14px;border-radius:var(--radius);font-size:14px;line-height:1.7;word-break:break-word;animation:fadeIn .3s}
     .msg.user{align-self:flex-end;background:var(--bk);color:#fff;border-radius:var(--radius) var(--radius) 4px var(--radius)}
@@ -75,12 +76,12 @@
     .tag-btn:active{background:rgba(0,47,167,.15)}
     .welcome{text-align:center;color:var(--sub);padding:40px 20px}
     .welcome .icon{font-size:48px;margin-bottom:12px}
-    .drug-list{flex:1;overflow-y:auto;padding:12px 14px;min-height:0}
+    .drug-list{flex:1;overflow-y:auto;padding:12px 14px;min-height:0;-webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior-y:contain}
     .drug-pager{flex-shrink:0;padding:8px 14px;background:#fff;border-top:1px solid #e0e0e0}
     .drug-card{background:var(--card);border-radius:var(--radius);padding:14px;margin-bottom:10px;box-shadow:0 1px 4px rgba(0,0,0,.06);cursor:pointer}
     .drug-card h3{font-size:15px;color:var(--bk);margin-bottom:4px}
     .drug-card .meta{font-size:12px;color:var(--sub)}
-    .drug-detail{padding:16px 14px;flex:1;overflow-y:auto}
+    .drug-detail{padding:16px 14px;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior-y:contain}
     .drug-detail h2{font-size:20px;color:var(--bk);margin-bottom:8px}
     .drug-detail h3{font-size:15px;color:var(--bk);margin:16px 0 8px}
     .drug-detail .info-row{font-size:13px;color:var(--sub);margin:4px 0}
@@ -99,7 +100,6 @@
     .pager select{padding:6px 8px;appearance:auto}
     .clear-chat-btn{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.3);color:#fff;padding:4px 10px;border-radius:14px;font-size:11px;cursor:pointer;z-index:2;transition:all .15s}
     .clear-chat-btn:hover{background:rgba(255,255,255,.25)}
-@media(max-width:400px){.input-area{padding:8px 6px;gap:4px}.input-area input{padding:8px 10px;font-size:13px;min-height:40px}.btn{padding:6px 10px;font-size:12px;min-height:40px}.media-btn{min-width:40px;padding:4px 6px;font-size:20px;border-radius:10px}.media-label{font-size:9px}.tags{padding:6px 8px 8px;gap:4px}.tag-btn{font-size:11px;padding:4px 10px}.chat{padding:10px 8px}.msg{max-width:90%}.header h1{font-size:15px}.header .sub{font-size:10px}}
     .login-modal-mask{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,.5);z-index:100}
     .login-modal{width:min(320px,100%);overflow:hidden;border-radius:12px;background:#fff;box-shadow:0 12px 36px rgba(0,0,0,.2);text-align:center}
     .login-modal-title{padding:24px 24px 8px;color:var(--text);font-size:17px;font-weight:700}
@@ -172,6 +172,25 @@
     return t;
   })();
 
+  function syncAppHeight(){
+    var layoutHeight=window.innerHeight||0;
+    var visualHeight=window.visualViewport&&window.visualViewport.height
+      ? window.visualViewport.height
+      : 0;
+    var viewportHeight=layoutHeight&&visualHeight
+      ? Math.min(layoutHeight,visualHeight)
+      : (layoutHeight||visualHeight);
+    if(viewportHeight){
+      document.documentElement.style.setProperty('--app-height',Math.round(viewportHeight)+'px');
+    }
+  }
+  syncAppHeight();
+  window.addEventListener('resize',syncAppHeight);
+  window.addEventListener('orientationchange',syncAppHeight);
+  if(window.visualViewport){
+    window.visualViewport.addEventListener('resize',syncAppHeight);
+  }
+
   function authHeaders(){
     var h = {'Content-Type':'application/json'};
     if (TOKEN) h['Authorization'] = 'Bearer ' + TOKEN;
@@ -369,7 +388,6 @@
     try{
       var ctrl=streamAbort?streamAbort:new AbortController();
       var r=await fetch(endpoint,{method:'POST',headers:authHeaders(),body:body,signal:ctrl.signal});
-      if(r.status===401){showLoginModal();aiDiv.classList.remove('streaming');STREAMING=false;resetSendBtn();contentDiv.innerHTML=md2html('请先登录后再提问');return}
       if(!r.ok){contentDiv.innerHTML=md2html('请求失败: HTTP '+r.status);aiDiv.classList.remove('streaming');STREAMING=false;resetSendBtn();return}
       sourcesData=[];
       var reader=r.body.getReader(),decoder=new TextDecoder(),buffer='',fullText='',eventType='';
@@ -462,6 +480,7 @@
   });
 
   window.send=function(){
+    if(!TOKEN){showLoginModal();return}
     var input=document.getElementById('userInput'),text=input.value.trim();
     var hasMedia=!!pendingMedia;
     if(!text&&!hasMedia)return;input.value='';if(STREAMING)return;
@@ -522,8 +541,7 @@
 
   window.loadDrugDetailBySrc=async function(drugName){
     try{
-      var r=await fetch(API_BASE+'/api/v1/drug/search?keyword='+encodeURIComponent(drugName)+'&pageSize=10',{headers:authHeaders()});
-      if(r.status===401){showLoginModal();return}
+      var r=await fetch(API_BASE+'/api/v1/drug/search?keyword='+encodeURIComponent(drugName)+'&page_size=10',{headers:authHeaders()});
       var d=await r.json();var items=d.items||d.data||[];
       // 2025年版优先,再精确匹配
       items.sort(function(a,b){
@@ -541,11 +559,9 @@
   var ALL_DRUGS=[],drugPage=1,drugTotalPages=1,drugPageSize=20,drugKeyword='';
   async function loadDrugList(page){
     page=page||1;drugPage=page;
-    var url=API_BASE+'/api/v1/drug/search?page='+page+'&pageSize='+drugPageSize;
+    var url=API_BASE+'/api/v1/drug/search?page='+page+'&page_size='+drugPageSize;
     if(drugKeyword) url+='&keyword='+encodeURIComponent(drugKeyword);
-    try{var r=await fetch(url,{headers:authHeaders()});
-      if(r.status===401){showLoginModal();return}
-      var d=await r.json();
+    try{var r=await fetch(url,{headers:authHeaders()});var d=await r.json();
       ALL_DRUGS=d.items||d.data||[];drugTotalPages=d.total_pages||1;
       renderDrugCards(ALL_DRUGS);
     }catch(e){ALL_DRUGS=[];renderDrugCards([])}
@@ -585,7 +601,6 @@
   window.loadDrugDetail=async function(drugId){
     try{
       var r=await fetch(API_BASE+'/api/v1/drug/'+encodeURIComponent(drugId),{headers:authHeaders()});
-      if(r.status===401){showLoginModal();return}
       var d=await r.json();var drug=d.data||d;
       var dd=document.getElementById('tabDrugs');
       var topBar='<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e0e0e0">';