# -*- coding: utf-8 -*-
"""批次 B：新增「干部任免表」独立菜单（按会议列出已导入的 3.0 任免表）
   批次 C：任免表导入由演示向导改为真实上传（.lrmx → /api/admin/lrmx/import，多文件循环）"""
import shutil, time

A = '/data/www/files/rmsys-app/backend/src/Rmsys.Api/wwwroot/admin.html'
BK = time.strftime('%Y%m%d%H%M%S')
shutil.copy2(A, A + '.bakBC.' + BK)
s = open(A, encoding='utf-8').read()

# ---------- B1 侧栏菜单 ----------
anchor_nav = '''    <div class="sb-item" data-v="packages">'''
nav = '''    <div class="sb-item" data-v="forms">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/></svg>
      干部任免表
      <span class="badge" id="formBadge">0</span>
    </div>
'''
assert s.count(anchor_nav) == 1
s = s.replace(anchor_nav, nav + anchor_nav, 1)

# ---------- B2 标题映射 ----------
old_t = "var titles={meetings:'会议管理',depts:'处室维护',materials:'任免表及考察材料',packages:'数据包管理'"
new_t = "var titles={meetings:'会议管理',forms:'干部任免表',depts:'处室维护',materials:'任免表及考察材料',packages:'数据包管理'"
assert s.count(old_t) == 1
s = s.replace(old_t, new_t, 1)

# ---------- B3 视图分发 ----------
old_d = "  else if(v==='materials') renderMaterials();"
new_d = "  else if(v==='materials') renderMaterials();\n  else if(v==='forms') renderForms();"
assert s.count(old_d) == 1
s = s.replace(old_d, new_d, 1)

# ---------- B4 侧栏徽标 ----------
old_c = "  $('matBadge').textContent=CADRES.filter(function(c){ return meet().depts.length? true : true; }).length;"
new_c = old_c + "\n  if($('formBadge')) $('formBadge').textContent=CADRES.filter(function(c){ return !!matOf(c,'t30'); }).length;"
assert s.count(old_c) == 1
s = s.replace(old_c, new_c, 1)

# ---------- B5 renderForms ----------
anchor_f = "/* ===================== ② 任免表及考察材料 ===================== */"
forms_js = r'''/* ===================== ①B 干部任免表（独立菜单） =====================
   按会议列出「已导入的干部任免审批表 3.0 原件」，与「任免表及考察材料」共用同一份数据。 */
var FORM_Q='';
function formList(){
  var m=meet();
  var arr=CADRES.filter(function(c){ return m.depts.length ? (ROLE.dept==='all'||c.dept===ROLE.dept) : true; });
  if(FORM_Q) arr=arr.filter(function(c){ return ((c.name||'')+(c.cur||'')).indexOf(FORM_Q)>-1; });
  return arr;
}
function renderForms(){
  var m=meet(), h='';
  if(!m){ $('content').innerHTML='<div class="empty">请先在会议管理中创建会议</div>'; return; }
  var list=formList();
  var got=list.filter(function(c){ return !!matOf(c,'t30'); });
  var miss=list.filter(function(c){ return !matOf(c,'t30'); });
  h+='<div class="sec-note">本菜单只展示<b>本场会议已导入的干部任免审批表</b>（3.0 格式原件）。与「任免表及考察材料」是同一份数据，换版后旧版保留可追溯。</div>';
  h+='<div class="kpi-row">'
   + '<div class="kpi"><div class="kv">'+got.length+'</div><div class="kl">已导入任免表</div><div class="ks">本场会议 '+list.length+' 人</div></div>'
   + '<div class="kpi"><div class="kv">'+miss.length+'</div><div class="kl">尚未导入</div><div class="ks">'+(miss.length?'需补交原件':'全部齐备')+'</div></div>'
   + '<div class="kpi"><div class="kv" style="font-size:20px;">'+esc(m.name)+'</div><div class="kl">当前会议</div><div class="ks">'+typeOf(m.type).n+'</div></div>'
   + '</div>';
  h+='<div class="panel"><div class="panel-h"><h2>已导入的任免表</h2><div class="spacer"></div>'
   + '<button class="btn pri" onclick="wizImportForm()">任免表导入（3.0）</button>'
   + '<div class="searchbox"><input type="text" id="fq" placeholder="姓名 / 现任职务" value="'+esc(FORM_Q)+'" onkeydown="if(event.key===\'Enter\')doFormSearch()">'
   + '<button class="btn pri" onclick="doFormSearch()">查询</button>'
   + '<button class="btn" onclick="FORM_Q=\'\';renderForms();">重置</button></div></div><div class="panel-b">';
  h+='<div class="tbl-wrap"><table class="grid slim" style="min-width:920px;"><thead><tr>'
   + '<th class="opcell">操作</th><th>序号</th><th>姓名</th><th>所属处室</th><th>现任职务</th><th>拟任（免）职务</th>'
   + '<th>任免表原件</th><th>页数</th><th>上传人</th><th>上传时间</th>'
   + '</tr></thead><tbody>';
  if(!got.length) h+='<tr><td colspan="10"><div class="empty">本场会议还没有导入任免表，点右上角「任免表导入（3.0）」开始</div></td></tr>';
  got.forEach(function(c,i){
    var f=matOf(c,'t30');
    var prop = c.prop ? ('拟任 '+esc(c.prop)) : (c.dis ? ('拟免 '+esc(c.dis)) : '—');
    h+='<tr>'
     + opsCell([['预览','previewMat('+c.id+',\'t30\')','pri'],['下载','dlMat('+f.id+')'],['换版','uploadFor('+c.id+',\'t30\')']])
     + '<td>'+(i+1)+'</td><td class="nm">'+esc(c.name)+'</td><td>'+deptName(c.dept)+'</td>'
     + '<td>'+esc(c.cur||'—')+'</td><td>'+prop+'</td>'
     + '<td>'+esc(f.fileName||'')+' <span style="color:var(--ink3);font-size:11.5px;">'+esc(f.version||'')+'</span></td>'
     + '<td>'+(f.pages?(f.pages+' 页'):'—')+'</td><td>'+esc(f.uploadedBy||'—')+'</td><td>'+esc(f.uploadedAt||'—')+'</td>'
     + '</tr>';
  });
  h+='</tbody></table></div>';
  if(miss.length) h+='<div class="sec-note" style="margin-top:12px;">尚未导入（'+miss.length+' 人）：'+miss.map(function(c){ return esc(c.name); }).join('、')+'</div>';
  h+='</div></div>';
  $('content').innerHTML=h;
}
function doFormSearch(){ FORM_Q=($('fq').value||'').trim(); renderForms(); }

'''
assert s.count(anchor_f) == 1
s = s.replace(anchor_f, forms_js + anchor_f, 1)

# ---------- C1 任免表导入：真实实现 ----------
i1 = s.index("function wizImportForm(){")
i2 = s.index("function wizUpload(){", i1)
real_import = r'''function wizImportForm(){
  var m=meet();
  ensureAuth().then(function(ok){
    if(!ok) return;
    var h='<div class="modal-h"><h3>任免表导入（干部任免审批表 3.0）</h3><div class="spacer"></div><button class="x" onclick="closeModal()">&times;</button></div>';
    h+='<div class="modal-b">'
     + '<div class="sec-note">选择 <b>*.lrmx</b> 原件（可多选，一次导入多人）。系统按栏目全量解析：姓名、性别、出生年月、民族、籍贯、出生地、入党时间、参加工作时间、健康状况、专业技术职务、熟悉专业专长、全日制/在职学历学位、现任/拟任/拟免职务、奖惩、年度考核、任免理由、<b>简历逐段</b>、<b>家庭主要成员</b>、<b>照片</b>，并自动挂入本场会议上会名单。</div>'
     + '<div style="display:flex;gap:10px;align-items:center;margin:14px 0;">'
     + '<input type="file" id="lrmxFiles" accept=".lrmx" multiple style="flex:1;">'
     + '<button class="btn pri" onclick="doLrmxImport()">开始导入</button></div>'
     + '<div id="lrmxLog" style="max-height:38vh;overflow:auto;font-size:13.5px;line-height:1.95;"></div>'
     + '</div>';
    h+='<div class="modal-f"><span style="font-size:12.5px;color:var(--ink3);">同一人再次导入自动换版（v2、v3…），不会重复建人</span><div class="spacer"></div><button class="btn" onclick="closeModal()">关闭</button></div>';
    openModal(h, 'wide');
  });
}
function doLrmxImport(){
  var inp=document.getElementById('lrmxFiles'), log=document.getElementById('lrmxLog');
  if(!inp || !inp.files || !inp.files.length){ toast('请先选择 .lrmx 文件', 'wr'); return; }
  var files=[].slice.call(inp.files), m=meet(), i=0, okN=0, failN=0;
  log.innerHTML='';
  function step(){
    if(i>=files.length){
      log.innerHTML += '<div style="margin-top:10px;font-weight:700;">完成：成功 '+okN+' 个'+(failN?('，失败 '+failN+' 个'):'')+'</div>';
      toast('任免表导入完成：成功 '+okN+' 个'+(failN?('，失败 '+failN+' 个'):''), failN?'wr':'ok');
      bootstrap(true, true);
      return;
    }
    var f=files[i++];
    var fd=new FormData();
    fd.append('file', f); fd.append('meetingId', m.id); fd.append('dryRun', 0);
    var xhr=new XMLHttpRequest();
    xhr.open('POST', '/api/admin/lrmx/import');
    if(AUTH.token) xhr.setRequestHeader('Authorization', 'Bearer '+AUTH.token);
    log.innerHTML += '<div style="color:var(--ink2);">正在解析：'+esc(f.name)+' …</div>';
    log.scrollTop=log.scrollHeight;
    xhr.onload=function(){
      var d=null; try{ d=JSON.parse(xhr.responseText||'{}'); }catch(e){}
      if(xhr.status===401){ log.innerHTML+='<div style="color:var(--red);">登录已失效，请重新登录后重试</div>'; ensureAuth(); return; }
      if(d && d.ok){
        okN++;
        log.innerHTML += '<div style="color:var(--green);">✔ '+esc(f.name)+' → '+esc(d.message||'')
          + '｜'+(d.created?'新增':'更新')+'｜材料 '+esc(d.version||'')+'</div>';
      }else{
        failN++;
        log.innerHTML += '<div style="color:var(--red);">✘ '+esc(f.name)+' → '+esc((d&&d.message)||('HTTP '+xhr.status))+'</div>';
      }
      log.scrollTop=log.scrollHeight;
      step();
    };
    xhr.onerror=function(){
      failN++;
      log.innerHTML += '<div style="color:var(--red);">✘ '+esc(f.name)+' → 网络错误</div>';
      step();
    };
    xhr.send(fd);
  }
  step();
}
'''
s = s[:i1] + real_import + s[i2:]

open(A, 'w', encoding='utf-8').write(s)
print("✓ 批次B：菜单 + renderForms")
print("✓ 批次C：任免表导入真实实现")
print("备份后缀 .bakBC." + BK)
