| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=1280">
- <title>实验室安全教育与考试 — 管理后台</title>
- <style>
- *{box-sizing:border-box;margin:0;padding:0;}
- :root{
- --blue:#1857d4;--blue-deep:#0f3ea8;--blue-mid:#2e6fe0;--blue-light:#eef3fd;--blue-xlight:#f5f8ff;
- --green:#10a37f;--green-dark:#0d8f6f;--green-light:#edfaf6;
- --orange:#e67e22;--orange-light:#fef6ec;
- --red:#e53e3e;--red-light:#fff5f5;
- --gray:#8896a7;--gray-light:#f4f6fa;--gray-border:#dde3ed;
- --text-primary:#1a2233;--text-secondary:#4a5568;--text-hint:#8896a7;
- --bg:#f0f4fb;--white:#ffffff;
- --radius:8px;--shadow:0 2px 12px rgba(24,87,212,.08);--shadow-md:0 4px 20px rgba(24,87,212,.12);
- --sidebar-w:260px;--header-h:64px;
- }
- body{font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;background:var(--bg);color:var(--text-primary);font-size:15px;display:flex;flex-direction:column;height:100vh;overflow:hidden;}
- /* ===== HEADER ===== */
- .admin-header{height:var(--header-h);background:linear-gradient(135deg,#1857d4 0%,#2e6fe0 100%);display:flex;align-items:center;padding:0 28px;gap:20px;flex-shrink:0;z-index:200;box-shadow:0 2px 8px rgba(24,87,212,.2);}
- .header-logo{display:flex;align-items:center;gap:12px;color:#fff;font-size:17px;font-weight:700;letter-spacing:.3px;min-width:240px;}
- .header-logo-icon{width:36px;height:36px;background:rgba(255,255,255,.2);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:18px;}
- .header-tabs{display:flex;gap:4px;flex:1;}
- .header-tab{color:rgba(255,255,255,.75);font-size:14px;padding:7px 18px;border-radius:6px;cursor:pointer;transition:all .18s;font-weight:500;white-space:nowrap;}
- .header-tab:hover{color:#fff;background:rgba(255,255,255,.12);}
- .header-tab.active{color:#fff;background:rgba(255,255,255,.2);font-weight:600;}
- .header-right{display:flex;align-items:center;gap:14px;margin-left:auto;}
- .header-avatar{width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,.2);border:2px solid rgba(255,255,255,.35);display:flex;align-items:center;justify-content:center;font-size:15px;cursor:pointer;}
- .header-username{color:rgba(255,255,255,.9);font-size:14px;}
- /* ===== LAYOUT ===== */
- .admin-body{display:flex;flex:1;overflow:hidden;}
- .sidebar{width:var(--sidebar-w);background:var(--white);border-right:1px solid var(--gray-border);overflow-y:auto;flex-shrink:0;padding:16px 0;}
- .sidebar::-webkit-scrollbar{width:4px;}
- .sidebar::-webkit-scrollbar-thumb{background:rgba(24,87,212,.15);border-radius:2px;}
- .main-content{flex:1;overflow-y:auto;padding:32px 40px;}
- .main-content::-webkit-scrollbar{width:7px;}
- .main-content::-webkit-scrollbar-thumb{background:rgba(24,87,212,.15);border-radius:4px;}
- /* ===== SIDEBAR ===== */
- .nav-group{margin-bottom:6px;}
- .nav-group-label{font-size:11px;color:var(--text-hint);font-weight:600;letter-spacing:.8px;padding:10px 20px 4px;text-transform:uppercase;}
- .nav-item{display:flex;align-items:center;gap:10px;padding:10px 20px;cursor:pointer;color:var(--text-secondary);font-size:14px;font-weight:500;transition:all .15s;border-left:3px solid transparent;margin:1px 0;}
- .nav-item:hover{background:var(--blue-xlight);color:var(--blue);}
- .nav-item.active{background:var(--blue-light);color:var(--blue);border-left-color:var(--blue);font-weight:600;}
- .nav-item .nav-icon{font-size:16px;width:20px;text-align:center;}
- .nav-sub{padding-left:20px;}
- .nav-sub .nav-item{font-size:13px;padding:8px 16px;}
- /* ===== PAGE SYSTEM ===== */
- .page{display:none;}.page.active{display:block;}
- /* ===== BREADCRUMB ===== */
- .breadcrumb{display:flex;align-items:center;gap:6px;font-size:14px;color:var(--text-hint);margin-bottom:24px;}
- .breadcrumb a{color:var(--blue);cursor:pointer;text-decoration:none;}
- .breadcrumb a:hover{text-decoration:underline;}
- .breadcrumb-sep{color:var(--gray-border);}
- /* ===== PAGE HEADER ===== */
- .page-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:24px;}
- .page-title{font-size:22px;font-weight:700;color:var(--text-primary);}
- .page-subtitle{font-size:14px;color:var(--text-hint);margin-top:4px;}
- /* ===== CARDS ===== */
- .card{background:var(--white);border:1px solid var(--gray-border);border-radius:var(--radius);padding:24px;box-shadow:var(--shadow);}
- .card-title{font-size:16px;font-weight:700;color:var(--text-primary);display:flex;align-items:center;gap:8px;margin-bottom:18px;}
- .card-title::before{content:'';width:3px;height:16px;background:linear-gradient(180deg,var(--blue-mid),var(--blue-deep));border-radius:2px;display:inline-block;}
- /* ===== STAT BOXES ===== */
- .stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:24px;}
- .stat-box{background:var(--white);border:1px solid var(--gray-border);border-radius:var(--radius);padding:20px 24px;box-shadow:var(--shadow);}
- .stat-box-icon{font-size:32px;margin-bottom:10px;}
- .stat-box-val{font-size:32px;font-weight:700;color:var(--text-primary);line-height:1;}
- .stat-box-label{font-size:13px;color:var(--text-hint);margin-top:8px;}
- .stat-box.blue{border-top:3px solid var(--blue);}
- .stat-box.green{border-top:3px solid var(--green);}
- .stat-box.orange{border-top:3px solid var(--orange);}
- .stat-box.red{border-top:3px solid var(--red);}
- /* ===== TAGS ===== */
- .tag{display:inline-flex;align-items:center;padding:2px 9px;border-radius:20px;font-size:12px;font-weight:500;}
- .tag-blue{background:var(--blue-light);color:var(--blue);}
- .tag-green{background:var(--green-light);color:var(--green-dark);}
- .tag-orange{background:var(--orange-light);color:var(--orange);}
- .tag-red{background:var(--red-light);color:var(--red);}
- .tag-gray{background:var(--gray-light);color:var(--gray);}
- /* ===== BTNS ===== */
- .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;border:none;outline:none;transition:all .18s;padding:0 16px;height:36px;}
- .btn:active{opacity:.85;}
- .btn-primary{background:linear-gradient(135deg,var(--blue-mid) 0%,var(--blue-deep) 100%);color:#fff;box-shadow:0 2px 8px rgba(24,87,212,.25);}
- .btn-green{background:linear-gradient(135deg,#12b48a 0%,var(--green-dark) 100%);color:#fff;}
- .btn-outline{background:var(--white);color:var(--blue);border:1px solid rgba(24,87,212,.3);}
- .btn-outline-gray{background:var(--white);color:var(--text-secondary);border:1px solid var(--gray-border);}
- .btn-sm{height:30px;font-size:12px;padding:0 12px;border-radius:5px;}
- .btn-danger{background:var(--white);color:var(--red);border:1px solid rgba(229,62,62,.3);}
- .btn-icon{width:30px;height:30px;padding:0;border-radius:5px;}
- /* ===== TABLE ===== */
- .table-wrap{overflow-x:auto;border-radius:var(--radius);border:1px solid var(--gray-border);}
- table{width:100%;border-collapse:collapse;font-size:14px;}
- thead tr{background:var(--gray-light);}
- th{text-align:left;padding:12px 16px;color:var(--text-hint);font-weight:600;font-size:13px;border-bottom:1px solid var(--gray-border);white-space:nowrap;}
- td{padding:14px 16px;border-bottom:1px solid var(--gray-border);color:var(--text-primary);vertical-align:middle;}
- tbody tr:last-child td{border-bottom:none;}
- tbody tr:hover{background:var(--blue-xlight);}
- /* ===== FORM ===== */
- .form-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;}
- .form-grid.cols-1{grid-template-columns:1fr;}
- .form-grid.cols-3{grid-template-columns:1fr 1fr 1fr;}
- .form-item{display:flex;flex-direction:column;gap:7px;}
- .form-item.col-2{grid-column:span 2;}
- .form-label{font-size:14px;color:var(--text-secondary);font-weight:500;}
- .form-label.required::after{content:'*';color:var(--red);margin-left:3px;}
- .form-input{width:100%;border:1px solid var(--gray-border);border-radius:6px;padding:9px 14px;font-size:14px;color:var(--text-primary);background:var(--white);outline:none;transition:border-color .2s;}
- .form-input:focus{border-color:var(--blue);}
- textarea.form-input{min-height:110px;resize:vertical;line-height:1.6;}
- .form-select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238c8c8c' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;}
- .form-hint{font-size:12px;color:var(--text-hint);}
- /* ===== TOGGLE ===== */
- .toggle{position:relative;width:44px;height:24px;cursor:pointer;}
- .toggle input{opacity:0;width:0;height:0;}
- .toggle-slider{position:absolute;inset:0;background:#ccc;border-radius:24px;transition:.3s;}
- .toggle-slider::before{content:'';position:absolute;width:18px;height:18px;left:3px;top:3px;background:white;border-radius:50%;transition:.3s;}
- .toggle input:checked+.toggle-slider{background:var(--blue);}
- .toggle input:checked+.toggle-slider::before{transform:translateX(20px);}
- /* ===== SEARCH BAR ===== */
- .search-bar{display:flex;gap:10px;align-items:center;margin-bottom:20px;flex-wrap:wrap;}
- .search-input-wrap{position:relative;flex:1;min-width:240px;}
- .search-input-wrap .search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--text-hint);font-size:14px;}
- .search-input{width:100%;border:1px solid var(--gray-border);border-radius:6px;padding:8px 14px 8px 36px;font-size:14px;outline:none;background:var(--white);}
- .search-input:focus{border-color:var(--blue);}
- /* ===== PAGINATION ===== */
- .pagination{display:flex;align-items:center;gap:4px;margin-top:20px;justify-content:flex-end;}
- .page-btn{min-width:34px;height:34px;border-radius:5px;border:1px solid var(--gray-border);background:var(--white);cursor:pointer;font-size:13px;display:inline-flex;align-items:center;justify-content:center;color:var(--text-secondary);}
- .page-btn:hover{border-color:var(--blue);color:var(--blue);}
- .page-btn.active{background:var(--blue);color:#fff;border-color:var(--blue);}
- .page-info{font-size:13px;color:var(--text-hint);margin-left:10px;}
- /* ===== TABS ===== */
- .view-tabs{display:flex;gap:0;border-bottom:1px solid var(--gray-border);margin-bottom:24px;}
- .view-tab{padding:10px 20px;cursor:pointer;font-size:14px;color:var(--text-hint);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .15s;font-weight:500;}
- .view-tab.active{color:var(--blue);border-bottom-color:var(--blue);font-weight:600;}
- /* ===== DETAIL PANEL ===== */
- .detail-section{margin-bottom:28px;}
- .detail-section-title{font-size:13px;font-weight:600;color:var(--text-hint);text-transform:uppercase;letter-spacing:.6px;margin-bottom:14px;padding-bottom:8px;border-bottom:1px solid var(--gray-border);}
- .info-row{display:flex;padding:10px 0;border-bottom:1px solid var(--gray-border);}
- .info-row:last-child{border-bottom:none;}
- .info-key{width:130px;color:var(--text-hint);font-size:14px;flex-shrink:0;}
- .info-val{flex:1;font-size:14px;color:var(--text-primary);font-weight:500;}
- /* ===== UPLOAD AREA ===== */
- .upload-area{border:2px dashed var(--gray-border);border-radius:8px;padding:28px;text-align:center;cursor:pointer;transition:all .2s;background:var(--gray-light);}
- .upload-area:hover{border-color:var(--blue);background:var(--blue-xlight);}
- .upload-icon{font-size:36px;margin-bottom:10px;}
- .upload-text{font-size:14px;color:var(--text-hint);}
- /* ===== RICH TEXT PLACEHOLDER ===== */
- .rich-editor{border:1px solid var(--gray-border);border-radius:6px;overflow:hidden;}
- .rich-toolbar{background:var(--gray-light);padding:8px 14px;display:flex;gap:6px;border-bottom:1px solid var(--gray-border);flex-wrap:wrap;}
- .rich-tool-btn{background:var(--white);border:1px solid var(--gray-border);border-radius:4px;padding:3px 9px;font-size:13px;cursor:pointer;color:var(--text-secondary);}
- .rich-tool-btn:hover{background:var(--blue-light);color:var(--blue);border-color:rgba(24,87,212,.3);}
- .rich-body{min-height:130px;padding:14px;font-size:14px;color:var(--text-primary);outline:none;line-height:1.7;}
- /* ===== QR CODE ===== */
- .qr-box{width:80px;height:80px;background:var(--white);border:2px solid var(--gray-border);border-radius:8px;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:24px;cursor:pointer;transition:all .2s;}
- .qr-box:hover{border-color:var(--blue);box-shadow:0 2px 8px rgba(24,87,212,.15);}
- /* ===== ATTENDANCE ===== */
- .attend-row{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--gray-border);}
- .attend-row:last-child{border-bottom:none;}
- .attend-avatar{width:38px;height:38px;border-radius:50%;background:var(--blue-light);display:flex;align-items:center;justify-content:center;font-size:17px;flex-shrink:0;}
- .attend-info{flex:1;}
- .attend-status-yes{color:var(--green);font-size:12px;font-weight:600;}
- .attend-status-no{color:var(--red);font-size:12px;font-weight:600;}
- .attend-status-late{color:var(--orange);font-size:12px;font-weight:600;}
- /* ===== TRAINING EVENT CARD (PC version) ===== */
- .training-event-card{background:var(--white);border:1px solid var(--gray-border);border-radius:var(--radius);overflow:hidden;cursor:pointer;transition:all .2s;box-shadow:var(--shadow);}
- .training-event-card:hover{box-shadow:var(--shadow-md);border-color:rgba(24,87,212,.2);transform:translateY(-2px);}
- .training-event-cover{width:100%;height:160px;background:linear-gradient(135deg,#1857d4,#2e6fe0);display:flex;align-items:center;justify-content:center;font-size:42px;position:relative;overflow:hidden;}
- .training-event-body{padding:16px;}
- .training-event-title{font-size:15px;font-weight:600;color:var(--text-primary);margin-bottom:10px;line-height:1.4;}
- .training-event-meta{font-size:13px;color:var(--text-hint);display:flex;flex-direction:column;gap:5px;}
- .training-events-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;}
- /* ===== MODAL ===== */
- .modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:500;align-items:center;justify-content:center;padding:20px;}
- .modal-overlay.active{display:flex;}
- .modal-box{background:var(--white);border-radius:12px;width:100%;max-width:600px;max-height:90vh;overflow-y:auto;animation:modalIn .22s ease;box-shadow:0 8px 40px rgba(24,87,212,.18);}
- .modal-box.modal-lg{max-width:900px;}
- .modal-header{padding:22px 28px 18px;border-bottom:1px solid var(--gray-border);display:flex;align-items:center;justify-content:space-between;}
- .modal-title{font-size:17px;font-weight:700;color:var(--text-primary);}
- .modal-close{cursor:pointer;font-size:20px;color:var(--text-hint);background:none;border:none;line-height:1;padding:4px;}
- .modal-close:hover{color:var(--text-primary);}
- .modal-body{padding:24px 28px;}
- .modal-footer{padding:18px 28px;border-top:1px solid var(--gray-border);display:flex;align-items:center;justify-content:flex-end;gap:10px;}
- @keyframes modalIn{from{transform:scale(.93) translateY(10px);opacity:0;}to{transform:scale(1) translateY(0);opacity:1;}}
- /* ===== MISC ===== */
- .mt8{margin-top:8px;}.mt12{margin-top:12px;}.mt16{margin-top:16px;}.mt20{margin-top:20px;}
- .mb8{margin-bottom:8px;}.mb12{margin-bottom:12px;}.mb16{margin-bottom:16px;}
- .flex{display:flex;}.flex-col{flex-direction:column;}.items-center{align-items:center;}
- .justify-between{justify-content:space-between;}.gap8{gap:8px;}.gap12{gap:12px;}.gap16{gap:16px;}
- .text-sm{font-size:13px;}.text-xs{font-size:12px;}.text-bold{font-weight:600;}.text-gray{color:var(--gray);}
- .text-blue{color:var(--blue);}.text-green{color:var(--green);}.text-orange{color:var(--orange);}.text-red{color:var(--red);}
- .grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px;}
- .divider{height:1px;background:var(--gray-border);margin:20px 0;}
- .empty-state{text-align:center;padding:60px 20px;color:var(--text-hint);}
- .empty-icon{font-size:52px;margin-bottom:14px;}
- .dot{width:8px;height:8px;border-radius:50%;display:inline-block;}
- .dot-green{background:var(--green);}.dot-orange{background:var(--orange);}.dot-red{background:var(--red);}.dot-gray{background:#b0bec5;}
- .progress-wrap{background:#e8edf6;border-radius:4px;height:6px;overflow:hidden;margin-top:4px;}
- .progress-bar{height:100%;border-radius:4px;background:linear-gradient(90deg,var(--blue-mid),var(--blue));transition:width .4s;}
- /* ===== PUBLISH TOGGLE (table-safe) ===== */
- .pub-slider{position:absolute;inset:0;border-radius:24px;transition:.3s;cursor:pointer;}
- .pub-slider::before{content:'';position:absolute;width:18px;height:18px;left:3px;top:3px;background:white;border-radius:50%;transition:.3s;box-shadow:0 1px 3px rgba(0,0,0,.2);}
- .pub-on{background:var(--blue);}
- .pub-off{background:#ccc;}
- .pub-on::before{transform:translateX(20px);}
- </style>
- </head>
- <body>
- <!-- ===== HEADER ===== -->
- <div class="admin-header">
- <div class="header-logo">
- <div class="header-logo-icon">🔬</div>
- <span>实验室安全教育与考试</span>
- </div>
- <div class="header-right">
- <div style="color:rgba(255,255,255,.7);font-size:12px;">2026-07-31</div>
- <div class="header-username">管理员</div>
- <div class="header-avatar">👤</div>
- </div>
- </div>
- <!-- ===== BODY ===== -->
- <div class="admin-body">
- <!-- ===== SIDEBAR ===== -->
- <div class="sidebar" id="sidebar">
- <div class="nav-group">
- <div class="nav-group-label">培训管理</div>
- <div class="nav-item active" onclick="showPage('page-training-plan')"><span class="nav-icon">📋</span>培训计划</div>
- <div class="nav-item" onclick="showPage('page-training-record')"><span class="nav-icon">📁</span>培训记录</div>
- </div>
- <div class="nav-group">
- <div class="nav-group-label">培训活动</div>
- <div class="nav-item" onclick="showPage('page-training-activity-list')"><span class="nav-icon">📅</span>培训活动</div>
- </div>
- <div class="nav-group">
- <div class="nav-group-label">考试管理</div>
- <div class="nav-item" onclick="showPage('page-exam-template')"><span class="nav-icon">📋</span>考试模版</div>
- <div class="nav-item"><span class="nav-icon">📝</span>考试计划</div>
- <div class="nav-item"><span class="nav-icon">📊</span>考试记录</div>
- </div>
- <div class="nav-group">
- <div class="nav-group-label">用户管理</div>
- <div class="nav-item"><span class="nav-icon">👥</span>用户列表</div>
- </div>
- <div class="nav-group">
- <div class="nav-group-label">实验室管理</div>
- <div class="nav-item"><span class="nav-icon">🔬</span>实验室列表</div>
- </div>
- </div>
- <!-- ===== MAIN CONTENT ===== -->
- <div class="main-content">
- <!-- ==================== PAGE: 培训计划 ==================== -->
- <div class="page active" id="page-training-plan">
- <div class="breadcrumb"><span>培训管理</span><span class="breadcrumb-sep">/</span><span>培训计划</span></div>
- <div class="page-header">
- <div><div class="page-title">培训计划</div><div class="page-subtitle">管理所有培训活动的计划与发布状态</div></div>
- <button class="btn btn-primary" onclick="showPage('page-training-new')">➕ 新建培训</button>
- </div>
- <div class="search-bar">
- <div class="search-input-wrap"><span class="search-icon">🔍</span><input class="search-input" placeholder="搜索培训名称、主讲人..."></div>
- <select class="form-input form-select" style="width:130px;"><option>全部状态</option><option>进行中</option><option>即将开始</option><option>已结束</option></select>
- <select class="form-input form-select" style="width:130px;"><option>全部分类</option><option>知识讲座</option><option>应急演练</option></select>
- <input class="form-input" type="text" placeholder="组织单位" style="width:140px;">
- <div class="flex items-center gap8" style="flex-shrink:0;">
- <input class="form-input" type="date" style="width:150px;" title="开始日期">
- <span style="color:var(--text-hint);font-size:13px;">至</span>
- <input class="form-input" type="date" style="width:150px;" title="结束日期">
- </div>
- <button class="btn btn-outline">筛选</button>
- <button class="btn btn-outline-gray">重置</button>
- </div>
- <div id="plan-teacher-view">
- <div class="table-wrap">
- <table>
- <thead><tr><th>培训名称</th><th>分类</th><th>培训时间</th><th>组织单位</th><th>学时/积分</th><th>活动状态</th><th>签到人数</th><th>签到状态</th><th>发布</th><th>操作</th></tr></thead>
- <tbody>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">实验室生物安全操作规范培训</span></td>
- <td><span class="tag tag-blue">知识讲座</span></td>
- <td style="white-space:nowrap;">2026-08-01<br><span class="text-xs text-gray">10:00–12:00</span></td>
- <td>生命科学学院</td>
- <td><span class="text-green text-bold">2学时 +10分</span></td>
- <td><span class="tag tag-orange">进行中</span></td>
- <td><div><span class="text-bold text-blue">42</span> / 60</div><div class="progress-wrap" style="width:80px;margin-top:4px;"><div class="progress-bar" style="width:70%;"></div></div></td>
- <td><div class="flex" style="gap:4px;flex-wrap:wrap;"><span class="tag tag-green" style="font-size:10px;">已签到 42</span><span class="tag tag-red" style="font-size:10px;">未到 18</span></div></td>
- <td><div style="width:44px;height:24px;position:relative;cursor:pointer;"><input type="checkbox" checked style="opacity:0;width:0;height:0;position:absolute;"><div class="pub-slider pub-on"></div></div></td>
- <td><div class="flex gap8" style="flex-wrap:wrap;"><button class="btn btn-sm btn-outline" onclick="showModal('modal-qr')">📷 签到码</button><button class="btn btn-sm btn-outline" onclick="showModal('modal-progress')">📊 进度</button><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-new')">✏️ 编辑</button><button class="btn btn-sm btn-danger" onclick="showModal('modal-confirm-delete')">🗑 删除</button></div></td>
- </tr>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">化学品泄漏应急演练2026</span></td>
- <td><span class="tag tag-orange">应急演练</span></td>
- <td style="white-space:nowrap;">2026-08-05<br><span class="text-xs text-gray">14:00–17:00</span></td>
- <td>化学化工学院</td>
- <td><span class="text-green text-bold">3学时 +15分</span></td>
- <td><span class="tag tag-blue">即将开始</span></td>
- <td><div><span class="text-bold text-orange">0</span> / 50</div><div class="progress-wrap" style="width:80px;margin-top:4px;"><div class="progress-bar" style="width:0%;"></div></div></td>
- <td><span class="tag tag-gray" style="font-size:10px;">未开始</span></td>
- <td><div style="width:44px;height:24px;position:relative;cursor:pointer;"><input type="checkbox" style="opacity:0;width:0;height:0;position:absolute;"><div class="pub-slider pub-off"></div></div></td>
- <td><div class="flex gap8" style="flex-wrap:wrap;"><button class="btn btn-sm btn-outline" onclick="showModal('modal-qr')">📷 签到码</button><button class="btn btn-sm btn-outline" onclick="showModal('modal-progress')">📊 进度</button><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-new')">✏️ 编辑</button><button class="btn btn-sm btn-danger" onclick="showModal('modal-confirm-delete')">🗑 删除</button></div></td>
- </tr>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">辐射安全基础知识讲座</span></td>
- <td><span class="tag tag-blue">知识讲座</span></td>
- <td style="white-space:nowrap;">2026-07-20<br><span class="text-xs text-gray">14:00–16:00</span></td>
- <td>物理学院</td>
- <td><span class="text-green text-bold">2学时 +10分</span></td>
- <td><span class="tag tag-gray">已结束</span></td>
- <td><div><span class="text-bold text-green">55</span> / 60</div><div class="progress-wrap" style="width:80px;margin-top:4px;"><div class="progress-bar" style="width:92%;background:linear-gradient(90deg,var(--green),var(--green-dark));"></div></div></td>
- <td><div class="flex" style="gap:4px;flex-wrap:wrap;"><span class="tag tag-green" style="font-size:10px;">已签到 55</span><span class="tag tag-red" style="font-size:10px;">未到 5</span></div></td>
- <td><div style="width:44px;height:24px;position:relative;cursor:pointer;"><input type="checkbox" checked style="opacity:0;width:0;height:0;position:absolute;"><div class="pub-slider pub-on"></div></div></td>
- <td><div class="flex gap8" style="flex-wrap:wrap;"><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-record')">查看记录</button><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-new')">✏️ 编辑</button><button class="btn btn-sm btn-danger" onclick="showModal('modal-confirm-delete')">🗑 删除</button></div></td>
- </tr>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">全校实验室安全通识培训2026</span></td>
- <td><span class="tag tag-blue">知识讲座</span></td>
- <td style="white-space:nowrap;">2026-09-01<br><span class="text-xs text-gray">09:00–11:00</span></td>
- <td>测试大学</td>
- <td><span class="text-green text-bold">2学时 +10分</span></td>
- <td><span class="tag tag-blue">即将开始</span></td>
- <td><div><span class="text-bold text-gray">0</span> / —</div><div class="progress-wrap" style="width:80px;margin-top:4px;"><div class="progress-bar" style="width:0%;"></div></div></td>
- <td><span class="tag tag-gray" style="font-size:10px;">未开始</span></td>
- <td><div style="width:44px;height:24px;position:relative;cursor:pointer;"><input type="checkbox" style="opacity:0;width:0;height:0;position:absolute;"><div class="pub-slider pub-off"></div></div></td>
- <td><div class="flex gap8" style="flex-wrap:wrap;"><button class="btn btn-sm btn-outline" onclick="showModal('modal-qr')">📷 签到码</button><button class="btn btn-sm btn-outline" onclick="showModal('modal-progress')">📊 进度</button><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-new')">✏️ 编辑</button><button class="btn btn-sm btn-danger" onclick="showModal('modal-confirm-delete')">🗑 删除</button></div></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="pagination">
- <button class="page-btn">«</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">»</button>
- <span class="page-info">共 18 条</span>
- </div>
- </div>
- <!-- ==================== PAGE: 新建培训 ==================== -->
- <div class="page" id="page-training-new">
- <div class="breadcrumb"><span>培训管理</span><span class="breadcrumb-sep">/</span><span>新建培训</span></div>
- <div class="page-header">
- <div><div class="page-title">新建培训</div><div class="page-subtitle">填写培训活动信息</div></div>
- <div class="flex gap8">
- <button class="btn btn-outline-gray" onclick="showPage('page-training-plan')">取消</button>
- <button class="btn btn-primary">保存</button>
- </div>
- </div>
- <div class="card">
- <div class="card-title">基本信息</div>
- <div class="form-grid">
- <div class="form-item col-2">
- <label class="form-label required">活动名称</label>
- <input class="form-input" placeholder="请输入培训活动名称">
- </div>
- <div class="form-item">
- <label class="form-label required">活动分类</label>
- <select class="form-input form-select"><option value="">请选择</option><option>知识讲座</option><option>应急演练</option></select>
- </div>
- <div class="form-item">
- <label class="form-label required">组织单位</label>
- <input class="form-input" placeholder="请输入组织单位">
- </div>
- <div class="form-item">
- <label class="form-label required">培训开始时间</label>
- <input class="form-input" type="datetime-local" step="1">
- </div>
- <div class="form-item">
- <label class="form-label required">培训结束时间</label>
- <input class="form-input" type="datetime-local" step="1">
- </div>
- <div class="form-item">
- <label class="form-label required">主讲人</label>
- <input class="form-input" placeholder="请输入主讲人姓名">
- </div>
- <div class="form-item">
- <label class="form-label required">培训地点</label>
- <input class="form-input" placeholder="请输入培训地点">
- </div>
- <div class="form-item">
- <label class="form-label required">可得学时</label>
- <input class="form-input" type="number" placeholder="例:2" min="0.5" step="0.5">
- </div>
- <div class="form-item">
- <label class="form-label required">可得积分</label>
- <input class="form-input" type="number" placeholder="例:10" min="0" step="1">
- </div>
- <div class="form-item col-2">
- <label class="form-label required">培训范围</label>
- <div class="flex gap8" style="margin-bottom:10px;">
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;padding:7px 14px;border:1.5px solid var(--gray-border);border-radius:6px;font-size:13px;transition:all .15s;" id="scope-label-all" onclick="setScopeMode('all')">
- <input type="radio" name="training-scope" value="all" checked style="accent-color:var(--blue);"> 全校
- </label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;padding:7px 14px;border:1.5px solid var(--gray-border);border-radius:6px;font-size:13px;transition:all .15s;" id="scope-label-dept" onclick="setScopeMode('dept')">
- <input type="radio" name="training-scope" value="dept" style="accent-color:var(--blue);"> 指定范围
- </label>
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;padding:7px 14px;border:1.5px solid var(--gray-border);border-radius:6px;font-size:13px;transition:all .15s;" id="scope-label-person" onclick="setScopeMode('person')">
- <input type="radio" name="training-scope" value="person" style="accent-color:var(--blue);"> 指定人员
- </label>
- </div>
- <!-- 指定范围:院系/专业 -->
- <div id="scope-dept-section" style="display:none;padding:14px;background:var(--blue-xlight);border-radius:8px;border:1px solid rgba(24,87,212,.12);">
- <div style="font-size:12px;color:var(--text-hint);margin-bottom:10px;">选择参与的院系 / 单位(可多选)</div>
- <div style="display:flex;flex-wrap:wrap;gap:8px;">
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">生命科学学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">化学化工学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">物理学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">材料科学学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">医学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">环境科学学院</label>
- <label style="display:flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;padding:4px 10px;border:1px solid var(--gray-border);border-radius:20px;background:var(--white);"><input type="checkbox" style="accent-color:var(--blue);">安全管理处</label>
- </div>
- </div>
- <!-- 指定人员 -->
- <div id="scope-person-section" style="display:none;padding:14px;background:var(--blue-xlight);border-radius:8px;border:1px solid rgba(24,87,212,.12);">
- <div style="font-size:12px;color:var(--text-hint);margin-bottom:10px;">输入学号或姓名搜索添加,或批量导入</div>
- <div class="flex gap8" style="margin-bottom:10px;">
- <div class="search-input-wrap" style="flex:1;">
- <span class="search-icon">🔍</span>
- <input class="search-input" placeholder="搜索学号 / 姓名添加人员...">
- </div>
- <button class="btn btn-outline" style="white-space:nowrap;">📥 批量导入</button>
- </div>
- <div style="min-height:60px;border:1px dashed var(--gray-border);border-radius:6px;padding:10px;background:var(--white);">
- <div style="display:flex;flex-wrap:wrap;gap:6px;">
- <span style="display:inline-flex;align-items:center;gap:5px;background:var(--blue-light);color:var(--blue);border-radius:20px;padding:3px 10px;font-size:12px;">张明远 <span style="cursor:pointer;opacity:.6;" onclick="this.parentElement.remove()">✕</span></span>
- <span style="display:inline-flex;align-items:center;gap:5px;background:var(--blue-light);color:var(--blue);border-radius:20px;padding:3px 10px;font-size:12px;">李晓燕 <span style="cursor:pointer;opacity:.6;" onclick="this.parentElement.remove()">✕</span></span>
- <span style="font-size:12px;color:var(--text-hint);align-self:center;">已添加 2 人</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="divider"></div>
- <div class="card-title">封面图片</div>
- <div class="upload-area" style="max-width:400px;">
- <div class="upload-icon">🖼️</div>
- <div class="upload-text">点击或拖拽上传封面图<br><span style="font-size:11px;">推荐尺寸 16:9,支持 JPG / PNG,最大 5MB</span></div>
- </div>
- <div class="divider"></div>
- <div class="card-title">培训详情</div>
- <div class="rich-editor">
- <div class="rich-toolbar">
- <button class="rich-tool-btn">B</button><button class="rich-tool-btn"><i>I</i></button><button class="rich-tool-btn">U</button>
- <button class="rich-tool-btn">H1</button><button class="rich-tool-btn">H2</button>
- <button class="rich-tool-btn">≡</button><button class="rich-tool-btn">•</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">请输入培训详情内容,可包含培训目标、培训内容大纲、注意事项等...</div>
- </div>
- <div class="divider"></div>
- <div class="card-title">附件上传</div>
- <div class="upload-area">
- <div class="upload-icon">📎</div>
- <div class="upload-text">点击上传培训相关文件(PPT、PDF、Word等)<br><span style="font-size:11px;">支持 PDF / PPT / PPTX / DOC / DOCX,单文件最大 50MB</span></div>
- </div>
- <div class="divider"></div>
- <div style="display:flex;flex-direction:column;gap:16px;">
- <div class="form-item">
- <label class="form-label">发布状态</label>
- <div class="flex items-center gap8">
- <label class="toggle"><input type="checkbox" id="publish-toggle"><span class="toggle-slider"></span></label>
- <span style="font-size:13px;color:var(--text-secondary);">开启后培训学员可见</span>
- </div>
- </div>
- <div class="form-item">
- <label class="form-label">颁发证书</label>
- <div class="flex items-center gap8" style="margin-bottom:10px;">
- <label class="toggle"><input type="checkbox" id="cert-toggle" onchange="toggleCertTemplate(this)"><span class="toggle-slider"></span></label>
- <span style="font-size:13px;color:var(--text-secondary);">开启后完成培训的学员可获得培训证书</span>
- </div>
- <div id="cert-template-section" style="display:none;margin-top:8px;padding:14px;background:var(--blue-xlight);border-radius:8px;border:1px solid rgba(24,87,212,.12);">
- <label class="form-label" style="margin-bottom:8px;">证书模板</label>
- <select class="form-input form-select" style="max-width:360px;">
- <option value="">请选择证书模板</option>
- <option>实验室安全培训证书(通用)</option>
- <option>生物安全专项培训证书</option>
- <option>化学品安全培训证书</option>
- <option>应急演练参与证书</option>
- </select>
- <div class="form-hint" style="margin-top:6px;">证书将自动填入学员姓名、培训名称、培训日期及学时信息</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- ==================== PAGE: 培训记录 ==================== -->
- <div class="page" id="page-training-record">
- <div class="breadcrumb"><span>培训管理</span><span class="breadcrumb-sep">/</span><span>培训记录</span></div>
- <div class="page-header">
- <div><div class="page-title">培训记录</div><div class="page-subtitle">已结束培训的参与记录与证明</div></div>
- <button class="btn btn-outline">📤 导出记录</button>
- </div>
- <div class="search-bar">
- <div class="search-input-wrap"><span class="search-icon">🔍</span><input class="search-input" placeholder="搜索培训名称、学员姓名..."></div>
- <select class="form-input form-select" style="width:130px;"><option>全部分类</option><option>知识讲座</option><option>应急演练</option></select>
- <input class="form-input" type="month" style="width:160px;" value="2026-07">
- <button class="btn btn-outline">筛选</button>
- </div>
- <div class="card mb16">
- <div class="card-title">已结束培训列表</div>
- <div class="table-wrap">
- <table>
- <thead><tr><th>培训名称</th><th>分类</th><th>培训时间</th><th>主讲人</th><th>应到人数</th><th>实到人数</th><th>签到率</th><th>操作</th></tr></thead>
- <tbody>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showModal('modal-record-detail')">辐射安全基础知识讲座</span></td>
- <td><span class="tag tag-blue">知识讲座</span></td>
- <td style="white-space:nowrap;">2026-07-20<br><span class="text-xs text-gray">14:00–16:00</span></td>
- <td>陈教授</td>
- <td>60</td>
- <td><span class="text-bold text-green">55</span></td>
- <td>
- <div>91.7%</div>
- <div class="progress-wrap" style="width:80px;"><div class="progress-bar" style="width:92%;background:linear-gradient(90deg,var(--green),var(--green-dark));"></div></div>
- </td>
- <td><div class="flex gap8"><button class="btn btn-sm btn-outline" onclick="showModal('modal-record-detail')">查看详情</button><button class="btn btn-sm btn-outline-gray">导出</button></div></td>
- </tr>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showModal('modal-record-detail')">生物安全法规与合规操作</span></td>
- <td><span class="tag tag-blue">知识讲座</span></td>
- <td style="white-space:nowrap;">2026-07-10<br><span class="text-xs text-gray">09:00–11:00</span></td>
- <td>刘研究员</td>
- <td>45</td>
- <td><span class="text-bold text-green">43</span></td>
- <td>
- <div>95.6%</div>
- <div class="progress-wrap" style="width:80px;"><div class="progress-bar" style="width:96%;background:linear-gradient(90deg,var(--green),var(--green-dark));"></div></div>
- </td>
- <td><div class="flex gap8"><button class="btn btn-sm btn-outline" onclick="showModal('modal-record-detail')">查看详情</button><button class="btn btn-sm btn-outline-gray">导出</button></div></td>
- </tr>
- <tr>
- <td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showModal('modal-record-detail')">消防疏散应急演练(A区)</span></td>
- <td><span class="tag tag-orange">应急演练</span></td>
- <td style="white-space:nowrap;">2026-06-25<br><span class="text-xs text-gray">15:00–17:30</span></td>
- <td>安全部</td>
- <td>120</td>
- <td><span class="text-bold text-blue">98</span></td>
- <td>
- <div>81.7%</div>
- <div class="progress-wrap" style="width:80px;"><div class="progress-bar" style="width:82%;"></div></div>
- </td>
- <td><div class="flex gap8"><button class="btn btn-sm btn-outline" onclick="showModal('modal-record-detail')">查看详情</button><button class="btn btn-sm btn-outline-gray">导出</button></div></td>
- </tr>
- </tbody>
- </table>
- </div>
- <div class="pagination">
- <button class="page-btn">«</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">»</button>
- <span class="page-info">共 9 条</span>
- </div>
- </div>
- </div>
- <!-- PAGE: 培训活动列表 -->
- <div class="page" id="page-training-activity-list">
- <div class="breadcrumb"><span>培训活动</span></div>
- <div class="page-header">
- <div><div class="page-title">培训活动</div><div class="page-subtitle">全部培训活动列表</div></div>
- <button class="btn btn-primary" onclick="showPage('page-training-new');switchMenu('training-mgmt')">+ 新建培训</button>
- </div>
- <div class="search-bar">
- <div class="search-input-wrap"><span class="search-icon">🔍</span><input class="search-input" placeholder="搜索培训名称、主讲人..."></div>
- <select class="form-input form-select" style="width:130px;"><option>全部状态</option><option>进行中</option><option>即将开始</option><option>报名中</option><option>已结束</option></select>
- <select class="form-input form-select" style="width:130px;"><option>全部分类</option><option>知识讲座</option><option>应急演练</option></select>
- <button class="btn btn-outline">筛选</button>
- <div style="margin-left:auto;display:flex;gap:8px;">
- <button class="btn btn-outline-gray" onclick="setListView('grid')">卡片视图</button>
- <button class="btn btn-outline-gray" onclick="setListView('list')">列表视图</button>
- </div>
- </div>
- <div id="activity-grid-view" class="training-events-grid">
- <div class="training-event-card" onclick="showPage('page-training-activity-detail')">
- <div class="training-event-cover" style="background:linear-gradient(135deg,#1857d4,#2e6fe0);">🧪<div style="position:absolute;top:10px;left:10px;"><span class="tag tag-orange" style="background:rgba(230,126,34,.9);color:#fff;">进行中</span></div><div style="position:absolute;bottom:10px;right:10px;background:rgba(255,255,255,.15);border-radius:6px;padding:4px 8px;font-size:11px;color:rgba(255,255,255,.9);">2学时</div></div>
- <div class="training-event-body"><div class="training-event-title">实验室生物安全操作规范培训</div><div class="training-event-meta"><div>2026-08-01 10:00-12:00</div><div>生命科学楼 B206</div><div class="flex items-center gap8 mt8"><span class="tag tag-blue">知识讲座</span><span class="text-xs text-gray">42/60人</span><span class="text-xs text-green">+2学时+10积分</span></div></div></div>
- </div>
- <div class="training-event-card" onclick="showPage('page-training-activity-detail')">
- <div class="training-event-cover" style="background:linear-gradient(135deg,#e67e22,#f39c12);">🚚<div style="position:absolute;top:10px;left:10px;"><span class="tag" style="background:rgba(229,62,62,.9);color:#fff;">即将开始</span></div><div style="position:absolute;bottom:10px;right:10px;background:rgba(255,255,255,.15);border-radius:6px;padding:4px 8px;font-size:11px;color:rgba(255,255,255,.9);">3学时</div></div>
- <div class="training-event-body"><div class="training-event-title">化学品泄漏应急演练2026</div><div class="training-event-meta"><div>2026-08-05 14:00-17:00</div><div>化学实验楼 A101</div><div class="flex items-center gap8 mt8"><span class="tag tag-orange">应急演练</span><span class="text-xs text-gray">28/50人</span><span class="text-xs text-green">+3学时+15积分</span></div></div></div>
- </div>
- <div class="training-event-card" onclick="showPage('page-training-activity-detail')">
- <div class="training-event-cover" style="background:linear-gradient(135deg,#10a37f,#0d8f6f);">⚡<div style="position:absolute;top:10px;left:10px;"><span class="tag tag-green" style="background:rgba(16,163,127,.9);color:#fff;">报名中</span></div><div style="position:absolute;bottom:10px;right:10px;background:rgba(255,255,255,.15);border-radius:6px;padding:4px 8px;font-size:11px;color:rgba(255,255,255,.9);">1.5学时</div></div>
- <div class="training-event-body"><div class="training-event-title">实验室用电安全与消防知识讲座</div><div class="training-event-meta"><div>2026-08-10 09:30-11:00</div><div>综合楼 3F 多功能厅</div><div class="flex items-center gap8 mt8"><span class="tag tag-blue">知识讲座</span><span class="text-xs text-gray">15/80人</span><span class="text-xs text-green">+1.5学时+8积分</span></div></div></div>
- </div>
- <div class="training-event-card" onclick="showPage('page-training-activity-detail')">
- <div class="training-event-cover" style="background:linear-gradient(135deg,#6f42c1,#5a35a0);">☢<div style="position:absolute;top:10px;left:10px;"><span class="tag tag-gray" style="background:rgba(136,150,167,.9);color:#fff;">已结束</span></div><div style="position:absolute;bottom:10px;right:10px;background:rgba(255,255,255,.15);border-radius:6px;padding:4px 8px;font-size:11px;color:rgba(255,255,255,.9);">2学时</div></div>
- <div class="training-event-body"><div class="training-event-title">辐射安全基础知识讲座</div><div class="training-event-meta"><div>2026-07-20 14:00-16:00</div><div>物理楼 C301</div><div class="flex items-center gap8 mt8"><span class="tag tag-blue">知识讲座</span><span class="text-xs text-green text-bold">55/60人签到</span></div></div></div>
- </div>
- <div class="training-event-card" onclick="showPage('page-training-activity-detail')">
- <div class="training-event-cover" style="background:linear-gradient(135deg,#e53e3e,#c53030);">🔥<div style="position:absolute;top:10px;left:10px;"><span class="tag tag-gray" style="background:rgba(136,150,167,.9);color:#fff;">已结束</span></div><div style="position:absolute;bottom:10px;right:10px;background:rgba(255,255,255,.15);border-radius:6px;padding:4px 8px;font-size:11px;color:rgba(255,255,255,.9);">2.5学时</div></div>
- <div class="training-event-body"><div class="training-event-title">消防疏散应急演练(A区)</div><div class="training-event-meta"><div>2026-06-25 15:00-17:30</div><div>A区操场及实验楼</div><div class="flex items-center gap8 mt8"><span class="tag tag-orange">应急演练</span><span class="text-xs text-blue text-bold">98/120人签到</span></div></div></div>
- </div>
- </div>
- <div id="activity-list-view" style="display:none;">
- <div class="table-wrap"><table>
- <thead><tr><th>培训名称</th><th>分类</th><th>培训时间</th><th>主讲人</th><th>组织单位</th><th>地点</th><th>学时/积分</th><th>签到</th><th>状态</th><th>操作</th></tr></thead>
- <tbody>
- <tr><td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">实验室生物安全操作规范培训</span></td><td><span class="tag tag-blue">知识讲座</span></td><td>2026-08-01</td><td>李教授</td><td>生命科学学院</td><td>生命科学楼 B206</td><td><span class="text-green text-bold">2学时+10分</span></td><td>42/60</td><td><span class="tag tag-orange">进行中</span></td><td><button class="btn btn-sm btn-outline" onclick="showPage('page-training-activity-detail')">详情</button></td></tr>
- <tr><td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">化学品泄漏应急演练2026</span></td><td><span class="tag tag-orange">应急演练</span></td><td>2026-08-05</td><td>王老师</td><td>化学化工学院</td><td>化学楼 A101</td><td><span class="text-green text-bold">3学时+15分</span></td><td>28/50</td><td><span class="tag tag-blue">即将开始</span></td><td><button class="btn btn-sm btn-outline" onclick="showPage('page-training-activity-detail')">详情</button></td></tr>
- <tr><td><span class="text-blue" style="cursor:pointer;font-weight:500;" onclick="showPage('page-training-activity-detail')">辐射安全基础知识讲座</span></td><td><span class="tag tag-blue">知识讲座</span></td><td>2026-07-20</td><td>陈教授</td><td>物理学院</td><td>物理楼 C301</td><td><span class="text-green text-bold">2学时+10分</span></td><td>55/60</td><td><span class="tag tag-gray">已结束</span></td><td><button class="btn btn-sm btn-outline-gray" onclick="showPage('page-training-record');switchMenu('training-mgmt')">记录</button></td></tr>
- </tbody>
- </table></div>
- </div>
- <div class="pagination" style="margin-top:20px;">
- <button class="page-btn">«</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">»</button>
- <span class="page-info">共 12 条</span>
- </div>
- </div>
- <!-- PAGE: 培训活动详情 -->
- <div class="page" id="page-training-activity-detail">
- <div class="breadcrumb"><a onclick="showPage('page-training-activity-list');switchMenu('training-activity')">培训活动</a><span class="breadcrumb-sep">/</span><span>培训详情</span></div>
- <div style="display:flex;gap:20px;align-items:flex-start;">
- <div style="flex:1;">
- <div class="card mb16">
- <div style="background:linear-gradient(135deg,#1857d4,#2e6fe0);border-radius:8px;height:200px;display:flex;align-items:center;justify-content:center;font-size:64px;margin-bottom:20px;position:relative;">🧪<div style="position:absolute;top:14px;left:14px;"><span class="tag tag-orange" style="background:rgba(230,126,34,.9);color:#fff;">进行中</span></div><div style="position:absolute;bottom:14px;right:14px;background:rgba(255,255,255,.15);border-radius:8px;padding:6px 12px;color:rgba(255,255,255,.95);font-size:13px;">2学时</div></div>
- <div style="font-size:22px;font-weight:700;margin-bottom:12px;">实验室生物安全操作规范培训</div>
- <div style="display:flex;gap:8px;margin-bottom:16px;"><span class="tag tag-blue">知识讲座</span><span class="tag tag-green">+2学时</span><span class="tag tag-orange">+10积分</span></div>
- <div class="divider"></div>
- <div class="detail-section">
- <div class="detail-section-title">活动信息</div>
- <div class="info-row"><div class="info-key">培训时间</div><div class="info-val">2026-08-01 10:00 – 12:00</div></div>
- <div class="info-row"><div class="info-key">培训地点</div><div class="info-val">生命科学楼 B206 报告厅</div></div>
- <div class="info-row"><div class="info-key">主讲人</div><div class="info-val">李教授(生命科学学院)</div></div>
- <div class="info-row"><div class="info-key">组织单位</div><div class="info-val">生命科学学院 安全教育办公室</div></div>
- <div class="info-row"><div class="info-key">培训时长</div><div class="info-val">2 学时(120分钟)</div></div>
- <div class="info-row"><div class="info-key">可获学时</div><div class="info-val"><span class="text-green text-bold">2 学时</span></div></div>
- <div class="info-row"><div class="info-key">可获积分</div><div class="info-val"><span class="text-orange text-bold">10 积分</span></div></div>
- </div>
- <div class="divider"></div>
- <div class="detail-section">
- <div class="detail-section-title">培训详情</div>
- <div style="font-size:14px;color:var(--text-secondary);line-height:1.8;">
- <p style="margin-bottom:10px;">本次培训旨在强化实验室人员生物安全意识,规范日常实验操作,降低生物安全风险。</p>
- <p style="margin-bottom:8px;font-weight:600;color:var(--text-primary);">培训内容:</p>
- <ul style="padding-left:20px;display:flex;flex-direction:column;gap:6px;"><li>生物安全基本概念与法律法规解读</li><li>实验室生物安全等级介绍</li><li>个人防护装备(PPE)的正确使用</li><li>生物危险废弃物的分类处置</li><li>意外事故应急处理流程</li></ul>
- </div>
- </div>
- </div>
- </div>
- <div style="width:300px;flex-shrink:0;">
- <div class="card mb16">
- <div class="card-title">签到二维码</div>
- <div style="text-align:center;padding:16px 0;">
- <div style="width:140px;height:140px;background:var(--gray-light);border:2px solid var(--gray-border);border-radius:8px;display:flex;flex-direction:column;align-items:center;justify-content:center;margin:0 auto 12px;font-size:48px;cursor:pointer;" onclick="showModal('modal-qr')">▨<div style="font-size:11px;color:var(--text-hint);margin-top:4px;">点击放大</div></div>
- <button class="btn btn-primary" style="width:100%;margin-bottom:8px;" onclick="showModal('modal-qr')">显示签到码</button>
- <button class="btn btn-outline" style="width:100%;">下载二维码</button>
- </div>
- </div>
- <div class="card mb16">
- <div class="card-title">签到统计</div>
- <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px;">
- <div style="background:var(--blue-xlight);border-radius:6px;padding:10px;text-align:center;"><div style="font-size:22px;font-weight:700;color:var(--blue);">42</div><div class="text-xs text-gray">已签到</div></div>
- <div style="background:var(--red-light);border-radius:6px;padding:10px;text-align:center;"><div style="font-size:22px;font-weight:700;color:var(--red);">18</div><div class="text-xs text-gray">未签到</div></div>
- <div style="background:var(--green-light);border-radius:6px;padding:10px;text-align:center;"><div style="font-size:22px;font-weight:700;color:var(--green);">60</div><div class="text-xs text-gray">应到</div></div>
- <div style="background:var(--orange-light);border-radius:6px;padding:10px;text-align:center;"><div style="font-size:22px;font-weight:700;color:var(--orange);">70%</div><div class="text-xs text-gray">签到率</div></div>
- </div>
- <div class="progress-wrap" style="height:8px;"><div class="progress-bar" style="width:70%;"></div></div>
- </div>
- <div class="card">
- <div class="card-title">签到人员</div>
- <div style="max-height:280px;overflow-y:auto;">
- <div class="attend-row"><div class="attend-avatar">👤</div><div class="attend-info"><div style="font-size:13px;font-weight:500;">张明远</div><div class="text-xs text-gray">20231001</div></div><span class="attend-status-yes">10:05</span></div>
- <div class="attend-row"><div class="attend-avatar">👤</div><div class="attend-info"><div style="font-size:13px;font-weight:500;">李晓燕</div><div class="text-xs text-gray">20221056</div></div><span class="attend-status-yes">10:02</span></div>
- <div class="attend-row"><div class="attend-avatar">👤</div><div class="attend-info"><div style="font-size:13px;font-weight:500;">王浩然</div><div class="text-xs text-gray">20231089</div></div><span class="attend-status-late">迟到10:22</span></div>
- <div class="attend-row"><div class="attend-avatar">👤</div><div class="attend-info"><div style="font-size:13px;font-weight:500;">陈思雨</div><div class="text-xs text-gray">20241103</div></div><span class="attend-status-no">未签到</span></div>
- </div>
- <button class="btn btn-outline" style="width:100%;margin-top:12px;">查看全部 60 人</button>
- </div>
- </div>
- </div>
- </div>
- <!-- ==================== MODALS ==================== -->
- <!-- QR Code Modal -->
- <div class="modal-overlay" id="modal-qr">
- <div class="modal-box" style="max-width:360px;">
- <div class="modal-header">
- <div class="modal-title">📷 签到二维码</div>
- <button class="modal-close" onclick="hideModal('modal-qr')">✕</button>
- </div>
- <div class="modal-body" style="text-align:center;">
- <div style="font-size:15px;font-weight:600;margin-bottom:4px;">实验室生物安全操作规范培训</div>
- <div style="font-size:12px;color:var(--text-hint);margin-bottom:16px;">2026-08-01 10:00–12:00</div>
- <div style="width:200px;height:200px;background:var(--gray-light);border:3px solid var(--gray-border);border-radius:12px;display:flex;flex-direction:column;align-items:center;justify-content:center;margin:0 auto 16px;font-size:80px;">▨</div>
- <div style="background:var(--blue-xlight);border-radius:8px;padding:10px;font-size:12px;color:var(--text-secondary);margin-bottom:16px;">
- 学员扫描此二维码完成签到<br>
- <span style="color:var(--orange);font-weight:500;">有效期至 2026-08-01 12:30</span>
- </div>
- <div class="flex gap8" style="justify-content:center;">
- <button class="btn btn-primary">⬇ 下载二维码</button>
- <button class="btn btn-outline" onclick="hideModal('modal-qr')">关闭</button>
- </div>
- </div>
- </div>
- </div>
- <!-- Progress Modal -->
- <div class="modal-overlay" id="modal-progress">
- <div class="modal-box modal-lg">
- <div class="modal-header">
- <div class="modal-title">📊 培训进度详情</div>
- <button class="modal-close" onclick="hideModal('modal-progress')">✕</button>
- </div>
- <div class="modal-body">
- <div style="font-size:15px;font-weight:600;margin-bottom:12px;">实验室生物安全操作规范培训</div>
- <div style="display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px;">
- <div style="background:var(--blue-xlight);border-radius:8px;padding:12px;text-align:center;"><div style="font-size:24px;font-weight:700;color:var(--blue);">60</div><div class="text-xs text-gray">计划人数</div></div>
- <div style="background:var(--green-light);border-radius:8px;padding:12px;text-align:center;"><div style="font-size:24px;font-weight:700;color:var(--green);">42</div><div class="text-xs text-gray">已签到</div></div>
- <div style="background:var(--red-light);border-radius:8px;padding:12px;text-align:center;"><div style="font-size:24px;font-weight:700;color:var(--red);">18</div><div class="text-xs text-gray">未签到</div></div>
- <div style="background:var(--orange-light);border-radius:8px;padding:12px;text-align:center;"><div style="font-size:24px;font-weight:700;color:var(--orange);">70%</div><div class="text-xs text-gray">签到率</div></div>
- </div>
- <div class="progress-wrap" style="height:10px;margin-bottom:20px;"><div class="progress-bar" style="width:70%;"></div></div>
- <div class="table-wrap">
- <table>
- <thead><tr><th>姓名</th><th>学号</th><th>院系</th><th>签到状态</th><th>签到时间</th><th>获得学时</th><th>获得积分</th></tr></thead>
- <tbody>
- <tr><td>张明远</td><td>20231001</td><td>生命科学学院</td><td><span class="tag tag-green">已签到</span></td><td>10:05</td><td>2</td><td>10</td></tr>
- <tr><td>李晓燕</td><td>20221056</td><td>生命科学学院</td><td><span class="tag tag-green">已签到</span></td><td>10:02</td><td>2</td><td>10</td></tr>
- <tr><td>王浩然</td><td>20231089</td><td>化学化工学院</td><td><span class="tag tag-orange">迟到</span></td><td>10:22</td><td>2</td><td>8</td></tr>
- <tr><td>陈思雨</td><td>20241103</td><td>物理学院</td><td><span class="tag tag-red">未签到</span></td><td>—</td><td>0</td><td>0</td></tr>
- <tr><td>刘志远</td><td>20231055</td><td>生命科学学院</td><td><span class="tag tag-green">已签到</span></td><td>09:58</td><td>2</td><td>10</td></tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline">📄 导出Excel</button>
- <button class="btn btn-outline-gray" onclick="hideModal('modal-progress')">关闭</button>
- </div>
- </div>
- </div>
- <!-- Record Detail Modal -->
- <div class="modal-overlay" id="modal-record-detail">
- <div class="modal-box modal-lg">
- <div class="modal-header">
- <div class="modal-title">📄 培训记录详情</div>
- <button class="modal-close" onclick="hideModal('modal-record-detail')">✕</button>
- </div>
- <div class="modal-body">
- <div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin-bottom:16px;">
- <div style="font-size:16px;font-weight:700;">辐射安全基础知识讲座</div>
- <span class="tag tag-gray">已结束</span>
- <span class="tag tag-blue">知识讲座</span>
- <span class="tag tag-green" style="gap:4px;">🏅 已颁发证书</span>
- </div>
- <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px;font-size:13px;">
- <div><span style="color:var(--text-hint);">培训时间:</span>2026-07-20 14:00–16:00</div>
- <div><span style="color:var(--text-hint);">培训地点:</span>物理楼 C301</div>
- <div><span style="color:var(--text-hint);">主讲人:</span>陈教授</div>
- <div><span style="color:var(--text-hint);">签到率:</span><span class="text-green text-bold">91.7% (55/60)</span></div>
- <div><span style="color:var(--text-hint);">可得学时:</span><span class="text-green text-bold">2 学时</span></div>
- <div><span style="color:var(--text-hint);">可得积分:</span><span class="text-orange text-bold">10 积分</span></div>
- <div><span style="color:var(--text-hint);">证书模板:</span>实验室安全培训证书(通用)</div>
- </div>
- <div class="divider"></div>
- <div style="margin-bottom:12px;font-size:13px;font-weight:600;">参与人员签到记录</div>
- <div class="table-wrap">
- <table>
- <thead><tr><th>姓名</th><th>学号</th><th>院系</th><th>签到状态</th><th>签到时间</th><th>获得学时</th><th>获得积分</th><th>证书状态</th><th>操作</th></tr></thead>
- <tbody>
- <tr><td>张明远</td><td>20231001</td><td>生命科学学院</td><td><span class="tag tag-green">已签到</span></td><td>14:02</td><td><span class="text-green text-bold">2</span></td><td><span class="text-orange text-bold">10</span></td><td><span class="tag tag-green" style="font-size:10px;">已颁发</span></td><td><div class="flex gap8"><span class="text-blue text-sm" style="cursor:pointer;" onclick="showModal('modal-cert-preview')">查看</span><span class="text-blue text-sm" style="cursor:pointer;">下载</span></div></td></tr>
- <tr><td>李晓燕</td><td>20221056</td><td>生命科学学院</td><td><span class="tag tag-green">已签到</span></td><td>14:05</td><td><span class="text-green text-bold">2</span></td><td><span class="text-orange text-bold">10</span></td><td><span class="tag tag-green" style="font-size:10px;">已颁发</span></td><td><div class="flex gap8"><span class="text-blue text-sm" style="cursor:pointer;" onclick="showModal('modal-cert-preview')">查看</span><span class="text-blue text-sm" style="cursor:pointer;">下载</span></div></td></tr>
- <tr><td>王浩然</td><td>20231089</td><td>化学化工学院</td><td><span class="tag tag-orange">迟到</span></td><td>14:18</td><td><span class="text-green text-bold">2</span></td><td><span class="text-orange text-bold">8</span></td><td><span class="tag tag-green" style="font-size:10px;">已颁发</span></td><td><div class="flex gap8"><span class="text-blue text-sm" style="cursor:pointer;" onclick="showModal('modal-cert-preview')">查看</span><span class="text-blue text-sm" style="cursor:pointer;">下载</span></div></td></tr>
- <tr><td>陈思雨</td><td>20241103</td><td>物理学院</td><td><span class="tag tag-red">未签到</span></td><td>—</td><td>0</td><td>0</td><td><span class="tag tag-gray" style="font-size:10px;">未颁发</span></td><td>—</td></tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-outline">📄 导出记录</button>
- <button class="btn btn-outline-gray" onclick="hideModal('modal-record-detail')">关闭</button>
- </div>
- </div>
- </div>
- <!-- Certificate Preview Modal -->
- <div class="modal-overlay" id="modal-cert-preview">
- <div class="modal-box" style="max-width:580px;">
- <div class="modal-header">
- <div class="modal-title">🏅 培训证书</div>
- <button class="modal-close" onclick="hideModal('modal-cert-preview')">✕</button>
- </div>
- <div class="modal-body">
- <!-- Certificate card -->
- <div style="background:linear-gradient(135deg,#1857d4 0%,#0f3ea8 100%);border-radius:12px;padding:32px 28px;color:#fff;position:relative;overflow:hidden;margin-bottom:16px;">
- <div style="position:absolute;right:-30px;top:-30px;width:160px;height:160px;background:rgba(255,255,255,.06);border-radius:50%;"></div>
- <div style="position:absolute;right:20px;bottom:-40px;width:120px;height:120px;background:rgba(255,255,255,.04);border-radius:50%;"></div>
- <div style="text-align:center;margin-bottom:20px;">
- <div style="font-size:13px;letter-spacing:2px;opacity:.75;margin-bottom:4px;">实验室安全培训证书</div>
- <div style="font-size:11px;opacity:.55;letter-spacing:1px;">LABORATORY SAFETY TRAINING CERTIFICATE</div>
- </div>
- <div style="text-align:center;margin-bottom:20px;">
- <div style="font-size:11px;opacity:.7;margin-bottom:6px;">兹证明</div>
- <div style="font-size:26px;font-weight:700;letter-spacing:3px;margin-bottom:6px;">张 明 远</div>
- <div style="font-size:11px;opacity:.7;">学号:20231001 · 硕士研究生 · 生命科学学院</div>
- </div>
- <div style="text-align:center;margin-bottom:20px;font-size:13px;opacity:.85;line-height:1.7;">
- 已参加并完成 <strong>辐射安全基础知识讲座</strong> 培训<br>
- 培训时间:2026-07-20 · 获得学时:<strong>2 学时</strong> · 获得积分:<strong>10 分</strong>
- </div>
- <div style="display:flex;justify-content:space-between;align-items:flex-end;border-top:1px solid rgba(255,255,255,.2);padding-top:14px;font-size:11px;opacity:.7;">
- <div>证书编号:CERT-2026-0720-001</div>
- <div>颁发日期:2026-07-20</div>
- <div>颁发单位:实验室安全教育中心</div>
- </div>
- </div>
- <div class="flex gap8" style="justify-content:flex-end;">
- <button class="btn btn-primary">⬇ 下载证书</button>
- <button class="btn btn-outline-gray" onclick="hideModal('modal-cert-preview')">关闭</button>
- </div>
- </div>
- </div>
- </div>
- <!-- Delete Confirm Modal -->
- <div class="modal-overlay" id="modal-confirm-delete">
- <div class="modal-box" style="max-width:380px;">
- <div class="modal-header">
- <div class="modal-title">确认删除</div>
- <button class="modal-close" onclick="hideModal('modal-confirm-delete')">✕</button>
- </div>
- <div class="modal-body" style="text-align:center;padding:24px;">
- <div style="font-size:40px;margin-bottom:12px;">🗑️</div>
- <div style="font-size:15px;font-weight:600;margin-bottom:8px;">确认删除此培训?</div>
- <div style="font-size:13px;color:var(--text-hint);">删除后数据将无法恢复,相关签到记录和证书也将一并删除。</div>
- </div>
- <div class="modal-footer" style="justify-content:center;">
- <button class="btn btn-outline-gray" onclick="hideModal('modal-confirm-delete')" style="min-width:90px;">取消</button>
- <button class="btn" style="min-width:90px;background:var(--red);color:#fff;" onclick="hideModal('modal-confirm-delete')">确认删除</button>
- </div>
- </div>
- </div>
- </div><!-- end main-content -->
- <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:24px;">
- <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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" id="kaixue-nav-basic" onclick="switchExamSection('kaixue','basic')">基本设置</div>
- <div class="nav-item" id="kaixue-nav-preexam" onclick="switchExamSection('kaixue','preexam')">考前配置</div>
- <div class="nav-item" id="kaixue-nav-cheat" onclick="switchExamSection('kaixue','cheat')">防作弊</div>
- <div class="nav-item" id="kaixue-nav-cert" onclick="switchExamSection('kaixue','cert')">获得证书</div>
- </div>
- <!-- Right content area -->
- <div style="flex:1;padding:28px;overflow-y:auto;max-height:calc(100vh - 220px);">
- <!-- 权限层级 + 每学年自动执行 (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 24px;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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g1','basic')">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','preexam')">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','cheat')">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g1','cert')">获得证书</div>
- </div>
- <div style="flex:1;padding:28px;overflow-y:auto;max-height:calc(100vh - 260px);">
- <!-- 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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g2','basic')">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','preexam')">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','cheat')">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g2','cert')">获得证书</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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g3','basic')">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','preexam')">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','cheat')">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g3','cert')">获得证书</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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" onclick="switchExamSection('fenji-g4','basic')">基本设置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','preexam')">考前配置</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','cheat')">防作弊</div>
- <div class="nav-item" onclick="switchExamSection('fenji-g4','cert')">获得证书</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:180px;flex-shrink:0;border-right:1px solid var(--gray-border);background:var(--gray-light);padding:14px 0;">
- <div class="nav-item active" id="yingzhi-nav-basic" onclick="switchExamSection('yingzhi','basic')">基本设置</div>
- <div class="nav-item" id="yingzhi-nav-preexam" onclick="switchExamSection('yingzhi','preexam')">考前配置</div>
- <div class="nav-item" id="yingzhi-nav-cheat" onclick="switchExamSection('yingzhi','cheat')">防作弊</div>
- <div class="nav-item" id="yingzhi-nav-cert" onclick="switchExamSection('yingzhi','cert')">获得证书</div>
- </div>
- <div style="flex:1;padding:28px;overflow-y:auto;max-height:calc(100vh - 220px);">
- <!-- 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 -->
- </div><!-- end admin-body -->
- <script>
- // ===== PAGE ROUTING =====
- function showPage(id) {
- document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
- const target = document.getElementById(id);
- if (target) { target.classList.add('active'); window.scrollTo(0,0); }
- // Highlight matching nav item by onclick attr
- document.querySelectorAll('.nav-item').forEach(n => {
- n.classList.remove('active');
- const oc = n.getAttribute('onclick') || '';
- if (oc.includes("'" + id + "'")) n.classList.add('active');
- // detail pages highlight their parent list item
- if (id === 'page-training-activity-detail' && oc.includes("'page-training-activity-list'")) n.classList.add('active');
- });
- }
- // switchMenu kept for backwards compat with any remaining onclick refs — no-op since sidebar is now unified
- function switchMenu() {}
- // ===== CERT TEMPLATE TOGGLE =====
- function toggleCertTemplate(checkbox) {
- document.getElementById('cert-template-section').style.display = checkbox.checked ? 'block' : 'none';
- }
- // ===== TRAINING SCOPE MODE =====
- function setScopeMode(mode) {
- document.getElementById('scope-dept-section').style.display = mode === 'dept' ? 'block' : 'none';
- document.getElementById('scope-person-section').style.display = mode === 'person' ? 'block' : 'none';
- ['all','dept','person'].forEach(function(m) {
- var lbl = document.getElementById('scope-label-' + m);
- if (lbl) {
- lbl.style.borderColor = m === mode ? 'var(--blue)' : 'var(--gray-border)';
- lbl.style.background = m === mode ? 'var(--blue-xlight)' : '';
- lbl.style.color = m === mode ? 'var(--blue)' : '';
- }
- });
- }
- // ===== PUBLISH TOGGLE CLICK =====
- document.addEventListener('click', function(e) {
- const wrap = e.target.closest('.pub-slider');
- if (!wrap) return;
- const isOn = wrap.classList.contains('pub-on');
- wrap.classList.toggle('pub-on', !isOn);
- wrap.classList.toggle('pub-off', isOn);
- });
- // ===== LIST/GRID VIEW =====
- function setListView(mode) {
- const grid = document.getElementById('activity-grid-view');
- const list = document.getElementById('activity-list-view');
- if (!grid || !list) return;
- if (mode === 'grid') { grid.style.display = 'grid'; list.style.display = 'none'; }
- else { grid.style.display = 'none'; list.style.display = 'block'; }
- }
- // ===== MODALS =====
- function showModal(id) {
- const m = document.getElementById(id);
- if (m) m.classList.add('active');
- }
- function hideModal(id) {
- const m = document.getElementById(id);
- if (m) m.classList.remove('active');
- }
- // Close modal on backdrop click
- document.querySelectorAll('.modal-overlay').forEach(m => {
- m.addEventListener('click', function(e) {
- if (e.target === this) this.classList.remove('active');
- });
- });
- // ===== 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>';
- }
- </script>
- </body>
- </html>
|