已完成“组织与权限”优化:

基础数据拆分为:组织机构、学年学期、教学场所。
人员档案拆分为:教师档案、学生档案。
基础数据、教师、学生、用户权限均支持 Excel 模板下载、批量导入和导出。
导入按编码/工号/学号/账号新增或更新;整批校验,失败不写入,限制 2000 条、10 MB。
用户列表新增密码重置,包含双重确认、最低 8 位校验和服务端权限保护。
导入严格执行角色及学院数据范围校验,并保护当前超级管理员账号。
保留旧地址重定向,原有入口不会失效。
This commit is contained in:
2026-07-24 18:12:56 +08:00 Unverified
parent 662aa1051f
commit 022e79c48d
13 changed files with 2133 additions and 59 deletions
+16 -2
View File
@@ -169,15 +169,16 @@ button { cursor: pointer; }
.page-intro { min-height: 106px; padding: 8px 4px; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.page-intro h2 { margin: 7px 0 7px; font-family: "STZhongsong", "Songti SC", serif; font-size: 27px; }
.page-intro p { margin: 0; color: var(--muted); font-size: 13px; }
.page-actions { display: flex; align-items: center; gap: 8px; }
.data-card { border: 1px solid var(--line); background: white; overflow: hidden; }
.data-tabs { display: grid; grid-template-columns: repeat(7, minmax(105px, 1fr)); border-bottom: 1px solid var(--line); overflow-x: auto; }
.data-tabs { display: grid; grid-template-columns: repeat(var(--tab-count, 7), minmax(105px, 1fr)); border-bottom: 1px solid var(--line); overflow-x: auto; }
.data-tabs button { min-width: 110px; padding: 16px 15px 14px; text-align: left; border: none; border-right: 1px solid #eaedf1; border-bottom: 3px solid transparent; color: var(--ink); background: #fafbfc; }
.data-tabs button:hover { background: white; }
.data-tabs button.active { border-bottom-color: var(--teal); background: white; }
.data-tabs b, .data-tabs span { display: block; }
.data-tabs b { font-size: 13px; }
.data-tabs span { margin-top: 4px; color: #9299a7; font-size: 10px; white-space: nowrap; }
.table-toolbar { min-height: 69px; padding: 14px 18px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--line); }
.table-toolbar { min-height: 69px; padding: 14px 18px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; border-bottom: 1px solid var(--line); }
.table-toolbar .el-input { width: min(340px, 60vw); }
.table-toolbar > span { margin-left: auto; color: var(--muted); font-size: 11px; }
.data-table { min-height: 360px; }
@@ -198,6 +199,8 @@ button { cursor: pointer; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid.compact { align-items: center; }
.form-grid.three { grid-template-columns: repeat(3, 1fr); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.password-reset-form { margin-top: 18px; }
.registry-switch { display: grid; grid-template-columns: 1fr 1fr 180px; min-height: 112px; border: 1px solid var(--line); background: white; }
.registry-switch button { padding: 22px 26px; display: grid; gap: 4px; text-align: left; border: none; border-right: 1px solid var(--line); border-bottom: 3px solid transparent; background: white; }
@@ -209,6 +212,14 @@ button { cursor: pointer; }
.registry-total { padding: 20px; display: grid; place-content: center; text-align: center; background: var(--indigo-deep); color: white; }
.registry-total span, .registry-total small { color: #aeb8d6; font-size: 10px; }
.registry-total strong { margin: 3px 0; font: 700 30px/1 Consolas, monospace; color: #59d3c1; }
.registry-banner { min-height: 104px; display: grid; grid-template-columns: 1fr 180px; color: white; border: 1px solid #243d70; background: linear-gradient(105deg, #172858, #29417c 68%, #19736f); overflow: hidden; }
.registry-banner.student { background: linear-gradient(105deg, #172858, #344877 60%, #6d5b91); }
.registry-banner > div:first-child { padding: 22px 27px; display: grid; align-content: center; gap: 6px; position: relative; }
.registry-banner > div:first-child::after { content: ""; position: absolute; right: 26px; top: 18px; width: 70px; height: 70px; opacity: .16; background-image: linear-gradient(rgba(255,255,255,.8) 1px, transparent 1px), linear-gradient(90deg,rgba(255,255,255,.8) 1px,transparent 1px); background-size: 14px 14px; }
.registry-banner > div > span { color: #65dac8; font: 700 9px/1.2 Consolas, monospace; letter-spacing: .14em; }
.registry-banner > div > b { font-family: "STZhongsong", "Songti SC", serif; font-size: 18px; font-weight: 600; }
.registry-banner > div > small { color: #bdc8e1; font-size: 10px; }
.registry-banner .registry-total { border-left: 1px solid rgba(255,255,255,.14); }
.filter-bar { min-height: 72px; padding: 14px 18px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; border-bottom: 1px solid var(--line); background: #fbfcfd; }
.filter-bar > .el-input { width: 280px; }
.filter-bar > .el-select { width: 150px; }
@@ -888,6 +899,9 @@ button { cursor: pointer; }
.registry-switch button { padding: 17px; }
.registry-total { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; min-height: 54px; }
.registry-total strong { margin-left: auto; font-size: 22px; }
.registry-banner { grid-template-columns: 1fr; }
.registry-banner > div:first-child { min-height: 98px; padding: 19px; }
.registry-banner .registry-total { grid-column: auto; min-height: 54px; border-left: none; border-top: 1px solid rgba(255,255,255,.14); }
.filter-bar > .el-input { width: 100%; }
.filter-bar > .el-select { flex: 1 1 140px; width: auto; }
.course-ledger { min-height: auto; display: block; }