| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851 |
- const fs = require('fs');
- const path = require('path');
- const filePath = path.join(__dirname, 'admin.html');
- let html = fs.readFileSync(filePath, 'utf8');
- // ─── EXAM TEMPLATE PAGE HTML ───────────────────────────────────────────────
- const examPageHtml = `
- <div id="page-exam-template" class="page" style="padding:0;">
- <!-- Page Header -->
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;">
- <div>
- <div class="page-title">考试模版</div>
- <div class="page-subtitle">管理各类考试的模版配置,包含基本设置、考前配置、防作弊及证书颁发等。</div>
- </div>
- <span class="tag tag-blue" style="font-size:12px;padding:4px 12px;">唯一模版</span>
- </div>
- <!-- Top-level tabs: 开学考试 / 分级考试 / 应知应会 -->
- <div class="view-tabs" id="exam-top-tabs">
- <div class="view-tab active" onclick="switchExamTab('kaixue')">开学考试</div>
- <div class="view-tab" onclick="switchExamTab('fenji')">分级考试</div>
- <div class="view-tab" onclick="switchExamTab('yingzhi')">应知应会</div>
- </div>
- <!-- ══════════════════════════════════════════════════════════
- TAB 1: 开学考试
- ══════════════════════════════════════════════════════════ -->
- <div id="exam-tab-kaixue" class="exam-tab-panel" style="display:flex;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden;">
- <!-- Left sidebar nav -->
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" id="kaixue-nav-basic" onclick="switchExamSection('kaixue','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" id="kaixue-nav-preexam" onclick="switchExamSection('kaixue','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" id="kaixue-nav-cheat" onclick="switchExamSection('kaixue','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" id="kaixue-nav-cert" onclick="switchExamSection('kaixue','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <!-- Right content area -->
- <div style="flex:1;padding:24px;overflow-y:auto;max-height:calc(100vh - 200px);">
- <!-- 权限层级 + 每学年自动执行 (common header) -->
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px;">
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label">权限层级:</span>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-perm" value="school" checked> 校级(全校/指定范围)
- </label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-perm" value="college"> 院级(所属学院)
- </label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-perm" value="lab"> 实验室(自己负责)
- </label>
- </div>
- <div style="display:flex;align-items:center;gap:8px;">
- <label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label>
- <span class="form-hint">每学年自动按配置日期创建考试</span>
- </div>
- </div>
- <!-- 基本设置 section -->
- <div id="kaixue-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span>
- <input class="form-input" style="width:200px;" value="开学考试" disabled>
- <span class="form-hint">系统内置,不可更改</span>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">风险等级</span>
- <select class="form-input form-select" style="width:200px;">
- <option value="">请选择风险等级</option>
- <option>重大风险</option>
- <option>高风险</option>
- <option>中风险</option>
- <option>低风险</option>
- </select>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span>
- <input class="form-input" style="width:300px;" placeholder="请输入考试名称">
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">答卷次数</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-answer-cnt',-1)">-</button>
- <input id="kaixue-answer-cnt" type="number" class="form-input" style="width:60px;text-align:center;" value="2" min="1">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-answer-cnt',1)">+</button>
- </div>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;margin-left:8px;">
- <input type="radio" name="kaixue-answer-mode" value="limit" checked> 限制次数
- </label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-answer-mode" value="unlimited"> 无限制
- </label>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">显示共享</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- <span class="form-hint">开课共享,全程有学号信息不可匿名</span>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">启用</span>
- <label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考卷</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline btn-sm">选择试卷</button>
- <span class="tag tag-blue" style="display:inline-flex;align-items:center;gap:4px;">实验室安全基础知识<span onclick="this.parentElement.remove()" style="cursor:pointer;margin-left:2px;">×</span></span>
- </div>
- <span class="form-hint">建议按知识点选择覆盖本校安全要求的试卷</span>
- </div>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时间</span>
- <input type="date" class="form-input" style="width:150px;">
- <span style="color:var(--text-hint);font-size:13px;">至</span>
- <input type="date" class="form-input" style="width:150px;">
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时长</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-duration',-5)">-</button>
- <input id="kaixue-duration" type="number" class="form-input" style="width:70px;text-align:center;" value="60" min="5" step="5">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-duration',5)">+</button>
- <span style="font-size:13px;color:var(--text-secondary);">分钟</span>
- </div>
- <span class="form-hint">限制答卷最大时长</span>
- </div>
- <!-- 考试范围 -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考试范围</span>
- <div style="display:flex;flex-direction:column;gap:10px;flex:1;">
- <div style="display:flex;gap:16px;">
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-scope" value="all" checked onclick="setKaixueScope('all')"> 全校
- </label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-scope" value="specify" onclick="setKaixueScope('specify')"> 考试范围(指定)
- </label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;">
- <input type="radio" name="kaixue-scope" value="student" onclick="setKaixueScope('student')"> 指定学生
- </label>
- </div>
- <div id="kaixue-scope-table" style="display:none;">
- <div class="table-wrap" style="margin-bottom:8px;">
- <table>
- <thead><tr><th>学院</th><th>专业</th><th>角色</th><th>年级</th><th>操作</th></tr></thead>
- <tbody id="kaixue-scope-tbody">
- <tr><td colspan="5" style="text-align:center;color:var(--text-hint);">暂无数据,请添加</td></tr>
- </tbody>
- </table>
- </div>
- <button class="btn btn-outline btn-sm">+ 添加范围</button>
- </div>
- </div>
- </div>
- <!-- 用户类别 -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;">
- <input type="checkbox" id="kaixue-user-undergrad" checked onchange="updateKaixueHours()"> 新入学本科生(默认勾选)
- </label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;">
- <input type="checkbox" id="kaixue-user-postgrad" checked onchange="updateKaixueHours()"> 新入学研究生
- </label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;">
- <input type="checkbox" id="kaixue-user-staff" checked onchange="updateKaixueHours()"> 新入职教职工
- </label>
- </div>
- </div>
- <!-- 学时配置 -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span>
- <div style="flex:1;">
- <div class="table-wrap">
- <table>
- <thead><tr><th>用户类别</th><th>所需学时</th><th>备注</th></tr></thead>
- <tbody id="kaixue-hours-tbody">
- <tr><td>新入学本科生</td><td><input type="number" class="form-input" style="width:80px;" value="4" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- <tr><td>新入学研究生</td><td><input type="number" class="form-input" style="width:80px;" value="4" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- <tr><td>新入职教职工</td><td><input type="number" class="form-input" style="width:80px;" value="2" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div><!-- /flex col -->
- <div style="margin-top:24px;display:flex;gap:12px;">
- <button class="btn btn-primary">保存设置</button>
- <button class="btn btn-outline-gray">重置</button>
- </div>
- </div><!-- /kaixue-sec-basic -->
- <!-- 考前配置 section -->
- <div id="kaixue-sec-preexam" class="exam-section" style="display:none;">
- <div class="card-title">考前配置</div>
- <div style="display:flex;flex-direction:column;gap:20px;">
- <!-- 学时要求 -->
- <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
- <span class="form-label" style="width:80px;flex-shrink:0;">学时要求</span>
- <label class="toggle"><input type="checkbox" id="kaixue-credit-toggle" onchange="document.getElementById('kaixue-credit-detail').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- <div id="kaixue-credit-detail" style="display:none;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-credit-val',-1)">-</button>
- <input id="kaixue-credit-val" type="number" class="form-input" style="width:60px;text-align:center;" value="2" min="0">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('kaixue-credit-val',1)">+</button>
- <span style="font-size:13px;color:var(--text-secondary);">学时</span>
- <span class="form-hint">参加考试前需完成的最低学时数</span>
- </div>
- </div>
- <!-- 考前学习 -->
- <div style="display:flex;align-items:flex-start;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考前学习</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <label class="toggle"><input type="checkbox" id="kaixue-prestudy-toggle" onchange="document.getElementById('kaixue-prestudy-detail').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- <div id="kaixue-prestudy-detail" style="display:none;align-items:center;gap:8px;">
- <button class="btn btn-outline btn-sm">选择课程</button>
- <span class="tag tag-blue" style="display:inline-flex;align-items:center;gap:4px;">实验室安全基础课程<span onclick="this.parentElement.remove()" style="cursor:pointer;margin-left:2px;">×</span></span>
- </div>
- </div>
- </div>
- <!-- 模拟考试 -->
- <div style="display:flex;align-items:flex-start;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">模拟考试</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <label class="toggle"><input type="checkbox" id="kaixue-mock-toggle" onchange="document.getElementById('kaixue-mock-detail').style.display=this.checked?'block':'none'"><span class="toggle-slider"></span></label>
- <div id="kaixue-mock-detail" style="display:none;">
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
- <button class="btn btn-outline btn-sm">选择试卷</button>
- <span class="tag tag-gray" id="kaixue-mock-paper">未选择</span>
- </div>
- <div style="display:flex;gap:16px;font-size:12px;color:var(--text-hint);">
- <span>总题数:<strong style="color:var(--text-primary);">50</strong></span>
- <span>总分:<strong style="color:var(--text-primary);">100</strong></span>
- <span>及格分:<strong style="color:var(--green);">60</strong></span>
- </div>
- </div>
- </div>
- </div>
- <!-- 考试承诺书 -->
- <div style="display:flex;align-items:flex-start;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考试承诺书</span>
- <div style="display:flex;flex-direction:column;gap:8px;flex:1;">
- <label class="toggle"><input type="checkbox" id="kaixue-pledge-toggle" onchange="document.getElementById('kaixue-pledge-detail').style.display=this.checked?'block':'none'"><span class="toggle-slider"></span></label>
- <div id="kaixue-pledge-detail" style="display:none;">
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
- <span class="form-label">承诺书编辑</span>
- <label class="toggle"><input type="checkbox" onchange="document.getElementById('kaixue-pledge-editor').style.display=this.checked?'block':'none'"><span class="toggle-slider"></span></label>
- </div>
- <div id="kaixue-pledge-editor" style="display:none;">
- <div class="rich-editor">
- <div class="rich-toolbar">
- <button class="rich-tool-btn">B</button><button class="rich-tool-btn">I</button>
- <button class="rich-tool-btn">U</button><button class="rich-tool-btn">≡</button>
- <button class="rich-tool-btn">链接</button><button class="rich-tool-btn">图片</button>
- </div>
- <div class="rich-body" contenteditable="true">
- <p><strong>实验室安全承诺书</strong></p>
- <p>本人郑重承诺:在参加实验室安全考试及日常实验操作过程中,严格遵守实验室各项安全规章制度,认真执行安全操作规程,不擅自使用不熟悉的仪器设备,不私自改装或违规操作实验装置。发现安全隐患及时上报,如实反映实验情况,对违规行为承担相应法律及校规责任。</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;">
- <button class="btn btn-primary">保存设置</button>
- <button class="btn btn-outline-gray">重置</button>
- </div>
- </div><!-- /kaixue-sec-preexam -->
- <!-- 防作弊 section -->
- <div id="kaixue-sec-cheat" class="exam-section" style="display:none;">
- <div class="card-title">防作弊</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:100px;flex-shrink:0;">切屏限制</span>
- <label class="toggle"><input type="checkbox" id="kaixue-switchscreen" onchange="document.getElementById('kaixue-switchscreen-cnt-wrap').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- <div id="kaixue-switchscreen-cnt-wrap" style="display:none;align-items:center;gap:6px;">
- <span style="font-size:13px;color:var(--text-secondary);">切屏</span>
- <input type="number" class="form-input" style="width:60px;text-align:center;" value="3" min="1">
- <span style="font-size:13px;color:var(--text-secondary);">次后提交</span>
- </div>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:100px;flex-shrink:0;">随机题目</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:100px;flex-shrink:0;">随机选项</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:100px;flex-shrink:0;">人脸识别</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;">
- <button class="btn btn-primary">保存设置</button>
- <button class="btn btn-outline-gray">重置</button>
- </div>
- </div><!-- /kaixue-sec-cheat -->
- <!-- 获得证书 section -->
- <div id="kaixue-sec-cert" class="exam-section" style="display:none;">
- <div class="card-title">获得证书</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">颁发证书</span>
- <label class="toggle"><input type="checkbox" id="kaixue-cert-toggle" onchange="document.getElementById('kaixue-cert-tmpl').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- </div>
- <div id="kaixue-cert-tmpl" style="display:none;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">证书模板</span>
- <select class="form-input form-select" style="width:240px;">
- <option value="">请选择证书模板</option>
- <option>实验室安全教育证书(标准版)</option>
- <option>实验室安全教育证书(精英版)</option>
- </select>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;">
- <button class="btn btn-primary">保存设置</button>
- <button class="btn btn-outline-gray">重置</button>
- </div>
- </div><!-- /kaixue-sec-cert -->
- </div><!-- /right content -->
- </div><!-- /exam-tab-kaixue -->
- <!-- ══════════════════════════════════════════════════════════
- TAB 2: 分级考试
- ══════════════════════════════════════════════════════════ -->
- <div id="exam-tab-fenji" class="exam-tab-panel" style="display:none;">
- <!-- Grade sub-tabs -->
- <div class="view-tabs" id="fenji-grade-tabs" style="margin-bottom:0;padding:0 20px;background:var(--white);border:1px solid var(--gray-border);border-bottom:none;border-radius:var(--radius) var(--radius) 0 0;">
- <div class="view-tab active" onclick="switchGradeTab('g1')">Ⅰ级(重大风险)</div>
- <div class="view-tab" onclick="switchGradeTab('g2')">Ⅱ级(高风险)</div>
- <div class="view-tab" onclick="switchGradeTab('g3')">Ⅲ级(中风险)</div>
- <div class="view-tab" onclick="switchGradeTab('g4')">Ⅳ级(低风险)</div>
- </div>
- <!-- Each grade panel shares the same two-column layout. We generate g1-g4. -->
- <div id="fenji-grade-g1" class="fenji-grade-panel" style="display:flex;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:0 0 var(--radius) var(--radius);box-shadow:var(--shadow);overflow:hidden;">
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g1','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <div style="flex:1;padding:24px;overflow-y:auto;max-height:calc(100vh - 240px);">
- <!-- Common header -->
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px;">
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label">权限层级:</span>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="fenji-g1-perm" value="school" checked> 校级(全校/指定范围)</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="fenji-g1-perm" value="college"> 院级(所属学院)</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="fenji-g1-perm" value="lab"> 实验室(自己负责)</label>
- </div>
- <div style="display:flex;align-items:center;gap:8px;">
- <label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label>
- <span class="form-hint">每学年自动按配置日期创建考试</span>
- </div>
- </div>
- <!-- 基本设置 -->
- <div id="fenji-g1-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span><input class="form-input" style="width:200px;" value="Ⅰ级(重大风险)" disabled></div>
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span><input class="form-input" style="width:300px;" placeholder="请输入考试名称"></div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">答卷次数</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-ans',-1)">-</button>
- <input id="fenji-g1-ans" type="number" class="form-input" style="width:60px;text-align:center;" value="2" min="1">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-ans',1)">+</button>
- </div>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;margin-left:8px;"><input type="radio" name="fenji-g1-ans-mode" value="limit" checked> 限制次数</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="fenji-g1-ans-mode" value="unlimited"> 无限制</label>
- </div>
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">启用</span><label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考卷</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <div style="display:flex;align-items:center;gap:8px;"><button class="btn btn-outline btn-sm">选择试卷</button></div>
- <span class="form-hint">建议按知识点选择覆盖本校安全要求的试卷</span>
- </div>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时间</span>
- <input type="date" class="form-input" style="width:150px;"><span style="color:var(--text-hint);font-size:13px;">至</span><input type="date" class="form-input" style="width:150px;">
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时长</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-dur',-5)">-</button>
- <input id="fenji-g1-dur" type="number" class="form-input" style="width:70px;text-align:center;" value="60" min="5" step="5">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-dur',5)">+</button>
- <span style="font-size:13px;color:var(--text-secondary);">分钟</span>
- </div>
- <span class="form-hint">限制答卷最大时长</span>
- </div>
- <!-- 用户类别 (分级考试专用) -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 通过入学考试后绑定实验室的本科生</label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 绑定实验室的研究生</label>
- </div>
- </div>
- <!-- 学时配置 (分级考试) -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span>
- <div style="padding:10px 14px;background:var(--gray-light);border-radius:6px;font-size:13px;color:var(--text-secondary);">按公共配置的分级规则执行</div>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <!-- 考前配置 -->
- <div id="fenji-g1-sec-preexam" class="exam-section" style="display:none;">
- <div class="card-title">考前配置</div>
- <div style="display:flex;flex-direction:column;gap:20px;">
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">学时要求</span>
- <label class="toggle"><input type="checkbox" onchange="this.closest('.exam-section').querySelector('.credit-detail').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- <div class="credit-detail" style="display:none;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-credit',-1)">-</button>
- <input id="fenji-g1-credit" type="number" class="form-input" style="width:60px;text-align:center;" value="2" min="0">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('fenji-g1-credit',1)">+</button>
- <span style="font-size:13px;color:var(--text-secondary);">学时</span>
- </div>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考前学习</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">模拟考试</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试承诺书</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <!-- 防作弊 -->
- <div id="fenji-g1-sec-cheat" class="exam-section" style="display:none;">
- <div class="card-title">防作弊</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">切屏限制</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">随机题目</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">随机选项</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">人脸识别</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <!-- 获得证书 -->
- <div id="fenji-g1-sec-cert" class="exam-section" style="display:none;">
- <div class="card-title">获得证书</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">颁发证书</span>
- <label class="toggle"><input type="checkbox" onchange="this.closest('.exam-section').querySelector('.cert-tmpl-row').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label>
- </div>
- <div class="cert-tmpl-row" style="display:none;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">证书模板</span>
- <select class="form-input form-select" style="width:240px;"><option value="">请选择证书模板</option><option>实验室安全教育证书(标准版)</option></select>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- </div>
- </div><!-- /fenji-grade-g1 -->
- <!-- Grades g2, g3, g4 share identical structure, only IDs and type labels differ -->
- <div id="fenji-grade-g2" class="fenji-grade-panel" style="display:none;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:0 0 var(--radius) var(--radius);box-shadow:var(--shadow);overflow:hidden;flex-direction:row;">
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g2','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <div style="flex:1;padding:24px;">
- <div id="fenji-g2-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span><input class="form-input" style="width:200px;" value="Ⅱ级(高风险)" disabled></div>
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span><input class="form-input" style="width:300px;" placeholder="请输入考试名称"></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span><div style="display:flex;flex-direction:column;gap:8px;"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 通过入学考试后绑定实验室的本科生</label><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 绑定实验室的研究生</label></div></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span><div style="padding:10px 14px;background:var(--gray-light);border-radius:6px;font-size:13px;color:var(--text-secondary);">按公共配置的分级规则执行</div></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <div id="fenji-g2-sec-preexam" class="exam-section" style="display:none;"><div class="card-title">考前配置</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g2-sec-cheat" class="exam-section" style="display:none;"><div class="card-title">防作弊</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g2-sec-cert" class="exam-section" style="display:none;"><div class="card-title">获得证书</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- </div>
- </div><!-- /fenji-grade-g2 -->
- <div id="fenji-grade-g3" class="fenji-grade-panel" style="display:none;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:0 0 var(--radius) var(--radius);box-shadow:var(--shadow);overflow:hidden;flex-direction:row;">
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g3','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <div style="flex:1;padding:24px;">
- <div id="fenji-g3-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span><input class="form-input" style="width:200px;" value="Ⅲ级(中风险)" disabled></div>
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span><input class="form-input" style="width:300px;" placeholder="请输入考试名称"></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span><div style="display:flex;flex-direction:column;gap:8px;"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 通过入学考试后绑定实验室的本科生</label><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 绑定实验室的研究生</label></div></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span><div style="padding:10px 14px;background:var(--gray-light);border-radius:6px;font-size:13px;color:var(--text-secondary);">按公共配置的分级规则执行</div></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <div id="fenji-g3-sec-preexam" class="exam-section" style="display:none;"><div class="card-title">考前配置</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g3-sec-cheat" class="exam-section" style="display:none;"><div class="card-title">防作弊</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g3-sec-cert" class="exam-section" style="display:none;"><div class="card-title">获得证书</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- </div>
- </div><!-- /fenji-grade-g3 -->
- <div id="fenji-grade-g4" class="fenji-grade-panel" style="display:none;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:0 0 var(--radius) var(--radius);box-shadow:var(--shadow);overflow:hidden;flex-direction:row;">
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g4','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <div style="flex:1;padding:24px;">
- <div id="fenji-g4-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span><input class="form-input" style="width:200px;" value="Ⅳ级(低风险)" disabled></div>
- <div style="display:flex;align-items:center;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span><input class="form-input" style="width:300px;" placeholder="请输入考试名称"></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span><div style="display:flex;flex-direction:column;gap:8px;"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 通过入学考试后绑定实验室的本科生</label><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 绑定实验室的研究生</label></div></div>
- <div style="display:flex;align-items:flex-start;gap:16px;"><span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span><div style="padding:10px 14px;background:var(--gray-light);border-radius:6px;font-size:13px;color:var(--text-secondary);">按公共配置的分级规则执行</div></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <div id="fenji-g4-sec-preexam" class="exam-section" style="display:none;"><div class="card-title">考前配置</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g4-sec-cheat" class="exam-section" style="display:none;"><div class="card-title">防作弊</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- <div id="fenji-g4-sec-cert" class="exam-section" style="display:none;"><div class="card-title">获得证书</div><div style="color:var(--text-hint);font-size:13px;">(配置同Ⅰ级)</div><div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button></div></div>
- </div>
- </div><!-- /fenji-grade-g4 -->
- </div><!-- /exam-tab-fenji -->
- <!-- ══════════════════════════════════════════════════════════
- TAB 3: 应知应会
- ══════════════════════════════════════════════════════════ -->
- <div id="exam-tab-yingzhi" class="exam-tab-panel" style="display:none;gap:0;background:var(--white);border:1px solid var(--gray-border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden;flex-direction:row;">
- <div style="width:160px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:12px 0;">
- <div class="nav-item active" id="yingzhi-nav-basic" onclick="switchExamSection('yingzhi','basic')" style="font-size:13px;">基本设置</div>
- <div class="nav-item" id="yingzhi-nav-preexam" onclick="switchExamSection('yingzhi','preexam')" style="font-size:13px;">考前配置</div>
- <div class="nav-item" id="yingzhi-nav-cheat" onclick="switchExamSection('yingzhi','cheat')" style="font-size:13px;">防作弊</div>
- <div class="nav-item" id="yingzhi-nav-cert" onclick="switchExamSection('yingzhi','cert')" style="font-size:13px;">获得证书</div>
- </div>
- <div style="flex:1;padding:24px;overflow-y:auto;max-height:calc(100vh - 200px);">
- <!-- Common header -->
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px;">
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label">权限层级:</span>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="yingzhi-perm" value="school" checked> 校级(全校/指定范围)</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="yingzhi-perm" value="college"> 院级(所属学院)</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="yingzhi-perm" value="lab"> 实验室(自己负责)</label>
- </div>
- <div style="display:flex;align-items:center;gap:8px;">
- <label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label>
- <span class="form-hint">每学年自动按配置日期创建考试</span>
- </div>
- </div>
- <!-- 基本设置 -->
- <div id="yingzhi-sec-basic" class="exam-section">
- <div class="card-title">基本设置</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试类型</span>
- <input class="form-input" style="width:200px;" value="应知应会" disabled>
- <span class="form-hint">系统内置,不可更改</span>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试名称</span>
- <input class="form-input" style="width:300px;" placeholder="请输入考试名称">
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">答卷次数</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('yingzhi-ans',-1)">-</button>
- <input id="yingzhi-ans" type="number" class="form-input" style="width:60px;text-align:center;" value="2" min="1">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('yingzhi-ans',1)">+</button>
- </div>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;margin-left:8px;"><input type="radio" name="yingzhi-ans-mode" value="limit" checked> 限制次数</label>
- <label style="display:flex;align-items:center;gap:5px;cursor:pointer;font-size:13px;"><input type="radio" name="yingzhi-ans-mode" value="unlimited"> 无限制</label>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">显示共享</span>
- <label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label>
- <span class="form-hint">开课共享,全程有学号信息不可匿名</span>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">启用</span>
- <label class="toggle"><input type="checkbox" checked><span class="toggle-slider"></span></label>
- </div>
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">考卷</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <div style="display:flex;align-items:center;gap:8px;"><button class="btn btn-outline btn-sm">选择试卷</button></div>
- <span class="form-hint">建议按知识点选择覆盖本校安全要求的试卷</span>
- </div>
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时间</span>
- <input type="date" class="form-input" style="width:150px;"><span style="color:var(--text-hint);font-size:13px;">至</span><input type="date" class="form-input" style="width:150px;">
- </div>
- <div style="display:flex;align-items:center;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">考试时长</span>
- <div style="display:flex;align-items:center;gap:8px;">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('yingzhi-dur',-5)">-</button>
- <input id="yingzhi-dur" type="number" class="form-input" style="width:70px;text-align:center;" value="60" min="5" step="5">
- <button class="btn btn-outline-gray btn-sm" onclick="stepNum('yingzhi-dur',5)">+</button>
- <span style="font-size:13px;color:var(--text-secondary);">分钟</span>
- </div>
- <span class="form-hint">限制答卷最大时长</span>
- </div>
- <!-- 用户类别 (应知应会) -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">用户类别</span>
- <div style="display:flex;flex-direction:column;gap:8px;">
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 无需进入实验室的新入学研究生</label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 新入职教职工</label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;" title="按实验室分级取年度学时值,不可取消">
- <input type="checkbox" checked disabled style="opacity:.5;"> 在读研究生 <span class="tag tag-gray" style="font-size:11px;margin-left:4px;">按实验室分级取年度学时值</span>
- </label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 存量教职工</label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;"><input type="checkbox" checked> 在读本科生</label>
- </div>
- </div>
- <!-- 学时配置 (应知应会) -->
- <div style="display:flex;align-items:flex-start;gap:16px;">
- <span class="form-label" style="width:80px;flex-shrink:0;padding-top:4px;">学时配置</span>
- <div style="flex:1;">
- <div class="table-wrap">
- <table>
- <thead><tr><th>用户类别</th><th>所需学时</th><th>备注</th></tr></thead>
- <tbody>
- <tr><td>无需进入实验室的新入学研究生</td><td><input type="number" class="form-input" style="width:80px;" value="2" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- <tr><td>新入职教职工</td><td><input type="number" class="form-input" style="width:80px;" value="2" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- <tr style="background:var(--gray-light);color:var(--text-hint);">
- <td>在读研究生</td>
- <td><input type="number" class="form-input" style="width:80px;background:var(--gray-light);color:var(--text-hint);" disabled placeholder="按分级取值"></td>
- <td><span style="font-size:12px;">按实验室分级取年度学时值</span></td>
- </tr>
- <tr><td>存量教职工</td><td><input type="number" class="form-input" style="width:80px;" value="1" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- <tr><td>在读本科生</td><td><input type="number" class="form-input" style="width:80px;" value="1" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div><!-- /yingzhi-sec-basic -->
- <!-- 考前配置 -->
- <div id="yingzhi-sec-preexam" class="exam-section" style="display:none;">
- <div class="card-title">考前配置</div>
- <div style="display:flex;flex-direction:column;gap:20px;">
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:80px;flex-shrink:0;">学时要求</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:80px;flex-shrink:0;">考前学习</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:80px;flex-shrink:0;">模拟考试</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:80px;flex-shrink:0;">考试承诺书</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <!-- 防作弊 -->
- <div id="yingzhi-sec-cheat" class="exam-section" style="display:none;">
- <div class="card-title">防作弊</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">切屏限制</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">随机题目</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">随机选项</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:100px;flex-shrink:0;">人脸识别</span><label class="toggle"><input type="checkbox"><span class="toggle-slider"></span></label></div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- <!-- 获得证书 -->
- <div id="yingzhi-sec-cert" class="exam-section" style="display:none;">
- <div class="card-title">获得证书</div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div style="display:flex;align-items:center;gap:12px;"><span class="form-label" style="width:80px;flex-shrink:0;">颁发证书</span><label class="toggle"><input type="checkbox" onchange="document.getElementById('yingzhi-cert-tmpl').style.display=this.checked?'flex':'none'"><span class="toggle-slider"></span></label></div>
- <div id="yingzhi-cert-tmpl" style="display:none;align-items:center;gap:12px;">
- <span class="form-label" style="width:80px;flex-shrink:0;">证书模板</span>
- <select class="form-input form-select" style="width:240px;"><option value="">请选择证书模板</option><option>实验室安全教育证书(标准版)</option></select>
- </div>
- </div>
- <div style="margin-top:24px;display:flex;gap:12px;"><button class="btn btn-primary">保存设置</button><button class="btn btn-outline-gray">重置</button></div>
- </div>
- </div><!-- /right content yingzhi -->
- </div><!-- /exam-tab-yingzhi -->
- </div><!-- /page-exam-template -->
- `; // end examPageHtml
- // ─── JS FUNCTIONS TO INJECT ────────────────────────────────────────────────
- const examJsFunctions = `
- // ===== EXAM TEMPLATE PAGE =====
- function switchExamTab(tab) {
- document.querySelectorAll('.exam-tab-panel').forEach(function(p) { p.style.display = 'none'; });
- var panel = document.getElementById('exam-tab-' + tab);
- if (panel) {
- panel.style.display = tab === 'yingzhi' ? 'flex' : 'flex';
- if (tab === 'fenji') {
- // ensure flex for fenji sub-tab wrapper
- panel.style.display = 'block';
- }
- }
- document.querySelectorAll('#exam-top-tabs .view-tab').forEach(function(t) { t.classList.remove('active'); });
- var tabMap = { kaixue: 0, fenji: 1, yingzhi: 2 };
- var tabs = document.querySelectorAll('#exam-top-tabs .view-tab');
- if (tabs[tabMap[tab]]) tabs[tabMap[tab]].classList.add('active');
- }
- function switchExamSection(prefix, section) {
- // Hide all sections in this prefix's container
- var secs = document.querySelectorAll('#' + prefix + '-sec-basic, #' + prefix + '-sec-preexam, #' + prefix + '-sec-cheat, #' + prefix + '-sec-cert');
- secs.forEach(function(s) { s.style.display = 'none'; });
- var target = document.getElementById(prefix + '-sec-' + section);
- if (target) target.style.display = 'block';
- // Update nav active state - find nav items in same sidebar
- var secContainer = target && target.closest('[style*="overflow:hidden"]');
- if (secContainer) {
- secContainer.querySelectorAll('.nav-item').forEach(function(n) {
- n.classList.remove('active');
- var oc = n.getAttribute('onclick') || '';
- if (oc.includes("'" + section + "'")) n.classList.add('active');
- });
- }
- }
- function switchGradeTab(grade) {
- document.querySelectorAll('.fenji-grade-panel').forEach(function(p) { p.style.display = 'none'; });
- var panel = document.getElementById('fenji-grade-' + grade);
- if (panel) panel.style.display = 'flex';
- document.querySelectorAll('#fenji-grade-tabs .view-tab').forEach(function(t) { t.classList.remove('active'); });
- var gradeMap = { g1: 0, g2: 1, g3: 2, g4: 3 };
- var tabs = document.querySelectorAll('#fenji-grade-tabs .view-tab');
- if (tabs[gradeMap[grade]]) tabs[gradeMap[grade]].classList.add('active');
- }
- function setKaixueScope(mode) {
- document.getElementById('kaixue-scope-table').style.display = (mode === 'specify' || mode === 'student') ? 'block' : 'none';
- document.querySelectorAll('[name="kaixue-scope"]').forEach(function(r) {
- r.checked = (r.value === mode);
- });
- }
- function stepNum(id, delta) {
- var el = document.getElementById(id);
- if (!el) return;
- var val = (parseInt(el.value, 10) || 0) + delta;
- var min = parseInt(el.min, 10);
- if (!isNaN(min) && val < min) val = min;
- el.value = val;
- }
- function updateKaixueHours() {
- // Reflect checked user types in the hours table
- var tbody = document.getElementById('kaixue-hours-tbody');
- if (!tbody) return;
- var types = [
- { id: 'kaixue-user-undergrad', label: '新入学本科生', def: 4 },
- { id: 'kaixue-user-postgrad', label: '新入学研究生', def: 4 },
- { id: 'kaixue-user-staff', label: '新入职教职工', def: 2 }
- ];
- var rows = '';
- types.forEach(function(t) {
- var cb = document.getElementById(t.id);
- if (cb && cb.checked) {
- rows += '<tr><td>' + t.label + '</td><td><input type="number" class="form-input" style="width:80px;" value="' + t.def + '" min="0"></td><td><input class="form-input" placeholder="备注说明"></td></tr>';
- }
- });
- tbody.innerHTML = rows || '<tr><td colspan="3" style="text-align:center;color:var(--text-hint);">请先选择用户类别</td></tr>';
- }
- `; // end examJsFunctions
- // ─── PERFORM REPLACEMENTS ──────────────────────────────────────────────────
- const PLACEHOLDER = '<!-- EXAM TEMPLATE PAGE PLACEHOLDER -->';
- if (!html.includes(PLACEHOLDER)) {
- console.error('ERROR: Placeholder not found in admin.html');
- process.exit(1);
- }
- html = html.replace(PLACEHOLDER, examPageHtml);
- // Inject JS before closing </script> tag
- const SCRIPT_END = '</script>';
- const lastScriptEnd = html.lastIndexOf(SCRIPT_END);
- if (lastScriptEnd === -1) {
- console.error('ERROR: No closing </script> tag found');
- process.exit(1);
- }
- html = html.slice(0, lastScriptEnd) + examJsFunctions + '\n' + SCRIPT_END + html.slice(lastScriptEnd + SCRIPT_END.length);
- fs.writeFileSync(filePath, html, 'utf8');
- console.log('inject_exam.js: admin.html updated successfully.');
|