// 干部管理系统 — PC 后台扩展模块（6 个原占位页的真实实现）
// 包含：考核管理 / 晋升管理 / 奖惩记录 / 人才九宫格 / 数据看板 / 系统设置
// 依赖 shared.jsx 暴露的 window.Icon / Avatar / Badge / CADRES / DEPARTMENTS / LEVELS / getStats / parseResume
// 通过 window.PC_MODULES 暴露给 pc-app.jsx 使用
(function () {
  "use strict";
  const { useState, useMemo, useEffect, useRef } = React;
  const Icon = window.Icon;
  const Avatar = window.Avatar;
  const Badge = window.Badge;
  const DEPARTMENTS = window.DEPARTMENTS;
  const LEVELS = window.LEVELS;
  const getStats = window.getStats;
  const parseResume = window.parseResume;

  // ============ 通用子组件 ============
  function PageHead({ title, sub, children }) {
    return (
      <div className="page-head">
        <div>
          <div className="page-title"><span className="accent"></span>{title}</div>
          {sub && <div className="page-sub">{sub}</div>}
        </div>
        {children && <div style={{ display: "flex", gap: 10 }}>{children}</div>}
      </div>
    );
  }

  function SectionCard({ title, icon, right, children, style }) {
    return (
      <div className="card" style={{ padding: 20, ...style }}>
        {(title || right) && (
          <div style={{ display: "flex", alignItems: "center", marginBottom: 16, gap: 8 }}>
            {icon && <Icon name={icon} />}
            {title && <h3 style={{ fontSize: 15, fontWeight: 600 }}>{title}</h3>}
            <div style={{ flex: 1 }}></div>
            {right}
          </div>
        )}
        {children}
      </div>
    );
  }

  function resultTone(result) {
    if (result === "优秀") return "green";
    if (result === "称职") return "blue";
    if (result === "基本称职") return "orange";
    if (result === "不称职") return "red";
    return "gray";
  }

  // =========================================================================
  // 1. 考核管理 AssessPage
  // =========================================================================
  function AssessPage({ cadres, onOpen }) {
    // 当前测评状态：按编号顺序前 16 名已测评、后 8 名待测评
    const withStatus = useMemo(
      () => cadres.map((c, i) => ({ ...c, _assessed: i < 16 })),
      [cadres]
    );
    const assessed = withStatus.filter((c) => c._assessed).length;
    const pending = withStatus.length - assessed;
    const rate = Math.round((assessed / withStatus.length) * 100);

    // 五维平均分（基于已测评对象的模拟分数）
    const dims = [
      { key: "德", desc: "政治品质与道德品行", score: 92 },
      { key: "能", desc: "业务能力与组织协调", score: 88 },
      { key: "勤", desc: "担当精神与工作作风", score: 90 },
      { key: "绩", desc: "工作实绩与突出成果", score: 85 },
      { key: "廉", desc: "廉洁自律与规矩意识", score: 95 },
    ];

    // 结果分布（基于上一年度考核）
    const distribution = useMemo(() => {
      const buckets = { 优秀: 0, 称职: 0, 基本称职: 0, 不称职: 0 };
      cadres.forEach((c) => {
        const last = c.assessment[0];
        if (last) buckets[last.result] = (buckets[last.result] || 0) + 1;
      });
      return buckets;
    }, [cadres]);

    const [deptFilter, setDeptFilter] = useState("全部");
    const filtered = withStatus.filter((c) => deptFilter === "全部" || c.dept === deptFilter);

    return (
      <div>
        <PageHead
          title="考核管理"
          sub="围绕「德、能、勤、绩、廉」开展年度与任期考核，支持测评邀请、多维打分与结果汇总"
        >
          <button className="btn"><Icon name="download" />导出结果</button>
          <button className="btn btn-primary"><Icon name="plus" />新建考核</button>
        </PageHead>

        {/* 核心指标 */}
        <div className="stat-grid">
          <div className="stat"><div className="ic r"><Icon name="users" /></div><div className="lbl">本期考核对象</div><div className="val">{cadres.length}<small>人</small></div><div className="delta">2026 年度 · 全员考核</div></div>
          <div className="stat"><div className="ic g"><Icon name="check" /></div><div className="lbl">已提交测评</div><div className="val">{assessed}<small>人</small></div><div className="delta">已完成率 <b style={{ color: "var(--success)" }}>{rate}%</b></div></div>
          <div className="stat"><div className="ic o"><Icon name="clock" /></div><div className="lbl">待测评</div><div className="val" style={{ color: pending ? "var(--warning)" : "var(--text1)" }}>{pending}<small>人</small></div><div className="delta">截止 <b>2026-07-15</b></div></div>
          <div className="stat"><div className="ic b"><Icon name="assessment" /></div><div className="lbl">上年度优秀率</div><div className="val">{Math.round((distribution.优秀 / cadres.length) * 100)}<small>%</small></div><div className="delta">优秀 <b>{distribution.优秀}</b> 人 · 称职 <b>{distribution.称职}</b> 人</div></div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1.4fr", gap: 18, alignItems: "start" }}>
          {/* 左：考核方案 + 五维评分 */}
          <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
            <SectionCard title="考核方案" icon="assessment">
              <div className="dl" style={{ marginBottom: 18 }}>
                <div className="dl-item"><div className="k">考核周期</div><div className="v">2026 年度</div></div>
                <div className="dl-item"><div className="k">考核类型</div><div className="v">年度考核</div></div>
                <div className="dl-item"><div className="k">起止时间</div><div className="v">2026-06-20 — 2026-07-15</div></div>
                <div className="dl-item"><div className="k">责任主体</div><div className="v">本单位组织部门</div></div>
                <div className="dl-item"><div className="k">测评方式</div><div className="v">上级评 / 互评 / 民主测评</div></div>
                <div className="dl-item"><div className="k">考核等级</div><div className="v">优秀 / 称职 / 基本称职 / 不称职</div></div>
              </div>
              <div className="progress"><div className="progress-bar" style={{ width: rate + "%" }}></div></div>
              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, color: "var(--text3)", marginTop: 6 }}>
                <span>已完成 {assessed} / {cadres.length}</span>
                <span>{rate}%</span>
              </div>
            </SectionCard>

            <SectionCard title="测评维度 · 五维平均" icon="grid">
              <div className="dim-grid">
                {dims.map((d) => (
                  <div key={d.key} className="dim-item">
                    <div className="dim-head">
                      <span className="dim-key">{d.key}</span>
                      <span className="dim-score">{d.score}<small>分</small></span>
                    </div>
                    <div className="dim-bar"><div style={{ width: d.score + "%" }}></div></div>
                    <div className="dim-desc">{d.desc}</div>
                  </div>
                ))}
              </div>
            </SectionCard>
          </div>

          {/* 右：测评对象列表 */}
          <div>
            <SectionCard
              title="测评对象"
              icon="users"
              right={
                <div className="select" style={{ padding: "5px 10px" }} onClick={(e) => {
                  const next = e.currentTarget.querySelector(".dp");
                  if (next) next.style.display = next.style.display === "block" ? "none" : "block";
                }}>
                  <Icon name="building" /><span>{deptFilter}</span><Icon name="chevronDown" size={13} />
                  <div className="dp" style={{ display: "none" }}>
                    {["全部", ...DEPARTMENTS].map((d) => (
                      <div key={d} onClick={(e) => { e.stopPropagation(); setDeptFilter(d); e.currentTarget.parentElement.style.display = "none"; }}>{d}</div>
                    ))}
                  </div>
                </div>
              }
              style={{ padding: 0 }}
            >
              <div className="table-wrap" style={{ border: "none", borderRadius: 0 }}>
                <table className="data">
                  <thead>
                    <tr>
                      <th>姓名 / 编号</th>
                      <th>部门 / 职务</th>
                      <th>上年度结果</th>
                      <th>本期状态</th>
                      <th style={{ width: 80 }}>操作</th>
                    </tr>
                  </thead>
                  <tbody>
                    {filtered.slice(0, 12).map((c) => (
                      <tr key={c.id} onClick={() => onOpen(c.id)}>
                        <td>
                          <div className="name-cell">
                            <Avatar cadre={c} size={34} />
                            <div><div className="nm">{c.name}</div><div className="iid">{c.id}</div></div>
                          </div>
                        </td>
                        <td><div>{c.dept}</div><div style={{ fontSize: 12, color: "var(--text3)" }}>{c.position}</div></td>
                        <td>{c.assessment[0] ? <Badge color={resultTone(c.assessment[0].result)}>{c.assessment[0].result}</Badge> : "—"}</td>
                        <td>{c._assessed ? <Badge color="green">已测评</Badge> : <Badge color="orange">待测评</Badge>}</td>
                        <td>
                          <div className="col-actions" onClick={(e) => e.stopPropagation()}>
                            <button className="mini-btn" title={c._assessed ? "查看" : "测评"} onClick={() => onOpen(c.id)}>
                              <Icon name={c._assessed ? "eye" : "edit"} />
                            </button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                <div className="pagination">
                  <div className="info">显示 1 - {Math.min(12, filtered.length)} 条 / 共 {filtered.length} 条</div>
                  <div className="pg-btns"><button className="active">1</button><button>2</button><button>›</button></div>
                </div>
              </div>
            </SectionCard>

            <SectionCard title="上年度结果分布" icon="chart" style={{ marginTop: 18 }}>
              <div className="dist-bars">
                {Object.entries(distribution).map(([k, v]) => {
                  const tone = resultTone(k);
                  const colors = { green: "var(--success)", blue: "var(--blue)", orange: "var(--warning)", red: "var(--danger)" };
                  return (
                    <div key={k} className="dist-row">
                      <span className="dist-lbl">{k}</span>
                      <div className="dist-track"><div className="dist-fill" style={{ width: (v / cadres.length) * 100 + "%", background: colors[tone] }}></div></div>
                      <span className="dist-num">{v}<small>人</small></span>
                    </div>
                  );
                })}
              </div>
            </SectionCard>
          </div>
        </div>
      </div>
    );
  }

  // =========================================================================
  // 2. 晋升管理 PromotionPage
  // =========================================================================
  const PROMOTION_STAGES = [
    { key: "recommend", label: "民主推荐", icon: "users" },
    { key: "inspect", label: "组织考察", icon: "shield" },
    { key: "decide", label: "讨论决定", icon: "briefcase" },
    { key: "public", label: "任前公示", icon: "bell" },
    { key: "appoint", label: "任职", icon: "check" },
  ];

  const PENDING_CASES = [
    {
      id: "PC2026001",
      cadreId: "C20260008",
      name: "郑文涛",
      avatar: "郑",
      gender: "男",
      from: "技术研发中心副主任 · 副处级",
      to: "技术研发中心主任 · 正处级",
      stage: "public",
      initiator: "组织部",
      submitTime: "2026-06-22",
      publicEnd: "2026-07-03",
      note: "民主推荐得票 87%，考察材料已完成。",
    },
    {
      id: "PC2026002",
      cadreId: "C20260011",
      name: "何静",
      avatar: "何",
      gender: "女",
      from: "党委办公室副主任 · 副处级",
      to: "党委办公室主任 · 正处级",
      stage: "decide",
      initiator: "党委办公室",
      submitTime: "2026-06-18",
      publicEnd: "—",
      note: "已完成组织考察，待党委会议讨论决定。",
    },
    {
      id: "PC2026003",
      cadreId: "C20260015",
      name: "韩雪",
      avatar: "韩",
      gender: "女",
      from: "组织部干部一处副处长 · 副科级",
      to: "组织部干部一处处长 · 正科级",
      stage: "inspect",
      initiator: "组织部",
      submitTime: "2026-06-25",
      publicEnd: "—",
      note: "民主推荐已完成，正在开展组织考察。",
    },
  ];

  const HISTORY_PROMOTIONS = [
    { id: "PH2026001", name: "秦海洋", avatar: "秦", gender: "男", from: "市场营销部副部长", to: "市场营销部部长", level: "副处级 → 正处级", date: "2026-05", dept: "市场营销部" },
    { id: "PH2026002", name: "吴永康", avatar: "吴", gender: "男", from: "安全生产部副部长", to: "安全生产部部长", level: "副处级 → 正处级", date: "2026-03", dept: "安全生产部" },
    { id: "PH2026003", name: "周敏", avatar: "周", gender: "女", from: "人力资源部薪酬主管", to: "人力资源部副部长", level: "正科级 → 副处级", date: "2026-01", dept: "人力资源部" },
    { id: "PH2025008", name: "陈志远", avatar: "陈", gender: "男", from: "综合管理部主任", to: "党委书记", level: "正处级", date: "2025-12", dept: "党委办公室" },
  ];

  function PromotionPage({ cadres, onOpen }) {
    const stageCounts = useMemo(() => {
      const m = { recommend: 0, inspect: 0, decide: 0, public: 0, appoint: 0 };
      PENDING_CASES.forEach((c) => { m[c.stage] = (m[c.stage] || 0) + 1; });
      return m;
    }, []);

    return (
      <div>
        <PageHead
          title="晋升管理"
          sub="管理干部提拔任用流程：民主推荐 → 组织考察 → 讨论决定 → 任前公示 → 任职"
        >
          <button className="btn"><Icon name="download" />导出名册</button>
          <button className="btn btn-primary"><Icon name="plus" />发起提拔</button>
        </PageHead>

        {/* 核心指标 */}
        <div className="stat-grid">
          <div className="stat"><div className="ic r"><Icon name="briefcase" /></div><div className="lbl">在办提拔</div><div className="val">{PENDING_CASES.length}<small>件</small></div><div className="delta">较上月 <b style={{ color: "var(--success)" }}>+1</b></div></div>
          <div className="stat"><div className="ic b"><Icon name="users" /></div><div className="lbl">民主推荐中</div><div className="val">{stageCounts.recommend + stageCounts.inspect}<small>件</small></div><div className="delta">推荐 / 考察阶段</div></div>
          <div className="stat"><div className="ic o"><Icon name="bell" /></div><div className="lbl">任前公示</div><div className="val" style={{ color: "var(--warning)" }}>{stageCounts.public}<small>件</small></div><div className="delta">最迟结束 <b>2026-07-03</b></div></div>
          <div className="stat"><div className="ic g"><Icon name="check" /></div><div className="lbl">本年已完成</div><div className="val">{HISTORY_PROMOTIONS.length}<small>件</small></div><div className="delta">2026 年累计任职</div></div>
        </div>

        {/* 流程总览 */}
        <SectionCard title="任用流程总览" icon="sync" style={{ marginBottom: 18 }}>
          <div className="pipeline">
            {PROMOTION_STAGES.map((s, i) => {
              const isPublic = s.key === "public";
              return (
                <React.Fragment key={s.key}>
                  <div className={"pipe-stage" + (isPublic ? " alert-stage" : "")}>
                    <div className="pipe-ic"><Icon name={s.icon} /></div>
                    <div className="pipe-label">{s.label}</div>
                    <div className="pipe-count">{stageCounts[s.key] || 0}<small> 件</small></div>
                  </div>
                  {i < PROMOTION_STAGES.length - 1 && <div className="pipe-arrow"><Icon name="chevronRight" /></div>}
                </React.Fragment>
              );
            })}
          </div>
        </SectionCard>

        {/* 在办案例 */}
        <SectionCard title="在办提拔案例" icon="briefcase" style={{ padding: 0, marginBottom: 18 }}>
          <div style={{ display: "flex", flexDirection: "column" }}>
            {PENDING_CASES.map((pc, idx) => {
              const stageIdx = PROMOTION_STAGES.findIndex((s) => s.key === pc.stage);
              return (
                <div key={pc.id} className="promo-case" style={{ borderBottom: idx < PENDING_CASES.length - 1 ? "1px solid var(--border-soft)" : "none" }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 14, flex: 1, minWidth: 0 }}>
                    <Avatar cadre={{ avatar: pc.avatar, gender: pc.gender }} size={48} />
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4, flexWrap: "wrap" }}>
                        <span style={{ fontSize: 15, fontWeight: 600 }}>{pc.name}</span>
                        <Badge color="blue">{pc.id}</Badge>
                        <span style={{ fontSize: 12, color: "var(--text3)" }}>发起于 {pc.submitTime}</span>
                      </div>
                      <div style={{ fontSize: 13, color: "var(--text2)", lineHeight: 1.7 }}>
                        <span style={{ color: "var(--text2)" }}>{pc.from}</span>
                        <Icon name="chevronRight" size={13} style={{ display: "inline-block", verticalAlign: "-2px", margin: "0 6px", color: "var(--text3)" }} />
                        <span style={{ color: "var(--red)", fontWeight: 600 }}>{pc.to}</span>
                      </div>
                      <div style={{ fontSize: 12.5, color: "var(--text3)", marginTop: 6, lineHeight: 1.6 }}>{pc.note}</div>
                    </div>
                  </div>
                  <div className="promo-stage-mini">
                    {PROMOTION_STAGES.map((s, i) => (
                      <div key={s.key} className={"ps-dot" + (i < stageIdx ? " done" : i === stageIdx ? " current" : "")} title={s.label}>
                        <span className="ps-num">{i < stageIdx ? "✓" : i + 1}</span>
                        <span className="ps-lbl">{s.label}</span>
                      </div>
                    ))}
                  </div>
                  <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 6, marginLeft: 14, flexShrink: 0 }}>
                    {pc.stage === "public" ? <Badge color="orange" solid>公示中</Badge> : pc.stage === "decide" ? <Badge color="blue" solid>待讨论</Badge> : <Badge color="gold">考察中</Badge>}
                    <button className="btn btn-sm" onClick={() => onOpen(pc.cadreId)}><Icon name="eye" />查看档案</button>
                  </div>
                </div>
              );
            })}
          </div>
        </SectionCard>

        {/* 历史任职记录 */}
        <SectionCard title="本年度任职记录" icon="history" style={{ padding: 0 }}>
          <div className="table-wrap" style={{ border: "none", borderRadius: 0 }}>
            <table className="data">
              <thead>
                <tr><th>姓名</th><th>原任职务</th><th>新任职务</th><th>职级变动</th><th>所属部门</th><th>任职时间</th><th style={{ width: 80 }}>操作</th></tr>
              </thead>
              <tbody>
                {HISTORY_PROMOTIONS.map((h) => (
                  <tr key={h.id} onClick={() => onOpen(cadres.find((c) => c.name === h.name)?.id)}>
                    <td><div className="name-cell"><Avatar cadre={{ avatar: h.avatar, gender: h.gender }} size={34} /><div className="nm">{h.name}</div></div></td>
                    <td>{h.from}</td>
                    <td><span style={{ color: "var(--red)", fontWeight: 600 }}>{h.to}</span></td>
                    <td><Badge color="blue">{h.level}</Badge></td>
                    <td>{h.dept}</td>
                    <td>{h.date}</td>
                    <td><div className="col-actions" onClick={(e) => e.stopPropagation()}><button className="mini-btn" title="查看"><Icon name="doc" /></button></div></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </SectionCard>
      </div>
    );
  }

  // =========================================================================
  // 3. 奖惩记录 RewardPage
  // =========================================================================
  function RewardPage({ cadres, onOpen }) {
    const [tab, setTab] = useState("all"); // all | reward | punish
    const [deptFilter, setDeptFilter] = useState("全部");

    // 拍平所有奖惩记录
    const records = useMemo(() => {
      const list = [];
      cadres.forEach((c) => {
        c.rewards.forEach((r) => list.push({
          cadreId: c.id, name: c.name, avatar: c.avatar, gender: c.gender,
          dept: c.dept, level: c.level, kind: "reward", title: r.title, org: r.org, type: r.type, date: r.date,
        }));
        c.punish.forEach((p) => list.push({
          cadreId: c.id, name: c.name, avatar: c.avatar, gender: c.gender,
          dept: c.dept, level: c.level, kind: "punish", title: p.title, org: p.org, type: p.type, date: p.date,
        }));
      });
      return list.sort((a, b) => (a.date < b.date ? 1 : -1));
    }, [cadres]);

    const stats = useMemo(() => {
      const rewards = records.filter((r) => r.kind === "reward");
      const punishes = records.filter((r) => r.kind === "punish");
      const thisYear = records.filter((r) => r.date.startsWith("2026") && r.kind === "reward").length;
      const pending = 1; // 工作台中的「陈志远 表彰确认」
      return { rewards: rewards.length, punishes: punishes.length, thisYear, pending };
    }, [records]);

    const filtered = records.filter((r) => {
      if (tab === "reward" && r.kind !== "reward") return false;
      if (tab === "punish" && r.kind !== "punish") return false;
      if (deptFilter !== "全部" && r.dept !== deptFilter) return false;
      return true;
    });

    // 按类型汇总
    const byType = useMemo(() => {
      const m = {};
      records.filter((r) => r.kind === "reward").forEach((r) => { m[r.type] = (m[r.type] || 0) + 1; });
      return Object.entries(m).sort((a, b) => b[1] - a[1]);
    }, [records]);

    return (
      <div>
        <PageHead
          title="奖惩记录"
          sub="记录干部荣誉表彰与处分惩戒，支持按类型、级别、部门多维统计"
        >
          <button className="btn"><Icon name="download" />导出</button>
          <button className="btn btn-primary"><Icon name="plus" />新增记录</button>
        </PageHead>

        <div className="stat-grid">
          <div className="stat"><div className="ic g"><Icon name="award" /></div><div className="lbl">累计表彰</div><div className="val" style={{ color: "var(--success)" }}>{stats.rewards}<small>人次</small></div><div className="delta">覆盖部门 <b>{new Set(records.filter((r) => r.kind === "reward").map((r) => r.dept)).size}</b> 个</div></div>
          <div className="stat"><div className="ic o"><Icon name="flag" /></div><div className="lbl">累计惩戒</div><div className="val" style={{ color: "var(--danger)" }}>{stats.punishes}<small>人次</small></div><div className="delta">通报批评 <b>{stats.punishes}</b> 例</div></div>
          <div className="stat"><div className="ic r"><Icon name="star" /></div><div className="lbl">本年度表彰</div><div className="val">{stats.thisYear}<small>人次</small></div><div className="delta">2026 年累计</div></div>
          <div className="stat"><div className="ic b"><Icon name="bell" /></div><div className="lbl">待确认</div><div className="val" style={{ color: stats.pending ? "var(--warning)" : "var(--text1)" }}>{stats.pending}<small>条</small></div><div className="delta">需您审核签批</div></div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 18, alignItems: "start" }}>
          {/* 左：记录表 */}
          <SectionCard title="奖惩台账" icon="history" style={{ padding: 0 }}>
            <div className="toolbar" style={{ padding: "12px 16px", margin: 0, borderBottom: "1px solid var(--border-soft)" }}>
              <div className="seg">
                {[["all", "全部"], ["reward", "表彰"], ["punish", "惩戒"]].map(([k, v]) => (
                  <button key={k} className={tab === k ? "active" : ""} onClick={() => setTab(k)}>{v}</button>
                ))}
              </div>
              <div className="select" onClick={(e) => {
                const dp = e.currentTarget.querySelector(".dp");
                if (dp) dp.style.display = dp.style.display === "block" ? "none" : "block";
              }}>
                <Icon name="building" /><span>{deptFilter}</span><Icon name="chevronDown" size={13} />
                <div className="dp" style={{ display: "none" }}>
                  {["全部", ...DEPARTMENTS].map((d) => (
                    <div key={d} onClick={(e) => { e.stopPropagation(); setDeptFilter(d); e.currentTarget.parentElement.style.display = "none"; }}>{d}</div>
                  ))}
                </div>
              </div>
              <div className="spacer"></div>
              <div style={{ fontSize: 12.5, color: "var(--text2)" }}>共 <b style={{ color: "var(--text1)" }}>{filtered.length}</b> 条</div>
            </div>
            <div className="table-wrap" style={{ border: "none", borderRadius: 0 }}>
              <table className="data">
                <thead>
                  <tr><th>姓名</th><th>类型</th><th>标题</th><th>颁授 / 决定单位</th><th>级别</th><th>日期</th></tr>
                </thead>
                <tbody>
                  {filtered.slice(0, 11).map((r, i) => (
                    <tr key={i} onClick={() => onOpen(r.cadreId)}>
                      <td><div className="name-cell"><Avatar cadre={{ avatar: r.avatar, gender: r.gender }} size={32} /><div><div className="nm">{r.name}</div><div className="iid">{r.dept}</div></div></div></td>
                      <td>{r.kind === "reward" ? <Badge color="green">表彰</Badge> : <Badge color="red">惩戒</Badge>}</td>
                      <td style={{ fontWeight: 500 }}>{r.title}</td>
                      <td>{r.org}</td>
                      <td><Badge color="gray">{r.type}</Badge></td>
                      <td>{r.date}</td>
                    </tr>
                  ))}
                  {filtered.length === 0 && (
                    <tr><td colSpan={6}><div className="empty"><Icon name="award" /><div>暂无符合条件的记录</div></div></td></tr>
                  )}
                </tbody>
              </table>
              <div className="pagination">
                <div className="info">第 1 - {Math.min(11, filtered.length)} 条 / 共 {filtered.length} 条</div>
                <div className="pg-btns"><button className="active">1</button>{filtered.length > 11 && <button>2</button>}</div>
              </div>
            </div>
          </SectionCard>

          {/* 右：按类型汇总 + 待确认 */}
          <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
            <SectionCard title="表彰类型分布" icon="chart">
              <div className="dist-bars">
                {byType.map(([k, v]) => (
                  <div key={k} className="dist-row">
                    <span className="dist-lbl">{k}</span>
                    <div className="dist-track"><div className="dist-fill" style={{ width: (v / stats.rewards) * 100 + "%", background: "var(--gold)" }}></div></div>
                    <span className="dist-num">{v}<small>次</small></span>
                  </div>
                ))}
              </div>
            </SectionCard>

            <SectionCard title="待您确认" icon="bell">
              <div className="record" style={{ padding: "8px 0" }}>
                <div className="ri" style={{ background: "var(--gold-light)", color: "var(--gold)" }}><Icon name="award" /></div>
                <div className="rc">
                  <div className="rt">陈志远 · 优秀党务工作者</div>
                  <div className="rs">颁授：市委 · 2025-07 · 荣誉表彰</div>
                </div>
                <div style={{ display: "flex", gap: 6 }}>
                  <button className="btn btn-sm btn-primary"><Icon name="check" />确认</button>
                </div>
              </div>
              <div className="alert info" style={{ marginTop: 14, marginBottom: 0 }}><Icon name="shield" />奖惩记录一旦确认即归入干部档案，不可随意修改。</div>
            </SectionCard>
          </div>
        </div>
      </div>
    );
  }

  // =========================================================================
  // 4. 人才九宫格 TalentPage
  // =========================================================================
  // 9 宫格区域定义：按 performance（X）+ potential（Y）三段映射
  // band: 4-5 = high, 3 = mid, 1-2 = low
  function band(score) { return score >= 4 ? "h" : score === 3 ? "m" : "l"; }

  const TALENT_ZONES = {
    // 行（Y=潜力）从高到低；列（X=业绩）从低到高
    "l-h": { label: "潜力股", tone: "blue", desc: "潜力突出，业绩待释放", action: "加压锻炼" },
    "m-h": { label: "明日之星", tone: "gold", desc: "中业绩高潜力，加速培养", action: "重点培养" },
    "h-h": { label: "明星", tone: "red", desc: "业绩潜力双高，核心骨干", action: "优先使用" },
    "l-m": { label: "待发展", tone: "gray", desc: "中潜力待提升业绩", action: "辅导提升" },
    "m-m": { label: "中坚力量", tone: "blue", desc: "稳定中等，常态关注", action: "持续激励" },
    "h-m": { label: "业绩骨干", tone: "green", desc: "高业绩中潜力", action: "发挥专长" },
    "l-l": { label: "需关注", tone: "orange", desc: "业绩潜力双低", action: "重点帮扶" },
    "m-l": { label: "稳定贡献", tone: "gray", desc: "经验丰富，平稳贡献", action: "保留经验" },
    "h-l": { label: "老黄牛", tone: "green", desc: "业绩扎实，潜力有限", action: "表彰肯定" },
  };

  function TalentPage({ cadres, onOpen }) {
    const [deptFilter, setDeptFilter] = useState("全部");
    const [selected, setSelected] = useState(null);

    const placed = useMemo(() => cadres
      .filter((c) => deptFilter === "全部" || c.dept === deptFilter)
      .map((c) => ({ ...c, _zone: band(c.performance) + "-" + band(c.potential) })), [cadres, deptFilter]);

    // 9 宫格渲染顺序：行从「高潜力」到「低潜力」，列从「低业绩」到「高业绩」
    const rows = [
      { y: "h", label: "高潜力" },
      { y: "m", label: "中潜力" },
      { y: "l", label: "低潜力" },
    ];
    const cols = [
      { x: "l", label: "低业绩" },
      { x: "m", label: "中业绩" },
      { x: "h", label: "高业绩" },
    ];

    return (
      <div>
        <PageHead
          title="人才九宫格"
          sub="以「业绩 × 潜力」呈现干部分布，辅助人才盘点与梯队建设决策"
        >
          <div className="select" onClick={(e) => {
            const dp = e.currentTarget.querySelector(".dp");
            if (dp) dp.style.display = dp.style.display === "block" ? "none" : "block";
          }}>
            <Icon name="building" /><span>{deptFilter}</span><Icon name="chevronDown" size={13} />
            <div className="dp" style={{ display: "none" }}>
              {["全部", ...DEPARTMENTS].map((d) => (
                <div key={d} onClick={(e) => { e.stopPropagation(); setDeptFilter(d); e.currentTarget.parentElement.style.display = "none"; }}>{d}</div>
              ))}
            </div>
          </div>
          <button className="btn"><Icon name="download" />导出盘点表</button>
        </PageHead>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 280px", gap: 18, alignItems: "start" }}>
          {/* 九宫格主区 */}
          <div className="card talent-board" style={{ padding: 22 }}>
            <div className="tb-grid">
              {/* 顶部 X 轴标签 */}
              <div className="tb-corner"></div>
              {cols.map((c) => <div key={"cx" + c.x} className="tb-axis">{c.label}</div>)}

              {/* 三行九宫 */}
              {rows.map((r) => (
                <React.Fragment key={"r" + r.y}>
                  <div className="tb-yaxis">{r.label}</div>
                  {cols.map((c) => {
                    const zoneKey = c.x + "-" + r.y;
                    const zone = TALENT_ZONES[zoneKey];
                    const group = placed.filter((p) => p._zone === zoneKey);
                    return (
                      <div
                        key={zoneKey}
                        className={"tb-cell tone-" + zone.tone}
                        onClick={() => setSelected({ zoneKey, zone, group })}
                      >
                        <div className="tb-zone-head">
                          <span className="tb-zone-label">{zone.label}</span>
                          <span className="tb-zone-num">{group.length}</span>
                        </div>
                        <div className="tb-avatars">
                          {group.slice(0, 8).map((p) => (
                            <div key={p.id} className="tb-avatar" title={p.name + " · " + p.position} onClick={(e) => { e.stopPropagation(); onOpen(p.id); }}>
                              <Avatar cadre={p} size={30} />
                            </div>
                          ))}
                          {group.length > 8 && <span className="tb-more">+{group.length - 8}</span>}
                          {group.length === 0 && <span className="tb-empty">—</span>}
                        </div>
                      </div>
                    );
                  })}
                </React.Fragment>
              ))}
            </div>
            <div className="alert info" style={{ marginTop: 16, marginBottom: 0 }}><Icon name="grid" />点击任意宫格查看该梯队干部列表；点击干部头像可进入档案详情。</div>
          </div>

          {/* 右侧：选中宫格详情 / 或默认说明 */}
          <div className="card" style={{ padding: 20, position: "sticky", top: 12 }}>
            {selected ? (
              <>
                <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                  <span className={"zone-tag tone-" + selected.zone.tone}>{selected.zone.label}</span>
                  <span style={{ fontSize: 12, color: "var(--text3)" }}>{selected.group.length} 人</span>
                </div>
                <div style={{ fontSize: 13, color: "var(--text2)", marginBottom: 14, lineHeight: 1.7 }}>{selected.zone.desc}</div>
                <div className="alert info" style={{ marginBottom: 16, fontSize: 12.5 }}><Icon name="trendUp" />建议策略：<b>{selected.zone.action}</b></div>
                <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                  {selected.group.map((p) => (
                    <div key={p.id} className="talent-person" onClick={() => onOpen(p.id)}>
                      <Avatar cadre={p} size={34} />
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 13.5, fontWeight: 600 }}>{p.name}</div>
                        <div style={{ fontSize: 12, color: "var(--text2)" }}>{p.dept} · {p.position}</div>
                      </div>
                      <Icon name="chevronRight" size={15} style={{ color: "var(--text3)" }} />
                    </div>
                  ))}
                  {selected.group.length === 0 && <div className="empty" style={{ padding: 30 }}><Icon name="users" /><div>该梯队暂无干部</div></div>}
                </div>
              </>
            ) : (
              <>
                <h3 style={{ fontSize: 15, fontWeight: 600, marginBottom: 14 }}>九宫格说明</h3>
                <div style={{ fontSize: 13, color: "var(--text2)", lineHeight: 1.8, marginBottom: 16 }}>
                  以「业绩」为横轴、「潜力」为纵轴，将干部分布到 9 个梯队宫格。业绩、潜力各按 5 分制由近三年考核结果与组织评价综合得出。
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                  {Object.values(TALENT_ZONES).filter((_, i) => [0, 2, 5].includes(i)).map((z) => (
                    <div key={z.label} style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <span className={"zone-tag tone-" + z.tone}>{z.label}</span>
                      <span style={{ fontSize: 12.5, color: "var(--text2)" }}>{z.desc}</span>
                    </div>
                  ))}
                </div>
              </>
            )}
          </div>
        </div>
      </div>
    );
  }

  // =========================================================================
  // 5. 数据看板 BoardPage
  // =========================================================================
  function BoardPage({ cadres, onOpen }) {
    const stats = useMemo(() => getStats(cadres), [cadres]);

    const ageBuckets = useMemo(() => {
      const ranges = [["≤35", 0], ["36-40", 0], ["41-45", 0], ["46-50", 0], [">50", 0]];
      cadres.forEach((c) => {
        if (c.age <= 35) ranges[0][1]++;
        else if (c.age <= 40) ranges[1][1]++;
        else if (c.age <= 45) ranges[2][1]++;
        else if (c.age <= 50) ranges[3][1]++;
        else ranges[4][1]++;
      });
      return ranges;
    }, [cadres]);

    const eduBuckets = useMemo(() => {
      const m = {};
      cadres.forEach((c) => { m[c.edu.level] = (m[c.edu.level] || 0) + 1; });
      return Object.entries(m).sort((a, b) => b[1] - a[1]);
    }, [cadres]);

    const deptBuckets = useMemo(() => {
      const m = {};
      cadres.forEach((c) => { m[c.dept] = (m[c.dept] || 0) + 1; });
      return Object.entries(m).sort((a, b) => b[1] - a[1]);
    }, [cadres]);

    const levelBuckets = useMemo(() => {
      const m = {};
      cadres.forEach((c) => { m[c.level] = (m[c.level] || 0) + 1; });
      return LEVELS.map((l) => [l, m[l] || 0]);
    }, [cadres]);

    const assessBuckets = useMemo(() => {
      const m = { 优秀: 0, 称职: 0, 基本称职: 0, 不称职: 0 };
      cadres.forEach((c) => { if (c.assessment[0]) m[c.assessment[0].result]++; });
      return m;
    }, [cadres]);

    // 梯队预警：年龄>50 且 潜力<=3
    const warnings = useMemo(() => cadres
      .filter((c) => (c.age > 50 && c.potential <= 3) || c.assessment[0]?.result === "基本称职")
      .slice(0, 6), [cadres]);

    const maxDept = Math.max(...deptBuckets.map((d) => d[1]));

    return (
      <div>
        <PageHead title="数据看板" sub="多维度干部数据可视化看板，覆盖结构、考核、流动、预警等关键指标">
          <div className="select" style={{ padding: "5px 10px" }}>
            <Icon name="calendar" /><span>2026 年度</span><Icon name="chevronDown" size={13} />
          </div>
          <button className="btn"><Icon name="refresh" />刷新</button>
        </PageHead>

        {/* 顶部 KPI */}
        <div className="stat-grid">
          <div className="stat"><div className="ic r"><Icon name="users" /></div><div className="lbl">在册干部</div><div className="val">{stats.total}<small>人</small></div><div className="delta">男 <b>{stats.male}</b> / 女 <b>{stats.female}</b></div></div>
          <div className="stat"><div className="ic b"><Icon name="flag" /></div><div className="lbl">中共党员</div><div className="val">{stats.party}<small>人</small></div><div className="delta">占比 <b>{Math.round(stats.party / stats.total * 100)}%</b> · 预备 {stats.probParty}</div></div>
          <div className="stat"><div className="ic g"><Icon name="book" /></div><div className="lbl">研究生及以上</div><div className="val">{stats.master}<small>人</small></div><div className="delta">含博士 <b>{stats.doctor}</b> 人 · 占比 <b>{Math.round(stats.master / stats.total * 100)}%</b></div></div>
          <div className="stat"><div className="ic o"><Icon name="user" /></div><div className="lbl">平均年龄</div><div className="val">{stats.avgAge}<small>岁</small></div><div className="delta">覆盖 <b>{deptBuckets.length}</b> 个部门</div></div>
        </div>

        {/* 图表区 */}
        <div className="board-grid">
          {/* 年龄分布 - 纵向条形图 */}
          <div className="card chart-card">
            <div className="chart-head"><h4><Icon name="chart" />年龄分布</h4><span className="chart-sub">单位：人</span></div>
            <div className="vbar-chart">
              {ageBuckets.map(([lbl, n]) => {
                const max = Math.max(...ageBuckets.map((b) => b[1]));
                return (
                  <div key={lbl} className="vbar-col">
                    <div className="vbar-val">{n}</div>
                    <div className="vbar-bar" style={{ height: (n / max) * 100 + "%" }}></div>
                    <div className="vbar-lbl">{lbl}</div>
                  </div>
                );
              })}
            </div>
          </div>

          {/* 学历结构 - 横条 */}
          <div className="card chart-card">
            <div className="chart-head"><h4><Icon name="book" />学历结构</h4><span className="chart-sub">{eduBuckets.length} 类</span></div>
            <div className="dist-bars">
              {eduBuckets.map(([lbl, n]) => (
                <div key={lbl} className="dist-row">
                  <span className="dist-lbl">{lbl.replace("研究生", "研")}</span>
                  <div className="dist-track"><div className="dist-fill" style={{ width: (n / stats.total) * 100 + "%", background: "var(--blue)" }}></div></div>
                  <span className="dist-num">{n}<small>人</small></span>
                </div>
              ))}
            </div>
          </div>

          {/* 职级分布 - 圆环 */}
          <div className="card chart-card">
            <div className="chart-head"><h4><Icon name="shield" />职级分布</h4></div>
            <div className="donut-row">
              <DonutChart data={levelBuckets} />
              <div className="donut-legend">
                {levelBuckets.map(([lbl, n], i) => (
                  <div key={lbl} className="legend-item">
                    <span className="legend-dot" style={{ background: DonutColors[i % DonutColors.length] }}></span>
                    <span className="legend-label">{lbl}</span>
                    <span className="legend-val">{n}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* 部门分布 - 横条 */}
          <div className="card chart-card">
            <div className="chart-head"><h4><Icon name="building" />部门人数分布</h4><span className="chart-sub">共 {deptBuckets.length} 个部门</span></div>
            <div className="dist-bars scroll-area" style={{ maxHeight: 220, overflowY: "auto" }}>
              {deptBuckets.map(([lbl, n]) => (
                <div key={lbl} className="dist-row">
                  <span className="dist-lbl">{lbl}</span>
                  <div className="dist-track"><div className="dist-fill" style={{ width: (n / maxDept) * 100 + "%", background: "var(--red)" }}></div></div>
                  <span className="dist-num">{n}</span>
                </div>
              ))}
            </div>
          </div>

          {/* 考核结果 - 圆环 */}
          <div className="card chart-card">
            <div className="chart-head"><h4><Icon name="assessment" />本年度考核结果</h4></div>
            <div className="donut-row">
              <DonutChart data={Object.entries(assessBuckets).filter(([, n]) => n > 0)} />
              <div className="donut-legend">
                {Object.entries(assessBuckets).filter(([, n]) => n > 0).map(([lbl, n], i) => (
                  <div key={lbl} className="legend-item">
                    <span className="legend-dot" style={{ background: AssessColors[lbl] }}></span>
                    <span className="legend-label">{lbl}</span>
                    <span className="legend-val">{n}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* 梯队预警 */}
          <div className="card chart-card alert-list">
            <div className="chart-head"><h4><Icon name="bell" />梯队预警</h4><span className="chart-sub">{warnings.length} 人关注</span></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {warnings.map((c) => (
                <div key={c.id} className="alert-row" onClick={() => onOpen(c.id)}>
                  <Avatar cadre={c} size={32} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600 }}>{c.name}</div>
                    <div style={{ fontSize: 12, color: "var(--text2)" }}>{c.dept} · {c.position}</div>
                  </div>
                  {c.age > 50 && <Badge color="orange">临近退休</Badge>}
                  {c.assessment[0]?.result === "基本称职" && <Badge color="red">考核预警</Badge>}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    );
  }

  const DonutColors = ["#005d30", "#0A3B24", "#16A34A", "#dbb000", "#6B7280"];
  const AssessColors = { 优秀: "#16A34A", 称职: "#0A3B24", 基本称职: "#D97706", 不称职: "#DC2626" };

  function DonutChart({ data }) {
    const total = data.reduce((s, [, n]) => s + n, 0) || 1;
    let acc = 0;
    const segs = data.map(([lbl, n], i) => {
      const start = (acc / total) * 360;
      acc += n;
      const end = (acc / total) * 360;
      return { start, end, color: AssessColors[lbl] || DonutColors[i % DonutColors.length], n };
    });
    const gradient = segs.map((s) => `${s.color} ${s.start}deg ${s.end}deg`).join(", ");
    return (
      <div className="donut" style={{ background: `conic-gradient(${gradient})` }}>
        <div className="donut-hole">
          <div className="donut-num">{total}</div>
          <div className="donut-unit">总人数</div>
        </div>
      </div>
    );
  }

  // =========================================================================
  // 6. 系统设置 SettingsPage
  // =========================================================================
  const SETTINGS_NAV = [
    { id: "dict", icon: "database", label: "字典管理" },
    { id: "role", icon: "shield", label: "角色权限" },
    { id: "log", icon: "history", label: "操作日志" },
    { id: "param", icon: "settings", label: "系统参数" },
  ];

  const DICT_DEPTS = DEPARTMENTS;
  const DICT_DICTS = {
    dept: { label: "部门字典", items: DICT_DEPTS.map((d, i) => ({ code: "D" + String(1001 + i), name: d, sort: i + 1 })) },
    level: { label: "职级字典", items: LEVELS.map((l, i) => ({ code: "L" + String(101 + i), name: l, sort: i + 1 })) },
    edu: { label: "学历字典", items: ["博士研究生", "硕士研究生", "大学本科", "大学专科", "其他"].map((l, i) => ({ code: "E" + String(101 + i), name: l, sort: i + 1 })) },
    nation: { label: "民族字典", items: ["汉族", "回族", "满族", "蒙古族", "藏族", "其他"].map((l, i) => ({ code: "N" + String(101 + i), name: l, sort: i + 1 })) },
  };

  const ROLES = [
    { id: "R01", name: "超级管理员", icon: "shield", tone: "red", desc: "系统全部权限，可管理组织架构、角色与所有干部档案", members: 1, names: "林海峰" },
    { id: "R02", name: "组织部管理员", icon: "briefcase", tone: "blue", desc: "管理干部全生命周期：花名册、考核、晋升、奖惩", members: 2, names: "王建华、韩雪" },
    { id: "R03", name: "部门管理员", icon: "building", tone: "green", desc: "仅可查看与本部门相关的干部花名册信息", members: 8, names: "各部门主任" },
    { id: "R04", name: "普通干部", icon: "user", tone: "gray", desc: "查看本人档案、考核结果与表彰记录", members: 24, names: "全员" },
  ];

  const PERMISSIONS = [
    "花名册查看", "花名册编辑", "数据导入", "考核管理", "晋升审批",
    "奖惩录入", "九宫格盘点", "数据看板", "操作日志", "系统设置",
  ];

  const ROLE_PERMS = {
    R01: PERMISSIONS.reduce((m, p) => (m[p] = true, m), {}),
    R02: Object.fromEntries(PERMISSIONS.map((p) => [p, !["操作日志", "系统设置"].includes(p)])),
    R03: Object.fromEntries(PERMISSIONS.map((p) => [p, ["花名册查看", "数据看板"].includes(p)])),
    R04: Object.fromEntries(PERMISSIONS.map((p) => [p, false])),
  };

  const AUDIT_LOGS = [
    { user: "林海峰", avatar: "林", action: "编辑干部信息", target: "陈志远 C20260001", ip: "10.18.2.31", time: "2026-06-29 09:32:14" },
    { user: "林海峰", avatar: "林", action: "数据导入", target: "朗新系统同步 · 11 条变动", ip: "10.18.2.31", time: "2026-06-29 09:14:08" },
    { user: "王建华", avatar: "王", action: "新增奖惩记录", target: "高芸 · 三八红旗手", ip: "10.18.2.55", time: "2026-06-28 16:08:42" },
    { user: "系统", avatar: "系", action: "自动同步任务", target: "朗新定时同步 · 增量", ip: "—", time: "2026-06-28 02:00:00" },
    { user: "林海峰", avatar: "林", action: "导出花名册", target: "全部门 24 条", ip: "10.18.2.31", time: "2026-06-27 14:45:21" },
    { user: "曹建国", avatar: "曹", action: "查看干部详情", target: "朱国强 C20260017", ip: "10.18.3.12", time: "2026-06-26 10:22:55" },
    { user: "韩雪", avatar: "韩", action: "发起晋升流程", target: "韩雪 · 副科长 → 处长", ip: "10.18.2.40", time: "2026-06-25 11:04:18" },
    { user: "林海峰", avatar: "林", action: "修改角色权限", target: "部门管理员 · R03", ip: "10.18.2.31", time: "2026-06-24 17:30:09" },
  ];

  function SettingsPage() {
    const [section, setSection] = useState("dict");
    const [dictTab, setDictTab] = useState("dept");

    return (
      <div>
        <PageHead title="系统设置" sub="组织架构、角色权限、数据字典、操作日志等系统级配置" />

        <div className="settings-layout">
          {/* 左侧二级导航 */}
          <div className="settings-nav">
            {SETTINGS_NAV.map((s) => (
              <button key={s.id} className={"sn-item" + (section === s.id ? " active" : "")} onClick={() => setSection(s.id)}>
                <Icon name={s.icon} />
                <span>{s.label}</span>
                <Icon name="chevronRight" size={14} className="sn-chev" />
              </button>
            ))}
            <div className="alert info" style={{ margin: "16px 4px 0", fontSize: 12 }}>
              <Icon name="shield" />所有配置改动均会记入操作日志，敏感操作需二级审批。
            </div>
          </div>

          {/* 右侧配置面板 */}
          <div className="settings-content">
            {/* 字典管理 */}
            {section === "dict" && (
              <div className="card" style={{ padding: 20 }}>
                <div className="tabs" style={{ marginBottom: 18 }}>
                  {Object.entries(DICT_DICTS).map(([k, v]) => (
                    <button key={k} className={"tab" + (dictTab === k ? " active" : "")} onClick={() => setDictTab(k)}>{v.label}</button>
                  ))}
                </div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                  <div style={{ fontSize: 13, color: "var(--text2)" }}>共 <b style={{ color: "var(--text1)" }}>{DICT_DICTS[dictTab].items.length}</b> 条字典项</div>
                  <button className="btn btn-primary btn-sm"><Icon name="plus" />新增字典项</button>
                </div>
                <div className="table-wrap">
                  <table className="data">
                    <thead><tr><th>编码</th><th>名称</th><th>排序</th><th>状态</th><th style={{ width: 120 }}>操作</th></tr></thead>
                    <tbody>
                      {DICT_DICTS[dictTab].items.map((it) => (
                        <tr key={it.code}>
                          <td style={{ fontFamily: "ui-monospace,monospace", color: "var(--text2)" }}>{it.code}</td>
                          <td style={{ fontWeight: 600 }}>{it.name}</td>
                          <td>{it.sort}</td>
                          <td><Badge color="green">启用</Badge></td>
                          <td><div className="col-actions"><button className="mini-btn" title="编辑"><Icon name="edit" /></button><button className="mini-btn" title="删除"><Icon name="close" /></button></div></td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            )}

            {/* 角色权限 */}
            {section === "role" && (
              <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
                <div className="role-grid">
                  {ROLES.map((r) => (
                    <div key={r.id} className="card role-card">
                      <div className={"role-ic tone-" + r.tone}><Icon name={r.icon} /></div>
                      <div style={{ flex: 1 }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
                          <span style={{ fontSize: 14.5, fontWeight: 600 }}>{r.name}</span>
                          <Badge color="gray">{r.id}</Badge>
                        </div>
                        <div style={{ fontSize: 12.5, color: "var(--text2)", lineHeight: 1.6, marginBottom: 8 }}>{r.desc}</div>
                        <div style={{ fontSize: 12, color: "var(--text3)" }}>已分配 <b style={{ color: "var(--text1)" }}>{r.members}</b> 人 · {r.names}</div>
                      </div>
                    </div>
                  ))}
                </div>

                <div className="card scroll-area" style={{ padding: 20, overflowX: "auto" }}>
                  <div style={{ display: "flex", alignItems: "center", marginBottom: 16 }}>
                    <h3 style={{ fontSize: 15, fontWeight: 600 }}>权限矩阵</h3>
                    <div style={{ flex: 1 }}></div>
                    <button className="btn btn-sm"><Icon name="edit" />编辑权限</button>
                  </div>
                  <table className="data perm-table">
                    <thead>
                      <tr>
                        <th style={{ minWidth: 160 }}>权限项</th>
                        {ROLES.map((r) => <th key={r.id}>{r.name}</th>)}
                      </tr>
                    </thead>
                    <tbody>
                      {PERMISSIONS.map((p) => (
                        <tr key={p}>
                          <td style={{ fontWeight: 500 }}>{p}</td>
                          {ROLES.map((r) => (
                            <td key={r.id} style={{ textAlign: "center" }}>
                              {ROLE_PERMS[r.id][p]
                                ? <span className="perm-yes"><Icon name="check" /></span>
                                : <span className="perm-no">—</span>}
                            </td>
                          ))}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            )}

            {/* 操作日志 */}
            {section === "log" && (
              <div className="card" style={{ padding: 0 }}>
                <div className="toolbar" style={{ padding: "12px 16px", margin: 0, borderBottom: "1px solid var(--border-soft)" }}>
                  <div className="search-box" style={{ width: 240 }}>
                    <Icon name="search" /><input placeholder="搜索用户 / 操作 / 对象" />
                  </div>
                  <div className="select" style={{ padding: "7px 12px" }}><Icon name="filter" /><span>全部操作</span><Icon name="chevronDown" size={13} /></div>
                  <div className="select" style={{ padding: "7px 12px" }}><Icon name="calendar" /><span>最近 7 天</span><Icon name="chevronDown" size={13} /></div>
                  <div className="spacer"></div>
                  <button className="btn btn-sm"><Icon name="download" />导出日志</button>
                </div>
                <div className="table-wrap" style={{ border: "none", borderRadius: 0 }}>
                  <table className="data">
                    <thead><tr><th>操作人</th><th>操作类型</th><th>操作对象</th><th>IP 地址</th><th>操作时间</th></tr></thead>
                    <tbody>
                      {AUDIT_LOGS.map((log, i) => (
                        <tr key={i}>
                          <td>
                            <div className="name-cell">
                              <div className="av-mini" style={{ background: log.user === "系统" ? "var(--text3)" : "linear-gradient(135deg,#005d30,#003d1f)" }}>{log.avatar}</div>
                              <div className="nm">{log.user}</div>
                            </div>
                          </td>
                          <td><Badge color={log.action.includes("删除") ? "red" : log.action.includes("导出") ? "gold" : "blue"}>{log.action}</Badge></td>
                          <td>{log.target}</td>
                          <td style={{ fontFamily: "ui-monospace,monospace", fontSize: 12.5, color: "var(--text2)" }}>{log.ip}</td>
                          <td style={{ color: "var(--text2)" }}>{log.time}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                  <div className="pagination">
                    <div className="info">第 1 - {AUDIT_LOGS.length} 条 / 共 248 条</div>
                    <div className="pg-btns"><button className="active">1</button><button>2</button><button>3</button><button>›</button></div>
                  </div>
                </div>
              </div>
            )}

            {/* 系统参数 */}
            {section === "param" && (
              <div className="card" style={{ padding: 24 }}>
                <div className="form-section" style={{ marginBottom: 26 }}>
                  <div className="fs-head"><Icon name="building" />组织信息<span className="line"></span></div>
                  <div className="form-grid">
                    <div className="field"><label>单位名称</label><input defaultValue="中共XX市委组织部" /></div>
                    <div className="field"><label>单位编码</label><input defaultValue="ORG-2025-001" /></div>
                    <div className="field"><label>联系人</label><input defaultValue="韩雪" /></div>
                    <div className="field"><label>联系电话</label><input defaultValue="139****6677" /></div>
                  </div>
                </div>
                <div className="form-section" style={{ marginBottom: 26 }}>
                  <div className="fs-head"><Icon name="sync" />数据同步<span className="line"></span></div>
                  <div className="form-grid">
                    <div className="field"><label>朗新同步频率</label>
                      <select defaultValue="每日 02:00"><option>每 6 小时</option><option>每日 02:00</option><option>每周日 02:00</option></select>
                    </div>
                    <div className="field"><label>同步范围</label>
                      <select defaultValue="全单位"><option>全单位</option><option>指定部门</option></select>
                    </div>
                    <div className="field"><label>失败重试次数</label><input type="number" defaultValue={3} /></div>
                    <div className="field"><label>下次同步时间</label><input defaultValue="2026-06-30 02:00" disabled /></div>
                  </div>
                </div>
                <div className="form-section" style={{ marginBottom: 26 }}>
                  <div className="fs-head"><Icon name="shield" />安全与留存<span className="line"></span></div>
                  <div className="form-grid">
                    <div className="field"><label>操作日志留存（天）</label><input type="number" defaultValue={365} /></div>
                    <div className="field"><label>档案变更审批</label>
                      <select defaultValue="二级审批"><option>无需审批</option><option>一级审批</option><option>二级审批</option></select>
                    </div>
                    <div className="field"><label>密码有效期（天）</label><input type="number" defaultValue={90} /></div>
                    <div className="field"><label>登录失败锁定</label>
                      <select defaultValue="5 次失败后"><option>3 次失败后</option><option>5 次失败后</option><option>不锁定</option></select>
                    </div>
                  </div>
                </div>
                <div className="form-foot" style={{ paddingLeft: 0, paddingRight: 0 }}>
                  <div className="alert info" style={{ flex: 1 }}><Icon name="bell" />参数修改即刻生效，敏感项需经超级管理员审批。</div>
                  <button className="btn">重置</button>
                  <button className="btn btn-primary"><Icon name="save" />保存配置</button>
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }

  // ============ 暴露到 window ============
  Object.assign(window, {
    PC_MODULES: { AssessPage, PromotionPage, RewardPage, TalentPage, BoardPage, SettingsPage },
  });
})();
