report_images.html 7.43 KB
{% extends "base.html" %}
{% set request_path = "/report-images" %}

{% block body %}
<style>body{overflow-y:auto!important;height:auto!important;}</style>
<div style="max-width:700px;margin:0 auto;padding:20px;">
<h2 style="margin-bottom:12px;">🖼 日报图片列表</h2>
<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;align-items:center;">
  <input type="text" id="searchInput" placeholder="搜索群名/日期..." oninput="renderImages()" style="flex:1;min-width:120px;padding:10px;border:1px solid #ddd;border-radius:8px;font-size:14px;">
  <select id="sortBy" onchange="renderImages()" style="padding:10px;border:1px solid #ddd;border-radius:8px;font-size:13px;background:white;cursor:pointer;">
    <option value="time">按时间↓</option>
    <option value="name">按群名</option>
  </select>
</div>
<div id="imgList"><div class="loading"><div class="spinner"></div></div></div>
</div>

<div id="imgModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.9);z-index:1000;align-items:center;justify-content:center;" onclick="closeImg()">
  <img id="imgModalSrc" style="max-width:95%;max-height:90%;border-radius:4px;" onclick="event.stopPropagation()">
</div>
<div id="sendModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:999;align-items:center;justify-content:center;" onclick="closeSendModal()">
  <div style="background:white;border-radius:12px;width:92%;max-width:400px;max-height:80%;overflow-y:auto;padding:0;" onclick="event.stopPropagation()">
    <div style="padding:14px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center;"><span style="font-weight:600;">选择发送对象</span><button onclick="closeSendModal()" style="background:none;border:none;font-size:22px;cursor:pointer;">×</button></div>
    <div style="padding:8px 12px;"><input type="text" id="contactSearch" placeholder="搜索..." oninput="filterContacts()" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:8px;font-size:14px;margin-bottom:8px;"></div>
    <div id="contactList" style="max-height:400px;overflow-y:auto;"><div style="text-align:center;padding:20px;color:#999;">加载中...</div></div>
  </div>
</div>

<script>
var currentImageId=null,allContacts=[],allImages=[];
function showImg(u){document.getElementById('imgModalSrc').src=u;document.getElementById('imgModal').style.display='flex';}
function closeImg(){document.getElementById('imgModal').style.display='none';}
async function load(){
  var list=document.getElementById('imgList');
  try{var r=await fetch('/api/report-images');var j=await r.json();
    if(!j.ok||!j.data.length){list.innerHTML='<div class="empty-state">暂无日报图片</div>';return;}
    allImages=j.data;
    renderImages();
  }catch(e){list.innerHTML='<div class="empty-state">加载失败</div>';}
}
function renderImages(){
  var list=document.getElementById('imgList');
  var q=(document.getElementById('searchInput').value||'').trim().toLowerCase();
  var sb=document.getElementById('sortBy').value;
  var data=allImages.slice();
  if(q)data=data.filter(function(img){return ((img.chatroom_name||'')+' '+img.report_date).toLowerCase().indexOf(q)>=0;});
  if(sb==='name')data.sort(function(a,b){return (a.chatroom_name||'').localeCompare(b.chatroom_name||'')});
  else data.sort(function(a,b){return (b.created_at||'').localeCompare(a.created_at||'')});
  if(!data.length){list.innerHTML='<div class="empty-state">无匹配</div>';return;}
  var html='';
  for(var i=0;i<data.length;i++){
    var img=data[i],url='/media/report-image/'+img.id;
    html+='<div id="report-'+img.report_id+'" style="background:white;border-radius:8px;padding:16px;margin-bottom:12px;box-shadow:0 1px 2px rgba(0,0,0,0.05);">';
    html+='<img src="'+url+'" onclick="showImg(\''+url+'\')" style="width:100%;max-height:300px;object-fit:contain;border-radius:6px;border:1px solid #eee;cursor:pointer;margin-bottom:10px;">';
    html+='<div style="font-size:14px;font-weight:600;">'+esc(img.chatroom_name||'')+' — '+img.report_date+' <span style="font-size:11px;color:#999;">#'+img.report_id+'</span></div>';
    html+='<div style="font-size:11px;color:#999;margin:4px 0;">复古铜版画风格 · '+(img.created_at||'').slice(0,16)+' · <a href="/report/'+img.report_id+'" style="color:#3498db;text-decoration:none;">查看日报</a></div>';
    html+='<div style="display:flex;gap:8px;margin-top:10px;">';
    html+='<button onclick="showSendModal('+img.id+')" style="flex:1;padding:12px;border:1px solid #27ae60;border-radius:8px;background:white;color:#27ae60;font-size:14px;cursor:pointer;">发送微信</button>';
    html+='<button onclick="del('+img.id+')" style="flex:1;padding:12px;border:1px solid #e74c3c;border-radius:8px;background:white;color:#e74c3c;font-size:14px;cursor:pointer;">删除</button>';
    html+='</div></div>';
  }
  list.innerHTML=html;
}
function esc(s){return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');}
async function showSendModal(imgId){currentImageId=imgId;document.getElementById('sendModal').style.display='flex';document.getElementById('contactSearch').value='';
  if(!allContacts.length){try{var r=await fetch('/api/sessions');var j=await r.json();allContacts=(j.data||[]).map(function(s){return{wxid:s.talker,name:s.display_name||s.talker,type:s.talker_type,preview:s.preview||''};});}catch(e){}}
  renderContacts(allContacts);}
function renderContacts(list){var el=document.getElementById('contactList');if(!list.length){el.innerHTML='<div style="text-align:center;padding:20px;color:#999;">无联系人</div>';return;}
  var html='';
  for(var i=0;i<list.length;i++){var c=list[i],color=c.type==='group'?'#27ae60':c.type==='official'?'#e67e22':'#3498db',label=c.type==='group'?'群':c.type==='official'?'号':'人';
    html+='<div data-wxid="'+esc(c.wxid)+'" data-name="'+esc(c.name)+'" onclick="sendToEl(this)" style="padding:14px;border-bottom:1px solid #f5f5f5;cursor:pointer;display:flex;align-items:center;gap:10px;">';
    html+='<div style="width:40px;height:40px;border-radius:8px;background:'+color+';color:white;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">'+(c.name||'?')[0]+'</div>';
    html+='<div style="flex:1;min-width:0;"><div style="font-size:15px;">'+esc(c.name)+'</div><div style="font-size:12px;color:#999;">'+esc(c.preview).slice(0,30)+'</div></div>';
    html+='<span style="font-size:12px;color:#bbb;">'+label+'</span></div>';}
  el.innerHTML=html;}
function filterContacts(){var q=document.getElementById('contactSearch').value.trim().toLowerCase();if(!q){renderContacts(allContacts);return;}renderContacts(allContacts.filter(function(c){return c.name.toLowerCase().indexOf(q)>=0;}));}
function closeSendModal(){document.getElementById('sendModal').style.display='none';currentImageId=null;}
async function sendToEl(el){var wxid=el.getAttribute('data-wxid'),name=el.getAttribute('data-name');if(!confirm('发送给 '+name+'?'))return;var imgId=currentImageId;closeSendModal();
  try{var r=await fetch('/api/report-image/'+imgId+'/send',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({to:wxid})});var j=await r.json();
    if(j.ok){alert('发送任务已提交!');}else{alert('失败: '+(j.error||''));}}catch(e){alert('错误: '+e.message);}}
async function del(id){if(!confirm('确认删除?'))return;await fetch('/api/report-image/'+id+'/delete',{method:'POST'});load();}
load();
</script>
{% endblock %}