report_images.html 8.21 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="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){return; /* no-op: now uses dedicated page */}
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+='<a href="/report-image/'+img.id+'" style="display:block;"><img src="'+url+'" style="width:100%;max-height:300px;object-fit:contain;border-radius:6px;border:1px solid #eee;cursor:pointer;margin-bottom:10px;"></a>';
    html+='<div style="font-size:12px;color:#666;font-family:monospace;word-break:break-all;margin-bottom:4px;">📄 '+esc(img.image_path||'').split('/').pop()+'</div>';
    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>'+styleBadge(img.style)+'</div>';
    html+='<div style="font-size:11px;color:#999;margin:4px 0;">日报 ' + img.report_date + (img.created_at ? ' · 生成于 ' + (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;');}
var STYLE_LABELS={vintage:'复古报纸',swiss:'瑞士',magazine:'编辑杂志','visual-note':'视觉笔记',minimalism:'极简',brutalism:'粗野',memphis:'孟菲斯',bauhaus:'包豪斯',cyberpunk:'赛博朋克','futuristic-ui':'未来界面','pop-art':'波普',isometric:'等距',watercolor:'水彩',vaporwave:'蒸汽波'};
var STYLE_COLORS={vintage:'#8b7355',swiss:'#e02020',magazine:'#1a365d','visual-note':'#e67e22',minimalism:'#333',brutalism:'#0000ff',memphis:'#ff6b9d',bauhaus:'#1d3f8e',cyberpunk:'#00ff41','futuristic-ui':'#00bcd4','pop-art':'#ff5722',isometric:'#607d8b',watercolor:'#9c27b0',vaporwave:'#ff6ac2'};
function styleBadge(s){if(!s)return '';var n=STYLE_LABELS[s]||s,c=STYLE_COLORS[s]||'#999';return ' <span style=\"display:inline-block;font-size:10px;padding:1px 7px;border-radius:10px;background:'+c+'18;color:'+c+';border:1px solid '+c+'40;font-weight:500;\">'+n+'</span>';}
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 %}