937 lines
27 KiB
Vue
937 lines
27 KiB
Vue
<template>
|
||
<!-- 独立窗口模式 -->
|
||
<div v-if="isIndependent" class="independent-form">
|
||
<div class="independent-header">
|
||
<h2>{{ dialogTitle }}</h2>
|
||
</div>
|
||
<div class="independent-content">
|
||
<div class="program-edit">
|
||
<el-scrollbar height="calc(100vh - 150px)">
|
||
<div class="main">
|
||
<div class="tabsTip">
|
||
<el-icon><InfoFilled /></el-icon>WPS表格处理题目编辑
|
||
</div>
|
||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
||
<el-tab-pane label="基本内容" name="common">
|
||
<div class="line">
|
||
<div class="title-text">试题题目</div>
|
||
<div class="buttons">
|
||
<ElButton type="primary" plain>
|
||
<el-icon><Document /></el-icon>
|
||
更换题目模板
|
||
</ElButton>
|
||
<ElButton type="primary" plain>
|
||
<el-icon><Search /></el-icon>
|
||
预览
|
||
</ElButton>
|
||
</div>
|
||
<div class="block">
|
||
<Editor
|
||
v-model="formData.content"
|
||
:height="150"
|
||
:key="`editor-content-${formType}`"
|
||
/>
|
||
</div>
|
||
<div class="buttons">
|
||
<ElButton type="primary" plain>
|
||
<el-icon><Paperclip /></el-icon>
|
||
添加附件
|
||
</ElButton>
|
||
</div>
|
||
</div>
|
||
<div class="line">
|
||
<div class="title-text">基本信息</div>
|
||
<el-form
|
||
label-width="80px"
|
||
:inline="true"
|
||
label-position="right"
|
||
class="formList"
|
||
>
|
||
<el-form-item label="专业">
|
||
<el-input v-model="formData.specialtyName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="课程">
|
||
<el-input v-model="formData.courseName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="章节">
|
||
<el-input v-model="formData.chapteridDictText" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="科目">
|
||
<el-input v-model="formData.subjectName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="知识点">
|
||
<el-input v-model="formData.pointNames" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="题目类型">
|
||
<el-input v-model="formData.quType" placeholder="WPS表格处理题目" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="难度">
|
||
<el-select
|
||
v-model="formData.quLevel"
|
||
placeholder="请选择难度"
|
||
style="width: 200px"
|
||
>
|
||
<el-option
|
||
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="文件管理" name="files">
|
||
<div class="line">
|
||
<div class="title-text">上传Excel文件</div>
|
||
<div class="buttons">
|
||
<el-upload
|
||
ref="uploadRef"
|
||
:action="uploadAction"
|
||
:headers="uploadHeaders"
|
||
:data="{ type: 'excel' }"
|
||
:before-upload="beforeUpload"
|
||
:on-success="handleUploadSuccess"
|
||
:show-file-list="false"
|
||
accept=".xls,.xlsx"
|
||
>
|
||
<ElButton type="primary">
|
||
<el-icon><Upload /></el-icon>
|
||
上传Excel文件
|
||
</ElButton>
|
||
</el-upload>
|
||
<ElButton
|
||
type="success"
|
||
@click="parseExcelFile"
|
||
:disabled="!formData.excelFileUrl"
|
||
>
|
||
<el-icon><View /></el-icon>
|
||
解析文件
|
||
</ElButton>
|
||
</div>
|
||
<div class="file-info" v-if="formData.excelFileUrl">
|
||
<p>已上传文件: {{ formData.excelFileName }}</p>
|
||
<p>文件路径: {{ formData.excelFileUrl }}</p>
|
||
</div>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</div>
|
||
</el-scrollbar>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="independent-footer">
|
||
<el-button @click="submitForm" :loading="formLoading" :disabled="formLoading">
|
||
{{ formLoading ? '提交中...' : '确 定' }}
|
||
</el-button>
|
||
<el-button @click="handleCancel">取 消</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 对话框模式 -->
|
||
<el-dialog
|
||
v-else
|
||
v-model="dialogVisible"
|
||
:title="dialogTitle"
|
||
width="80%"
|
||
:before-close="handleCancel"
|
||
destroy-on-close
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form
|
||
ref="formRef"
|
||
:model="formData"
|
||
:rules="formRules"
|
||
label-width="120px"
|
||
class="question-form"
|
||
v-loading="formLoading"
|
||
>
|
||
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
|
||
<!-- 基本信息 -->
|
||
<el-tab-pane label="基本信息" name="common">
|
||
<div class="form-section">
|
||
<div class="section-title">题目信息</div>
|
||
<div class="form-grid">
|
||
<el-form-item label="专业" prop="specialtyName">
|
||
<el-input v-model="formData.specialtyName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="课程" prop="courseName">
|
||
<el-input v-model="formData.courseName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="章节" prop="chapteridDictText">
|
||
<el-input v-model="formData.chapteridDictText" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="科目" prop="subjectName">
|
||
<el-input v-model="formData.subjectName" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="知识点" prop="pointNames">
|
||
<el-input v-model="formData.pointNames" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="题目类型" prop="quType">
|
||
<el-input v-model="formData.quType" placeholder="WPS表格处理题目" readonly />
|
||
</el-form-item>
|
||
<el-form-item label="难度" prop="quLevel">
|
||
<el-select v-model="formData.quLevel" placeholder="请选择难度" style="width: 60px">
|
||
<el-option
|
||
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section">
|
||
<div class="section-title">题目内容</div>
|
||
<el-form-item label="题目描述" prop="content">
|
||
<Editor v-model="formData.content" :height="200" />
|
||
</el-form-item>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<!-- 文件管理 -->
|
||
<el-tab-pane label="文件管理" name="files">
|
||
<div class="form-section">
|
||
<div class="section-title">Excel文件上传</div>
|
||
<el-form-item label="上传Excel文件">
|
||
<el-upload
|
||
ref="uploadRef"
|
||
:action="uploadAction"
|
||
:headers="uploadHeaders"
|
||
:data="{ type: 'excel' }"
|
||
:before-upload="beforeUpload"
|
||
:on-success="handleUploadSuccess"
|
||
:show-file-list="false"
|
||
accept=".xls,.xlsx"
|
||
>
|
||
<el-button type="primary">
|
||
<el-icon><Upload /></el-icon>
|
||
选择Excel文件
|
||
</el-button>
|
||
</el-upload>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="文件信息" v-if="formData.excelFileUrl">
|
||
<div class="file-info">
|
||
<p><strong>文件名:</strong> {{ formData.excelFileName }}</p>
|
||
<p><strong>文件路径:</strong> {{ formData.excelFileUrl }}</p>
|
||
<el-button type="success" @click="parseExcelFile" size="small">
|
||
<el-icon><View /></el-icon>
|
||
解析文件内容
|
||
</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button @click="submitForm" :loading="formLoading" :disabled="formLoading">
|
||
{{ formLoading ? '提交中...' : '确 定' }}
|
||
</el-button>
|
||
<el-button @click="handleCancel">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ElMessage } from 'element-plus'
|
||
import { useI18n } from '@/hooks/web/useI18n'
|
||
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
|
||
import { getAccessToken } from '@/utils/auth'
|
||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||
import * as QuestionApi from '@/api/paper/question'
|
||
import { Editor } from '@/components/Editor'
|
||
import { InfoFilled, Document, Search, Paperclip, Upload, View } from '@element-plus/icons-vue'
|
||
|
||
defineOptions({ name: 'WpsXlsxForm' })
|
||
|
||
const { t } = useI18n()
|
||
|
||
// 组件参数
|
||
interface Props {
|
||
isIndependent?: boolean
|
||
}
|
||
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
isIndependent: false
|
||
})
|
||
|
||
const emit = defineEmits(['success'])
|
||
|
||
// 基础状态
|
||
const dialogVisible = ref(false)
|
||
const dialogTitle = ref('')
|
||
const formType = ref('')
|
||
const formLoading = ref(false)
|
||
const formRef = ref()
|
||
const activeName = ref('common')
|
||
|
||
// 表单数据
|
||
const formData = ref({
|
||
quId: undefined,
|
||
content: '',
|
||
specialtyName: '',
|
||
courseName: '',
|
||
subjectName: '',
|
||
chapteridDictText: '',
|
||
pointNames: '',
|
||
chapteridDictTextVo: '',
|
||
pointNamesVo: '',
|
||
quType: 'WPS表格处理题目',
|
||
quLevel: '',
|
||
excelFileUrl: '',
|
||
excelFileName: '',
|
||
parsedContent: ''
|
||
})
|
||
|
||
// 表单验证规则
|
||
const formRules = reactive({
|
||
content: [{ required: true, message: '请输入题目内容', trigger: 'blur' }]
|
||
})
|
||
|
||
// 上传相关
|
||
const uploadAction = computed(() => import.meta.env.VITE_UPLOAD_URL)
|
||
const uploadHeaders = computed(() => ({
|
||
Authorization: 'Bearer ' + getAccessToken()
|
||
}))
|
||
|
||
// 独立窗口相关
|
||
let isListeningForInit = false
|
||
|
||
onMounted(async () => {
|
||
if (props.isIndependent && !isListeningForInit) {
|
||
isListeningForInit = true
|
||
|
||
// 发送窗口准备就绪信号
|
||
try {
|
||
const { emit: emitEvent } = await import('@tauri-apps/api/event')
|
||
await emitEvent('wps-xlsx-window-ready', { message: 'Excel form window is ready' })
|
||
console.log('Excel form window ready signal sent')
|
||
} catch (error) {
|
||
console.error('Failed to send window ready signal:', error)
|
||
}
|
||
|
||
// 监听初始化事件
|
||
try {
|
||
const { listen } = await import('@tauri-apps/api/event')
|
||
|
||
await listen('init-wps-xlsx-form', (event: any) => {
|
||
console.log('Received init-wps-xlsx-form event:', event.payload)
|
||
const { queryParams, type, id } = event.payload
|
||
|
||
nextTick(() => {
|
||
open(queryParams, type, id)
|
||
})
|
||
})
|
||
|
||
// 请求初始化数据
|
||
const { emit: emitEvent } = await import('@tauri-apps/api/event')
|
||
await emitEvent('request-wps-xlsx-init', { message: 'Requesting Excel form initialization' })
|
||
console.log('Requested Excel form initialization')
|
||
} catch (error) {
|
||
console.error('Failed to set up Tauri event listeners:', error)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 表单操作
|
||
const resetForm = () => {
|
||
formData.value = {
|
||
quId: undefined,
|
||
content: '',
|
||
specialtyName: '',
|
||
courseName: '',
|
||
subjectName: '',
|
||
chapteridDictText: '',
|
||
pointNames: '',
|
||
chapteridDictTextVo: '',
|
||
pointNamesVo: '',
|
||
quType: 'WPS表格处理题目',
|
||
quLevel: '',
|
||
excelFileUrl: '',
|
||
excelFileName: '',
|
||
parsedContent: ''
|
||
}
|
||
|
||
if (formRef.value) {
|
||
formRef.value.resetFields()
|
||
}
|
||
}
|
||
|
||
const handleClick = (tab: any) => {
|
||
activeName.value = tab.name
|
||
}
|
||
|
||
const handleCancel = async () => {
|
||
if (props.isIndependent) {
|
||
// 独立窗口模式:发送取消事件并关闭窗口
|
||
try {
|
||
const { emit } = await import('@tauri-apps/api/event')
|
||
const { getCurrentWindow } = await import('@tauri-apps/api/window')
|
||
|
||
await emit('wps-xlsx-form-cancel')
|
||
const appWindow = getCurrentWindow()
|
||
await appWindow.close()
|
||
} catch (error) {
|
||
console.error('Failed to close independent window:', error)
|
||
}
|
||
} else {
|
||
// 对话框模式
|
||
dialogVisible.value = false
|
||
}
|
||
}
|
||
|
||
// 文件上传处理
|
||
const beforeUpload = (file: File) => {
|
||
const isExcel =
|
||
file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
|
||
file.type === 'application/vnd.ms-excel'
|
||
if (!isExcel) {
|
||
ElMessage.error('只能上传Excel文件!')
|
||
return false
|
||
}
|
||
const isLt10M = file.size / 1024 / 1024 < 10
|
||
if (!isLt10M) {
|
||
ElMessage.error('文件大小不能超过10MB!')
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
const handleUploadSuccess = (response: any) => {
|
||
if (response.code === 0) {
|
||
formData.value.excelFileUrl = response.data.url
|
||
formData.value.excelFileName = response.data.fileName
|
||
ElMessage.success('文件上传成功!')
|
||
} else {
|
||
ElMessage.error('文件上传失败: ' + response.msg)
|
||
}
|
||
}
|
||
|
||
const parseExcelFile = async () => {
|
||
if (!formData.value.excelFileUrl) {
|
||
ElMessage.warning('请先上传Excel文件')
|
||
return
|
||
}
|
||
|
||
try {
|
||
formLoading.value = true
|
||
// 临时注释掉API调用,直接显示成功
|
||
// const response = await WpsApi.getXlsxDataInfo({
|
||
// filePath: formData.value.excelFileUrl
|
||
// })
|
||
|
||
formData.value.parsedContent = '文件解析成功 - ' + formData.value.excelFileName
|
||
ElMessage.success('Excel文件解析成功!')
|
||
} catch (error) {
|
||
console.error('解析Excel文件失败:', error)
|
||
ElMessage.error('Excel文件解析失败')
|
||
} finally {
|
||
formLoading.value = false
|
||
}
|
||
}
|
||
|
||
// 提交表单
|
||
const submitForm = async () => {
|
||
console.log('WpsXlsxForm submitForm called, isIndependent:', props.isIndependent)
|
||
|
||
// 独立窗口模式下,基于表单数据进行简单验证
|
||
if (props.isIndependent) {
|
||
// 基本必填项检查
|
||
if (!formData.value.content) {
|
||
ElMessage.warning('请填写题目内容')
|
||
return
|
||
}
|
||
} else {
|
||
// 对话框模式下,使用formRef验证
|
||
if (!formRef.value) return
|
||
const valid = await formRef.value.validate().catch(() => false)
|
||
if (!valid) return
|
||
}
|
||
|
||
formLoading.value = true
|
||
try {
|
||
const dataToSubmit = JSON.parse(JSON.stringify(formData.value))
|
||
|
||
// 确保基础必需字段
|
||
dataToSubmit.quLevel = dataToSubmit.quLevel || 0
|
||
dataToSubmit.status = dataToSubmit.status || '0'
|
||
|
||
// 确保字符串字段不为undefined
|
||
dataToSubmit.specialtyName = dataToSubmit.specialtyName || ''
|
||
dataToSubmit.courseName = dataToSubmit.courseName || ''
|
||
dataToSubmit.subjectName = dataToSubmit.subjectName || ''
|
||
dataToSubmit.pointNames = dataToSubmit.pointNames || ''
|
||
dataToSubmit.chapteridDictText = dataToSubmit.chapteridDictText || ''
|
||
dataToSubmit.analysis = dataToSubmit.analysis || ''
|
||
dataToSubmit.resourceValue = dataToSubmit.resourceValue || ''
|
||
|
||
console.log('Submitting WPS Excel data:', dataToSubmit)
|
||
|
||
if (formType.value === 'create') {
|
||
await QuestionApi.addQuestion(dataToSubmit)
|
||
ElMessage.success(t('common.createSuccess'))
|
||
} else {
|
||
await QuestionApi.editQuestion(dataToSubmit)
|
||
ElMessage.success(t('common.updateSuccess'))
|
||
}
|
||
|
||
if (props.isIndependent) {
|
||
// 独立窗口模式:发送成功事件并关闭窗口
|
||
try {
|
||
const { emit: tauriEmit } = await import('@tauri-apps/api/event')
|
||
const { getCurrentWindow } = await import('@tauri-apps/api/window')
|
||
|
||
await tauriEmit('wps-xlsx-form-success')
|
||
const appWindow = getCurrentWindow()
|
||
await appWindow.close()
|
||
} catch (error) {
|
||
console.error('Failed to close independent window:', error)
|
||
}
|
||
} else {
|
||
// 对话框模式
|
||
dialogVisible.value = false
|
||
emit('success')
|
||
}
|
||
} catch (error: any) {
|
||
console.error('Submit error:', error)
|
||
|
||
// 更详细的错误处理
|
||
let errorMessage = '提交失败'
|
||
if (error?.response?.data?.msg) {
|
||
errorMessage += ':' + error.response.data.msg
|
||
} else if (error?.message) {
|
||
errorMessage += ':' + error.message
|
||
} else if (typeof error === 'string') {
|
||
errorMessage += ':' + error
|
||
} else {
|
||
errorMessage += ':未知错误'
|
||
}
|
||
|
||
ElMessage.error(errorMessage)
|
||
} finally {
|
||
formLoading.value = false
|
||
}
|
||
}
|
||
|
||
// 打开表单
|
||
const open = async (queryParams: any, type: string, id?: number) => {
|
||
if (!props.isIndependent) {
|
||
dialogVisible.value = true
|
||
}
|
||
dialogTitle.value = t('action.' + type)
|
||
formType.value = type
|
||
resetForm()
|
||
|
||
if (id) {
|
||
formLoading.value = true
|
||
try {
|
||
const res = await QuestionApi.getQuestion(id)
|
||
formData.value = { ...formData.value, ...res }
|
||
} finally {
|
||
formLoading.value = false
|
||
}
|
||
} else {
|
||
formData.value.specialtyName = queryParams.specialtyName
|
||
formData.value.courseName = queryParams.courseName
|
||
formData.value.subjectName = queryParams.subjectName
|
||
formData.value.pointNames = queryParams.pointNamesVo
|
||
formData.value.pointNamesVo = queryParams.pointNames
|
||
formData.value.chapteridDictText = queryParams.chapteridDictTextVo
|
||
formData.value.chapteridDictTextVo = queryParams.chapteridDictText
|
||
}
|
||
}
|
||
|
||
defineExpose({ open })
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
// 独立窗口模式样式
|
||
.independent-form {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: var(--app-content-bg-color);
|
||
overflow: hidden;
|
||
|
||
.independent-header {
|
||
background: var(--el-bg-color);
|
||
border-bottom: 1px solid var(--el-border-color);
|
||
padding: 16px 24px;
|
||
box-shadow: var(--el-box-shadow-light);
|
||
|
||
h2 {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: var(--el-text-color-primary);
|
||
}
|
||
}
|
||
|
||
.independent-content {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
background: var(--el-bg-color);
|
||
margin: 16px 16px 0 16px;
|
||
border-radius: 8px;
|
||
box-shadow: var(--el-box-shadow);
|
||
|
||
.program-edit {
|
||
height: 100%;
|
||
padding: 20px;
|
||
|
||
.main {
|
||
height: 100%;
|
||
position: relative;
|
||
|
||
.tabsTip {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
color: #4f9dfd;
|
||
line-height: 100%;
|
||
text-align: center;
|
||
align-items: center;
|
||
display: flex;
|
||
background: rgba(79, 157, 253, 0.1);
|
||
padding: 8px 12px;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
z-index: 10;
|
||
}
|
||
|
||
.el-tabs {
|
||
height: 100%;
|
||
padding-top: 40px; // 为tabsTip预留空间
|
||
|
||
:deep(.el-tabs__header) {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
:deep(.el-tabs__content) {
|
||
height: calc(100% - 60px);
|
||
overflow-y: auto;
|
||
padding-right: 8px;
|
||
|
||
.line {
|
||
margin-bottom: 24px;
|
||
|
||
.title-text {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
margin-bottom: 12px;
|
||
color: var(--el-text-color-primary);
|
||
padding-bottom: 8px;
|
||
border-bottom: 2px solid var(--el-border-color);
|
||
}
|
||
|
||
.buttons {
|
||
margin: 16px 0;
|
||
display: flex;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.block {
|
||
padding: 16px;
|
||
background: var(--el-fill-color-lighter);
|
||
border-radius: 6px;
|
||
border: 1px solid var(--el-border-color);
|
||
}
|
||
|
||
.formList {
|
||
background: var(--el-fill-color-lighter);
|
||
padding: 20px;
|
||
border-radius: 6px;
|
||
border: 1px solid var(--el-border-color);
|
||
}
|
||
|
||
.file-info {
|
||
background: rgba(79, 157, 253, 0.1);
|
||
border: 1px solid #4f9dfd;
|
||
border-radius: 6px;
|
||
padding: 16px;
|
||
color: #4f9dfd;
|
||
|
||
p {
|
||
margin: 4px 0;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.independent-footer {
|
||
background: #ffffff !important;
|
||
border-top: 1px solid #e4e7ed !important;
|
||
margin: 0 16px 16px 16px !important;
|
||
padding: 16px 24px !important;
|
||
display: flex !important;
|
||
justify-content: flex-end !important;
|
||
gap: 12px !important;
|
||
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1) !important;
|
||
z-index: 1000 !important;
|
||
border-radius: 0 0 8px 8px !important;
|
||
|
||
.el-button {
|
||
border-radius: 6px !important;
|
||
font-weight: 500 !important;
|
||
padding: 10px 20px !important;
|
||
font-size: 14px !important;
|
||
transition: all 0.3s !important;
|
||
min-width: 80px !important;
|
||
height: 36px !important;
|
||
|
||
&:first-child {
|
||
background: #409eff !important;
|
||
border-color: #409eff !important;
|
||
color: #ffffff !important;
|
||
|
||
&:hover {
|
||
background: #66b1ff !important;
|
||
border-color: #66b1ff !important;
|
||
color: #ffffff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #3a8ee6 !important;
|
||
border-color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
|
||
&:last-child {
|
||
background: #ffffff !important;
|
||
border: 1px solid #dcdfe6 !important;
|
||
color: #606266 !important;
|
||
|
||
&:hover {
|
||
background: #ecf5ff !important;
|
||
border-color: #409eff !important;
|
||
color: #409eff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #e6f7ff !important;
|
||
border-color: #3a8ee6 !important;
|
||
color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 对话框模式样式 */
|
||
.question-form {
|
||
max-height: 60vh;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.form-section {
|
||
margin-bottom: 24px;
|
||
padding: 20px;
|
||
background: var(--el-fill-color-lighter);
|
||
border-radius: 8px;
|
||
border: 1px solid var(--el-border-color);
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--el-text-color-primary);
|
||
margin-bottom: 16px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 2px solid var(--el-border-color);
|
||
}
|
||
|
||
.form-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 16px;
|
||
}
|
||
|
||
.file-info {
|
||
background: rgba(79, 157, 253, 0.1);
|
||
border: 1px solid #4f9dfd;
|
||
border-radius: 6px;
|
||
padding: 16px;
|
||
color: #4f9dfd;
|
||
|
||
p {
|
||
margin: 4px 0;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.dialog-footer {
|
||
display: flex !important;
|
||
justify-content: flex-end !important;
|
||
gap: 12px !important;
|
||
padding: 16px 0 !important;
|
||
|
||
.el-button {
|
||
border-radius: 6px !important;
|
||
font-weight: 500 !important;
|
||
padding: 10px 20px !important;
|
||
font-size: 14px !important;
|
||
transition: all 0.3s !important;
|
||
min-width: 80px !important;
|
||
height: 36px !important;
|
||
|
||
&:first-child {
|
||
background: #409eff !important;
|
||
border-color: #409eff !important;
|
||
color: #ffffff !important;
|
||
|
||
&:hover {
|
||
background: #66b1ff !important;
|
||
border-color: #66b1ff !important;
|
||
color: #ffffff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #3a8ee6 !important;
|
||
border-color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
|
||
&:last-child {
|
||
background: #ffffff !important;
|
||
border: 1px solid #dcdfe6 !important;
|
||
color: #606266 !important;
|
||
|
||
&:hover {
|
||
background: #ecf5ff !important;
|
||
border-color: #409eff !important;
|
||
color: #409eff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #e6f7ff !important;
|
||
border-color: #3a8ee6 !important;
|
||
color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 全局按钮样式强制覆盖 */
|
||
.el-button {
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
border-radius: 6px !important;
|
||
font-weight: 500 !important;
|
||
padding: 10px 20px !important;
|
||
font-size: 14px !important;
|
||
transition: all 0.3s !important;
|
||
min-width: 80px !important;
|
||
height: 36px !important;
|
||
border: 1px solid !important;
|
||
cursor: pointer !important;
|
||
text-decoration: none !important;
|
||
outline: none !important;
|
||
opacity: 1 !important;
|
||
visibility: visible !important;
|
||
|
||
&.el-button--primary {
|
||
background: #409eff !important;
|
||
border-color: #409eff !important;
|
||
color: #ffffff !important;
|
||
|
||
&:hover {
|
||
background: #66b1ff !important;
|
||
border-color: #66b1ff !important;
|
||
color: #ffffff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #3a8ee6 !important;
|
||
border-color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
|
||
&.el-button--default {
|
||
background: #ffffff !important;
|
||
border-color: #dcdfe6 !important;
|
||
color: #606266 !important;
|
||
|
||
&:hover {
|
||
background: #ecf5ff !important;
|
||
border-color: #409eff !important;
|
||
color: #409eff !important;
|
||
}
|
||
|
||
&:active {
|
||
background: #e6f7ff !important;
|
||
border-color: #3a8ee6 !important;
|
||
color: #3a8ee6 !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 全局样式 */
|
||
:deep(.el-tabs) {
|
||
.el-tabs__header {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
background: var(--el-bg-color);
|
||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.el-tabs__item {
|
||
padding: 0 20px;
|
||
height: 40px;
|
||
line-height: 40px;
|
||
font-weight: 500;
|
||
|
||
&.is-active {
|
||
color: var(--el-color-primary);
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.el-tabs__active-bar {
|
||
height: 3px;
|
||
border-radius: 2px;
|
||
}
|
||
|
||
.el-tabs__content {
|
||
padding-top: 20px;
|
||
}
|
||
}
|
||
|
||
:deep(.el-form-item__label) {
|
||
font-weight: 500;
|
||
color: var(--el-text-color-primary);
|
||
}
|
||
|
||
:deep(.el-input),
|
||
:deep(.el-select) {
|
||
width: 100%;
|
||
}
|
||
|
||
:deep(.demo-tabs) {
|
||
margin-top: 16px;
|
||
}
|
||
|
||
:deep(.demo-tabs .el-tabs__header) {
|
||
margin: 0 0 20px 0;
|
||
}
|
||
</style>
|