diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss index acd0b25..0c0b14b 100644 --- a/src/assets/styles/ruoyi.scss +++ b/src/assets/styles/ruoyi.scss @@ -279,33 +279,6 @@ margin-left: auto; } -/* Element Plus 下拉菜单全局样式覆盖 */ -.el-dropdown-menu { - background: linear-gradient(160deg, #0a1929 0%, #0d2137 50%, #0a1929 100%) !important; - border: 1px solid rgba(0, 170, 255, 0.35) !important; - border-radius: 14px !important; - box-shadow: 0 15px 50px rgba(0, 0, 0, 0.6), 0 0 30px rgba(0, 170, 255, 0.15) !important; - padding: 10px 12px !important; - - .el-dropdown-menu__item { - background: transparent !important; - color: rgba(200, 230, 255, 0.9) !important; - - &:hover { - background: rgba(0, 170, 255, 0.15) !important; - color: #ffffff !important; - } - - &.is-disabled { - background: transparent !important; - color: rgba(200, 230, 255, 0.4) !important; - } - } -} - -.el-dropdown__popper { - background: linear-gradient(160deg, #0a1929 0%, #0d2137 50%, #0a1929 100%) !important; - border: 1px solid rgba(0, 170, 255, 0.35) !important; - border-radius: 14px !important; - box-shadow: 0 15px 50px rgba(0, 0, 0, 0.6), 0 0 30px rgba(0, 170, 255, 0.15) !important; -} +/* Element Plus 下拉菜单:已移除旧暗色渐变皮肤(教师端/学生端亮色主题下不协调)。 + 弹层 teleport 到 body 无法按端锚定,统一回归 EP 默认白底 + 灰边 + 浅灰 hover, + 教育风外观由组件默认样式保证(教师端 teacher-light.scss 无需再覆盖)。 */ diff --git a/src/assets/styles/teacher-light.scss b/src/assets/styles/teacher-light.scss index 94618bf..8e779af 100644 --- a/src/assets/styles/teacher-light.scss +++ b/src/assets/styles/teacher-light.scss @@ -152,6 +152,7 @@ .toolbar, .filter-section, .df, + .assessment-toolbar, .query-bar, .btn-group { background: #ffffff !important; @@ -287,7 +288,8 @@ .exam-admin .el-button--primary:not(.is-text):not(.is-link), .exam-editor .el-button--primary:not(.is-text):not(.is-link), .review-page .el-button--primary:not(.is-text):not(.is-link), - .analysis-page .el-button--primary:not(.is-text):not(.is-link) { + .analysis-page .el-button--primary:not(.is-text):not(.is-link), + .ai-gen-page .el-button--primary:not(.is-text):not(.is-link) { background-color: #2563eb !important; background-image: none !important; border-color: #2563eb !important; @@ -711,15 +713,13 @@ } // EP 中 input 与 select 各自承载边框的 wrapper 必须同时覆盖 + // 注意:不强制 height/min-height/padding,让 Element Plus 的 size 属性(default/large/small)生效 .el-input__wrapper, .el-select__wrapper { - height: 36px !important; - min-height: 36px !important; background-color: #ffffff !important; border: 1px solid #e5e7eb !important; box-shadow: none !important; border-radius: 8px !important; - padding: 0 11px !important; transition: border-color 0.2s ease, box-shadow 0.2s ease; @@ -736,9 +736,6 @@ } .el-input__inner { - height: 34px !important; - line-height: 34px !important; - font-size: 12px !important; color: #1f2937 !important; &::placeholder { @@ -746,10 +743,9 @@ } } - // select 显示值/占位值(EP 用 -webkit-text-fill-color,需显式覆盖) + // select 显示值/占位值(EP 用 -webkit-text-fill-color,需显式覆盖;字号由 EP size 属性处理) .el-select__placeholder, .el-select__selected-item { - font-size: 12px !important; color: #1f2937 !important; -webkit-text-fill-color: #1f2937 !important; } @@ -768,12 +764,11 @@ color: #9ca3af; } - // 多行文本:与单行同一描边语言 + // 多行文本:与单行同一描边语言(字号由 EP size 属性处理) .el-textarea__inner { background-color: #ffffff !important; border: 1px solid #e5e7eb !important; color: #1f2937 !important; - font-size: 12px !important; border-radius: 8px !important; box-shadow: none !important; @@ -1574,74 +1569,227 @@ body.teacher-light-mode { } } - // 弹窗(教师端各页面 teacher-dialog / admin-edit-dialog) + // ===== 弹窗(teacher-dialog / admin-edit-dialog:扁平纯白 + 教育风令牌)===== .teacher-dialog, .admin-edit-dialog { + // dialog 作用域内重设 EP CSS 变量,防止 html.dark 的 --el-color-primary:#00aaff 污染 + --el-color-primary: #3b82f6; + --el-color-primary-light-3: #60a5fa; + --el-color-primary-light-5: #93c5fd; + --el-color-primary-light-7: #bfdbfe; + --el-color-primary-light-8: #dbeafe; + --el-color-primary-light-9: #eff6ff; + --el-color-primary-dark-2: #2563eb; + --el-color-white: #ffffff; + background: #ffffff !important; - border: 1px solid #e5e7eb !important; - border-radius: 16px !important; - box-shadow: 0 20px 56px rgba(30, 60, 100, 0.18) !important; + border: 1px solid var(--border-color) !important; + border-radius: var(--r-card) !important; + box-shadow: 0 20px 56px rgba(30, 60, 100, 0.12) !important; overflow: hidden; + // 弹窗整体:不超出视口,footer 固定底,body 滚动 + display: flex !important; + flex-direction: column !important; + max-height: calc(100vh - 120px) !important; .el-dialog__header { - background: linear-gradient(135deg, #eff6ff 0%, #eff6ff 100%) !important; - padding: 18px 24px; + background: #ffffff !important; + padding: 18px 24px 14px; margin: 0; - border-bottom: 1px solid rgba(59, 130, 246, 0.15); + border-bottom: 1px solid var(--border-color); + flex: 0 0 auto; .el-dialog__title { - color: #1f2937 !important; + color: var(--text-strong) !important; font-weight: 700; - font-size: 17px; + font-size: var(--fs-page); text-shadow: none !important; } - .el-dialog__headerbtn .el-dialog__close { - color: #6b7280 !important; + .el-dialog__headerbtn { + top: 18px; + right: 20px; - &:hover { - color: #3b82f6 !important; + .el-dialog__close { + color: var(--text-muted) !important; + font-size: 18px; + + &:hover { + color: var(--edu-primary) !important; + } } } } .el-dialog__body { background: #ffffff !important; - color: #1f2937; - padding: 24px 28px; + color: var(--text-strong); + padding: 24px; + flex: 1 1 auto; + overflow-y: auto !important; + // ruoyi.scss 有 max-height:70vh 的 dialog.scrollbar 规则,但我们没加 scrollbar 类, + // 直接用 flex:1 + overflow-y:auto 让 body 在 flex 布局内自然滚动 } .el-dialog__footer { - background: #f8fbfe !important; - border-top: 1px solid #edf2f7 !important; + background: #ffffff !important; + border-top: 1px solid var(--border-color) !important; padding: 14px 24px; + text-align: right; + flex: 0 0 auto; } + // form label 颜色(覆盖 index.scss 暗色残留) .el-form-item__label, label { - color: #1f2937 !important; - } - - .el-input__wrapper, - .el-select .el-input__wrapper, - .el-textarea__inner { - background-color: #ffffff !important; + color: var(--text-strong) !important; + font-weight: 600; + font-size: var(--fs-body); } + // input / textarea / select 文字 .el-input__inner, .el-textarea__inner { - color: #1f2937 !important; + color: var(--text-strong) !important; + font-size: 14px !important; // 题干/答案用 14px 更清晰 } + // radio / checkbox 文字 .el-radio__label, .el-checkbox__label { - color: #1f2937 !important; + color: var(--text-strong) !important; + font-size: var(--fs-body); } - // 班级成员管理弹窗内的搜索工具条 - .member-toolbar { - background: #f8fbfe !important; - border: 1px solid rgba(59, 130, 246, 0.12) !important; + // ===== 按钮颜色全量兜底(防止暗色主题残留污染)===== + // 默认按钮 + .el-button { + color: var(--text-strong) !important; + --el-button-bg-color: #ffffff; + --el-button-border-color: var(--border-color); + + &:hover { + color: var(--edu-primary) !important; + } + } + + // text 按钮(添加选项 / 删除):必须显式给深字 + 深 icon + .el-button.is-text, + .el-button.is-link { + background: transparent !important; + border-color: transparent !important; + color: var(--text-body) !important; + --el-text-color-placeholder: var(--text-body); + + &:hover { + background: transparent !important; + color: var(--edu-primary) !important; + } + + // 按钮内的 SVG icon(删除 ×) + .el-icon { + color: var(--text-muted) !important; + + &:hover { + color: var(--edu-primary) !important; + } + + svg { + fill: currentColor !important; + } + } + } + + // ghost/outline 按钮(取消) + .el-button:not(.is-text):not(.is-link):not(.el-button--primary):not(.el-button--success):not(.el-button--danger):not(.el-button--warning) { + background: #ffffff !important; + border: 1px solid var(--border-color) !important; + color: var(--text-strong) !important; + + &:hover { + background: #f9fafb !important; + border-color: var(--text-muted) !important; + color: var(--text-strong) !important; + } + } + + // ===== radio-button(题型选择器):教育风蓝色选中 ===== + // 注意:不能用 --el-color-primary CSS 变量,因为 html.dark 可能设成暗色 #00aaff, + // 必须显式写 var(--edu-primary) 让 teacher-light-mode 令牌生效 + .el-radio-button__inner { + border-radius: var(--r-control) !important; + border: 1px solid var(--border-color) !important; + background: #ffffff !important; + color: var(--text-body) !important; + font-size: var(--fs-body); + font-weight: 500; + padding: 8px 16px; + box-shadow: none !important; + transition: border-color 0.18s, color 0.18s, background 0.18s; + + &:hover { + color: var(--edu-primary) !important; + border-color: var(--edu-primary) !important; + } + } + + // EP 选中时会给 .el-radio-button 加 .is-active 类(比 :checked + 兄弟选择器更可靠, + // 因为中间没有 wrapper 断层) + .el-radio-button.is-active .el-radio-button__inner, + .el-radio-button .el-radio-button__orig-radio:checked + .el-radio-button__inner { + background: var(--edu-primary) !important; + background-color: var(--edu-primary) !important; + border-color: var(--edu-primary) !important; + color: #ffffff !important; + font-weight: 600 !important; + box-shadow: none !important; + } + + .el-radio-button:first-child .el-radio-button__inner { + border-left: 1px solid var(--border-color) !important; + border-top-left-radius: var(--r-control) !important; + border-bottom-left-radius: var(--r-control) !important; + } + + .el-radio-button:last-child .el-radio-button__inner { + border-top-right-radius: var(--r-control) !important; + border-bottom-right-radius: var(--r-control) !important; + } + + // 上传按钮(资料上传) + .el-upload { + .el-button { + border: 1px dashed var(--border-color) !important; + background: #f9fafb !important; + color: var(--text-body) !important; + } + } + + // 文件展示名 + .file-name { + color: var(--edu-primary); + font-size: var(--fs-body); + } + } + + // 弹窗遮罩层:中灰半透明、无 blur、不影响内容清晰度 + // 注:遮罩层在 body 下(teleport),用 body.teacher-light-mode 命中 + .el-overlay { + background-color: rgba(15, 23, 42, 0.45) !important; + backdrop-filter: none !important; + } + + // AI 智能出题页面:已迁移至 ai-generate.vue 的 scoped 样式(遵循 teacher-edu-style skill) + // 全局只保留主按钮方案 A 规则(见 L292),页面布局/视觉由 scoped 接管 + + @keyframes ai-bounce { + 0%, 80%, 100% { + transform: translateY(0); + opacity: 0.4; + } + 40% { + transform: translateY(-6px); + opacity: 1; } } diff --git a/src/router/index.js b/src/router/index.js index 20eed70..fec3ef1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -711,6 +711,13 @@ export const teacherRoutes = [ name: "TeacherExams", meta: { title: "综合考核", icon: "Finished", affix: true }, }, + { + path: "ai-generate", + component: () => import("@/views/teacherEnd/exam/ai-generate.vue"), + name: "TeacherExamAiGenerate", + hidden: true, + meta: { title: "AI 智能出题", affix: false }, + }, { path: "manage/:id", component: () => import("@/views/teacherEnd/exam/editor.vue"), diff --git a/src/views/teacherEnd/exam/ai-generate.vue b/src/views/teacherEnd/exam/ai-generate.vue new file mode 100644 index 0000000..73e5ecb --- /dev/null +++ b/src/views/teacherEnd/exam/ai-generate.vue @@ -0,0 +1,484 @@ + + + + + diff --git a/src/views/teacherEnd/exam/editor.vue b/src/views/teacherEnd/exam/editor.vue index 2096d5f..ef7c800 100644 --- a/src/views/teacherEnd/exam/editor.vue +++ b/src/views/teacherEnd/exam/editor.vue @@ -1,97 +1,207 @@ @@ -99,7 +209,7 @@ import { computed, onMounted, reactive, ref } from "vue"; import { useRoute, useRouter } from "vue-router"; import { ElMessage } from "element-plus"; -import { ArrowLeft, ArrowRight, Check, Download, FolderOpened, Promotion, Upload } from "@element-plus/icons-vue"; +import { ArrowLeft, ArrowRight, Check, Close, Download, FolderOpened, Promotion, Upload } from "@element-plus/icons-vue"; import { saveAs } from "file-saver"; import * as examApi from "@/api/exam"; @@ -140,24 +250,41 @@ function toBoolean(value, fallback) { if (value === undefined || value === null color: var(--text-strong); padding-bottom: 92px; - /* ===== 标题行(轻量标题行:返回 + 标题 + 主操作;卡片外观归 teacher-light.scss 扁平化接管)===== */ + /* ===== 标题行(左组:返回+标题;右侧:操作按钮;扁平落地画布)===== */ .editor-head { display: grid; - grid-template-columns: 1fr auto 1fr; - align-items: center; + gap: var(--sp-2); margin-bottom: var(--sp-4); - > :last-child { justify-self: end; } + padding-bottom: var(--sp-3); + border-bottom: 1px solid var(--border-color); } - .title-block { + .head-breadcrumb { display: flex; align-items: center; - gap: var(--sp-2); + gap: var(--sp-1); + font-size: var(--fs-tag); + color: var(--text-muted); + + span { cursor: pointer; transition: color 0.14s ease; } + span:hover { color: var(--edu-primary); } + .bc-sep { cursor: default; color: var(--text-muted); opacity: .5; } + .bc-sep:hover { color: var(--text-muted); } + .bc-current { cursor: default; color: var(--text-body); font-weight: 500; } + .bc-current:hover { color: var(--text-body); } + } + + .head-title-row { + display: flex; + align-items: center; + gap: var(--sp-3); + h1 { margin: 0; color: var(--text-strong); font-size: var(--fs-page); font-weight: 700; + letter-spacing: -0.01em; } } @@ -177,17 +304,17 @@ function toBoolean(value, fallback) { if (value === undefined || value === null :deep(.el-step__line-inner) { border-color: var(--edu-primary); } } - /* ===== 面板 ===== */ + /* ===== 面板(左对齐文档流,不居中悬浮)===== */ .editor-panel { width: 100%; - max-width: 1180px; - margin: auto; + max-width: 1280px; + margin: 0; box-sizing: border-box; h2 { display: flex; align-items: center; gap: var(--sp-2); - margin: 0 0 var(--sp-4); + margin: 0; color: var(--text-strong); font-size: var(--fs-page); font-weight: 700; @@ -195,14 +322,23 @@ function toBoolean(value, fallback) { if (value === undefined || value === null } } - /* ===== 基础设置表单(白卡容器、去彩色边;输入框外观由 teacher-light.scss 全局接管)===== */ - .base-form { - max-width: 820px; - padding: var(--sp-4); + /* ===== 分组白卡(调研结论:逻辑分组 + 呼吸感)===== */ + .section-card { + padding: var(--sp-5); border: 1px solid var(--border-color); border-radius: var(--r-card); background: #ffffff; + } + + .card-head { + margin-bottom: var(--sp-4); + p { margin: var(--sp-1) 0 0; color: var(--text-body); font-size: var(--fs-body); } + } + + /* ===== 基础设置表单(单列 + 成对字段组,呼吸感间距)===== */ + .base-form { :deep(.el-form-item) { margin-bottom: var(--sp-4); } + :deep(.el-form-item:first-child) { margin-bottom: var(--sp-3); } :deep(.el-form-item__label) { color: var(--text-body); font-weight: 600; } :deep(.el-input__count-inner) { color: var(--text-muted); background: transparent; } :deep(.el-input), :deep(.el-select), :deep(.el-date-editor) { width: 100%; } @@ -210,8 +346,91 @@ function toBoolean(value, fallback) { if (value === undefined || value === null :deep(.el-input-number .el-input__wrapper) { padding-right: 58px; } } + .form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--sp-4) var(--sp-5); + } + .unit { margin-left: var(--sp-2); color: var(--text-body); } + /* ===== 分值卡片组(替代旧表格,彩色顶部条)===== */ + .score-cards { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: var(--sp-3); + margin-top: var(--sp-5); + padding-top: var(--sp-4); + border-top: 1px solid var(--border-color); + } + + .score-card { + position: relative; + border: 1px solid var(--border-color); + border-radius: var(--r-control); + background: #ffffff; + overflow: hidden; + transition: border-color 0.16s ease; + + &:hover { border-color: var(--edu-primary); } + } + + .score-card-bar { + height: 3px; + background: var(--border-color); + } + + .score-card-bar, + .bar-total { background: var(--edu-primary); } + + .score-card-body { + padding: var(--sp-3); + display: grid; + gap: var(--sp-1); + } + + .score-card-label { + font-size: var(--fs-tag); + color: var(--text-muted); + font-weight: 500; + } + + .score-card-nums { + display: flex; + align-items: baseline; + gap: var(--sp-1); + } + + .num-picked { + font-size: var(--fs-num); + font-weight: 700; + color: var(--text-strong); + line-height: 1; + } + + .num-sep { + color: var(--text-muted); + font-size: var(--fs-card); + } + + .num-total { + font-size: var(--fs-card); + color: var(--text-body); + } + + .score-card-sub { + font-size: var(--fs-tag); + color: var(--text-body); + } + + .score-card-total { + background: var(--edu-primary-soft); + + .score-card-label { color: var(--edu-primary-deep); } + .num-picked { color: var(--edu-primary); } + .score-card-sub { color: var(--edu-primary-deep); } + } + .section-head { display: flex; align-items: flex-start; @@ -229,118 +448,350 @@ function toBoolean(value, fallback) { if (value === undefined || value === null .import-hint { max-width: 420px; color: var(--text-muted); font-size: var(--fs-tag); line-height: 1.45; text-align: right; } - /* ===== 选择试题 ===== */ - .question-layout { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: var(--sp-4); } + /* ===== 题型 Tab 栏(步骤02选择题型 + 步骤03试卷快速跳转共用)===== */ + .type-tabs { + display: flex; + gap: var(--sp-2); + margin-bottom: var(--sp-4); + padding-bottom: var(--sp-3); + border-bottom: 1px solid var(--border-color); + overflow-x: auto; + } - .type-nav { - align-self: start; - display: grid; - gap: var(--sp-1); - padding: var(--sp-2); + .type-tab { + display: inline-flex; + align-items: center; + gap: var(--sp-2); + padding: 9px var(--sp-4); border: 1px solid var(--border-color); - border-radius: var(--r-card); + border-radius: var(--r-control); background: #ffffff; - button { - appearance: none; - -webkit-appearance: none; - width: 100%; - border: 1px solid transparent; - background: transparent; - padding: var(--sp-3); - display: flex; - justify-content: space-between; - color: var(--text-body); - cursor: pointer; - border-radius: var(--r-control); - font: inherit; - text-align: left; - b { font-weight: 600; color: var(--edu-primary); } - &.active { color: var(--edu-primary-deep); background: var(--edu-primary-soft); } - &:hover { color: var(--text-strong); background: #f9fafb; } - } - } + cursor: pointer; + font: inherit; + font-size: var(--fs-body); + font-weight: 500; + color: var(--text-body); + white-space: nowrap; + transition: all 0.16s ease; + height: 36px; - .question-list { min-width: 0; } + &:hover { border-color: var(--edu-primary); color: var(--edu-primary); } - .question-item { - display: grid; - grid-template-columns: 28px 1fr auto; - gap: var(--sp-2); - padding: var(--sp-4) var(--sp-3); - border-bottom: 1px solid var(--border-color); - &.selected { background: var(--edu-primary-soft); } - h3 { color: var(--text-strong); font-size: var(--fs-card); line-height: 1.6; margin: 0; font-weight: 600; } + &.active { + background: var(--edu-primary); + border-color: var(--edu-primary); + color: #ffffff; + + .type-tab-count { background: rgba(255,255,255,0.2); } + .type-tab-count b { color: #ffffff; } + .type-tab-count em { color: rgba(255,255,255,0.7); } + } } - .options { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--sp-1) var(--sp-4); color: var(--text-body); margin-top: var(--sp-2); } + .type-tab-label { font-weight: 500; } - .score-input { - display: flex; + .type-tab-count { + display: inline-flex; align-items: center; gap: var(--sp-1); + padding: 2px var(--sp-2); + border-radius: var(--r-control); + background: var(--border-color); + font-size: var(--fs-tag); + + b { font-weight: 600; color: var(--edu-primary); font-style: normal; } + em { color: var(--text-muted); font-style: normal; } + } + + .type-tab-nav.type-tab { + border-color: var(--border-color); + background: #ffffff; color: var(--text-body); - :deep(.el-input-number) { width: 104px; } } - /* ===== 试卷概览 ===== */ - .score-summary { + .question-list { display: grid; - grid-template-columns: repeat(5, 1fr); + gap: var(--sp-3); + min-width: 0; + } + + /* 题目卡片 */ + .q-card { + position: relative; + display: flex; + gap: var(--sp-3); + padding: var(--sp-4); border: 1px solid var(--border-color); - border-radius: var(--r-card); - overflow: hidden; - margin-bottom: var(--sp-4); + border-radius: var(--r-control); background: #ffffff; - > div { - padding: var(--sp-4); - border-right: 1px solid var(--border-color); - display: grid; - gap: var(--sp-1); - &:last-child { border-right: 0; } - span { color: var(--text-body); } - small { color: var(--text-body); font-size: var(--fs-tag); } - strong { font-size: var(--fs-num); color: var(--text-strong); } + cursor: pointer; + transition: all 0.18s ease; + overflow: hidden; + + &:hover { border-color: var(--edu-primary); } + + &.is-picked { + border-color: var(--edu-primary); + background: var(--edu-primary-soft); } - .total { background: var(--edu-primary-soft); } } - .anchor-nav { + .q-card-stripe { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background: var(--border-color); + transition: background 0.18s ease; + } + + .q-card.is-picked .q-card-stripe { + background: var(--edu-primary); + } + + .q-card-body { flex: 1; min-width: 0; padding-left: var(--sp-2); } + + .q-card-head { display: flex; + align-items: center; gap: var(--sp-2); - margin: var(--sp-4) 0; - button { - border: 1px solid var(--border-color); - background: #ffffff; - color: var(--text-body); - padding: var(--sp-2) var(--sp-3); - border-radius: var(--r-control); - cursor: pointer; - font-size: var(--fs-body); - &:hover { border-color: var(--edu-primary); color: var(--edu-primary); } + margin-bottom: var(--sp-2); + } + + .q-card-no { + display: inline-grid; + place-items: center; + width: 22px; + height: 22px; + border-radius: 6px; + background: var(--border-color); + color: var(--text-muted); + font-size: var(--fs-tag); + font-weight: 600; + line-height: 1; + } + + .q-card.is-picked .q-card-no { + background: var(--edu-primary); + color: #ffffff; + } + + .q-card-type { + font-size: var(--fs-body); + color: var(--text-muted); + font-weight: 500; + } + + .q-score-chip { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + margin-left: auto; + padding: 2px var(--sp-3); + border-radius: var(--r-control); + background: #ffffff; + border: 1px solid var(--edu-primary); + font-size: var(--fs-tag); + color: var(--edu-primary-deep); + + span { color: var(--edu-primary-deep); font-weight: 500; } + + :deep(.el-input-number) { width: 88px; } + :deep(.el-input-number .el-input__wrapper) { + padding: 2px 6px; + box-shadow: none !important; + background: transparent; + } + :deep(.el-input-number__decrease), + :deep(.el-input-number__increase) { + display: none; } } + .q-card-stem { + margin: 0 0 var(--sp-2); + color: var(--text-strong); + font-size: var(--fs-body); + line-height: 1.6; + font-weight: 500; + } + + .q-options { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--sp-1) var(--sp-3); + } + + .q-option { + display: flex; + gap: 8px; + font-size: var(--fs-tag); + color: var(--text-body); + line-height: 1.5; + } + + .q-option-label { + font-weight: 600; + color: var(--text-muted); + flex-shrink: 0; + } + + .q-card-check { + flex-shrink: 0; + align-self: flex-start; + margin-top: 2px; + } + + .q-check-off { + width: 24px; + height: 24px; + border-radius: 50%; + border: 2px solid var(--text-muted); + display: grid; + place-items: center; + color: var(--text-muted); + font-size: var(--fs-card); + font-weight: 400; + transition: all 0.18s ease; + } + + .q-card:hover .q-check-off { + border-color: var(--edu-primary); + color: var(--edu-primary); + } + + .q-check-on { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--edu-primary); + display: grid; + place-items: center; + color: #ffffff; + transition: all 0.18s ease; + + .el-icon { font-size: var(--fs-card); } + } + + /* ===== 试卷概览(复用 score-cards + 新预览结构)===== */ + .preview-stage { max-width: 1280px; } + + .preview-score-cards { margin-top: var(--sp-4); } + + .score-card-zero { + opacity: 0.5; + .num-picked { color: var(--text-muted); } + .score-card-sub { color: var(--text-muted); } + } + + .preview-body { margin-top: var(--sp-5); } + .paper-section { - scroll-margin-top: var(--sp-5); - border-top: 1px solid var(--border-color); - padding-top: var(--sp-4); - margin-top: var(--sp-5); - h3 { color: var(--text-strong); font-size: var(--fs-page); margin: 0 0 var(--sp-2); } + scroll-margin-top: 80px; + margin-bottom: var(--sp-5); + border: 1px solid var(--border-color); + border-radius: var(--r-control); + background: #ffffff; + overflow: hidden; + } + + .paper-section-head { + display: flex; + align-items: center; + gap: var(--sp-3); + padding: var(--sp-3) var(--sp-4); + background: #ffffff; + border-bottom: 1px solid var(--border-color); + position: relative; + } + + .paper-section-stripe { + width: 4px; + height: 20px; + border-radius: 2px; + background: var(--border-color); + } + + .paper-section-head h3 { + margin: 0; + font-size: var(--fs-card); + font-weight: 600; + color: var(--text-strong); + } + + .paper-section-meta { + margin-left: auto; + font-size: var(--fs-tag); + color: var(--text-muted); + font-weight: 500; + } + + .paper-questions { + display: grid; + gap: var(--sp-1); } - .paper-question { + .pq-card { display: grid; - grid-template-columns: 26px 1fr; - padding: var(--sp-3) 0; + grid-template-columns: 36px 1fr auto; + gap: var(--sp-3); + align-items: start; + padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border-color); - h4 { - margin: 0 0 var(--sp-2); - color: var(--text-strong); - line-height: 1.6; - font-weight: 600; - b { float: right; color: var(--edu-primary-deep); } - } - p { margin: var(--sp-1) 0; color: var(--text-body); } + transition: background 0.14s ease; + + &:last-child { border-bottom: 0; } + &:hover { background: var(--edu-primary-soft); } + } + + .pq-no { + display: grid; + place-items: center; + width: 28px; + height: 28px; + border-radius: var(--r-control); + background: var(--border-color); + color: var(--text-muted); + font-size: var(--fs-card); + font-weight: 600; + flex-shrink: 0; + } + + .pq-body { min-width: 0; } + + .pq-stem { + margin: 0 0 var(--sp-2); + color: var(--text-strong); + font-size: var(--fs-body); + line-height: 1.65; + font-weight: 500; + } + + .pq-options { + display: grid; + gap: var(--sp-1); + } + + .pq-option { + font-size: var(--fs-tag); + color: var(--text-body); + line-height: 1.55; + + b { color: var(--text-muted); font-weight: 600; margin-right: var(--sp-1); } + } + + .pq-score { + display: inline-flex; + align-items: center; + padding: 2px var(--sp-3); + border-radius: var(--r-control); + background: var(--edu-primary-soft); + color: var(--edu-primary-deep); + font-size: var(--fs-tag); + font-weight: 600; + flex-shrink: 0; + margin-top: var(--sp-1); } /* ===== 自定义空状态 ===== */ @@ -388,108 +839,132 @@ function toBoolean(value, fallback) { if (value === undefined || value === null :deep(.el-button) { min-width: 112px; } } - /* ===== master 新版编辑器布局骨架(布局来自 master,配色按教育风令牌重制)===== */ + /* ===== 编辑器步骤条(极简文字式:数字徽标 + 文字 + 箭头,左对齐跟随内容流)===== */ .prototype-nav { display: flex; align-items: center; - justify-content: center; + justify-content: flex-start; gap: var(--sp-4); margin-bottom: var(--sp-4); - :deep(.el-button) { min-width: 150px; } - } - - .prototype-base-panel { - max-width: 1440px; - padding: 0 var(--sp-5) var(--sp-4); - - > h2 { margin-bottom: var(--sp-3); } - - .base-form { - max-width: none; - display: grid; - grid-template-columns: 1.7fr 1.2fr 1.2fr .9fr 1.35fr; - gap: var(--sp-2) var(--sp-4); - padding: 0; + .step-node { + display: inline-flex; + align-items: center; + gap: var(--sp-2); + padding: 6px 2px; border: 0; background: transparent; - box-shadow: none; + color: var(--text-body); + font-size: var(--fs-body); + font-weight: 400; + cursor: pointer; + transition: color 0.16s ease; + + .step-num { + display: inline-grid; + place-items: center; + width: 22px; + height: 22px; + border-radius: 50%; + background: var(--border-color); + color: var(--text-body); + font-size: var(--fs-tag); + font-weight: 600; + transition: all 0.16s ease; + } + + &:hover { + color: var(--text-strong); + + .step-num { + background: var(--edu-primary-soft); + color: var(--edu-primary); + } + } + + &.is-active { + color: var(--edu-primary); + font-weight: 600; + + .step-num { + background: var(--edu-primary); + color: #ffffff; + } + } + } - :deep(.el-form-item) { margin-bottom: var(--sp-2); } - :deep(.el-form-item:first-child) { grid-column: 1 / -1; } + .step-arrow { + color: var(--text-muted); + font-size: var(--fs-card); } } - .score-matrix { - margin-top: var(--sp-2); - border: 1px solid var(--border-color); - border-radius: 12px; - background: #ffffff; - overflow: hidden; + .prototype-base-panel { + max-width: 1280px; + padding: 0 0 var(--sp-4); } - .score-matrix-head, - .score-matrix-row { - display: grid; - grid-template-columns: 1.1fr 1.35fr 1.1fr 1.1fr 1.1fr; - min-height: 42px; - align-items: center; - text-align: center; - } + .settings-stage { max-width: 1280px; } - .score-matrix-head { - color: var(--text-strong); - background: var(--edu-primary-soft); - font-weight: 600; + /* ===== 考试设置:独立设置卡片(替代旧 setting-row 列表)===== */ + .settings-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: var(--sp-3); } - .score-matrix-row { - color: var(--text-body); + .setting-card { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-4); + padding: var(--sp-4) var(--sp-4); + border: 1px solid var(--border-color); + border-radius: var(--r-control); + background: #f9fafb; + transition: all 0.16s ease; - + .score-matrix-row { border-top: 1px solid var(--border-color); } + &:hover { + border-color: var(--edu-primary); + background: #ffffff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); + } } - .score-matrix-head span, - .score-matrix-row span { - padding: 8px 6px; - border-right: 1px solid var(--border-color); - - &:last-child { border-right: 0; } + .setting-card-wide { + grid-column: 1 / -1; } - .settings-stage { max-width: 1180px; } - - .setting-row { + .setting-card-body { display: grid; - grid-template-columns: 280px minmax(0, 1fr); - align-items: center; - min-height: 64px; - border-bottom: 1px solid var(--border-color); - gap: var(--sp-4); - - &:last-child { border-bottom: 0; } - - > span { color: var(--text-strong); font-weight: 600; } + gap: 4px; + min-width: 0; + } - :deep(.el-radio) { color: var(--text-body); margin-right: 0; } - :deep(.el-radio__input.is-checked + .el-radio__label) { color: var(--edu-primary-deep); } + .setting-card-label { + font-size: var(--fs-body); + font-weight: 600; + color: var(--text-strong); } - .multiple-score-row { - align-items: start; - padding: var(--sp-4) 0; + .setting-card-desc { + font-size: var(--fs-tag); + color: var(--text-muted); } @media (max-width: 760px) { .editor-head { - grid-template-columns: 1fr; - gap: var(--sp-3); - .title-block { grid-row: 1; } - > :last-child { justify-self: start; } + display: grid; + gap: var(--sp-2); } - .question-layout { grid-template-columns: 1fr; } - .type-nav { display: flex; overflow-x: auto; } - .score-summary { grid-template-columns: 1fr 1fr; } + .section-card { padding: var(--sp-4); } + .base-form { :deep(.el-form-item) { margin-bottom: var(--sp-3); } } + .form-row { grid-template-columns: 1fr; gap: var(--sp-3); } + .score-cards { grid-template-columns: repeat(2, 1fr); } + .settings-grid { grid-template-columns: 1fr; } + .type-tabs { flex-wrap: wrap; } + .pq-card { grid-template-columns: 28px 1fr; } + .pq-score { grid-column: 1 / -1; justify-self: start; } .section-head { align-items: flex-start; flex-direction: column; gap: var(--sp-3); } .import-tools { justify-items: start; width: 100%; } .import-hint { max-width: none; text-align: left; } diff --git a/src/views/teacherEnd/exam/index.vue b/src/views/teacherEnd/exam/index.vue index b2a9990..b97f00a 100644 --- a/src/views/teacherEnd/exam/index.vue +++ b/src/views/teacherEnd/exam/index.vue @@ -40,7 +40,7 @@ - +