forked from liweijie/education
741 lines
26 KiB
Vue
741 lines
26 KiB
Vue
<template>
|
||
<div class="app-container management-page subject-page">
|
||
|
||
<!-- ==================== 2. 查询条件区域 ==================== -->
|
||
<el-card shadow="never" class="search-card">
|
||
<div class="section-heading">
|
||
<div>
|
||
<h2 class="section-title">筛选条件</h2>
|
||
<p class="section-description">按课程名称、代码和培训属性筛选课程科目</p>
|
||
</div>
|
||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||
</div>
|
||
<el-form :model="searchForm">
|
||
<el-row :gutter="32">
|
||
<!-- 左栏 -->
|
||
<el-col :xs="24" :md="12">
|
||
<div class="query-field">
|
||
<span class="q-label no-check">课名称</span>
|
||
<el-input v-model="searchForm.kmc" placeholder="请输入课名称" clearable class="q-control" />
|
||
</div>
|
||
<div class="query-field">
|
||
<span class="q-label no-check">科目代码</span>
|
||
<el-input v-model="searchForm.kmdm" placeholder="请输入科目代码" clearable class="q-control" />
|
||
</div>
|
||
<div class="query-field">
|
||
<span class="q-label no-check">培训层次</span>
|
||
<el-input v-model="searchForm.pxcc" placeholder="请输入培训层次" clearable class="q-control" />
|
||
</div>
|
||
<div class="query-field">
|
||
<span class="q-label no-check">课程类型</span>
|
||
<el-input v-model="searchForm.kclx" placeholder="请输入课程类型" clearable class="q-control" />
|
||
</div>
|
||
</el-col>
|
||
|
||
<!-- 右栏 -->
|
||
<el-col :xs="24" :md="12">
|
||
<div class="query-field">
|
||
<span class="q-label no-check">简称</span>
|
||
<el-input v-model="searchForm.jc" placeholder="请输入简称" clearable class="q-control" />
|
||
</div>
|
||
<div class="query-field">
|
||
<span class="q-label no-check">教研室代号</span>
|
||
<el-input v-model="searchForm.jysdh" placeholder="请输入教研室代号" clearable class="q-control" />
|
||
</div>
|
||
<div class="query-field">
|
||
<span class="q-label no-check">培训类型</span>
|
||
<el-input v-model="searchForm.pxlx" placeholder="请输入培训类型" clearable class="q-control" />
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
|
||
</el-card>
|
||
|
||
<!-- ==================== 3. 操作按钮区域 ==================== -->
|
||
<el-card shadow="never" class="action-card">
|
||
<div class="section-heading section-heading--compact">
|
||
<div>
|
||
<h2 class="section-title">课程科目操作</h2>
|
||
<p class="section-description">维护课程科目,或下载业务数据与导入模板</p>
|
||
</div>
|
||
</div>
|
||
<div class="action-row">
|
||
<el-button type="primary" icon="el-icon-plus" @click="handleOpenDialog">新建课程科目</el-button>
|
||
<el-button type="danger" plain icon="el-icon-delete" @click="handleBatchDelete">删除所选</el-button>
|
||
</div>
|
||
<div class="action-row">
|
||
<el-button icon="el-icon-download" @click="handleDownloadTemplate">【课程科目数据文件模板】下载</el-button>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- ==================== 4. 文件上传区域 ==================== -->
|
||
<el-card shadow="never" class="upload-card">
|
||
<div class="section-heading section-heading--compact">
|
||
<div>
|
||
<h2 class="section-title">数据导入</h2>
|
||
<p class="section-description">选择填写完成的课程科目模板并上传</p>
|
||
</div>
|
||
</div>
|
||
<div class="upload-row">
|
||
<div class="upload-left">
|
||
<el-button icon="el-icon-folder-opened" @click="handleSelectFile">选择文件</el-button>
|
||
<span class="file-name" :class="{ 'has-file': selectedFile }">{{ fileName }}</span>
|
||
<input ref="fileInputRef" type="file" style="display: none" @change="handleFileChange" />
|
||
</div>
|
||
<div class="upload-right">
|
||
<el-checkbox v-model="coverExist">覆盖已存在课程科目</el-checkbox>
|
||
<el-button type="primary" icon="el-icon-upload2" @click="handleUpload">上传数据</el-button>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- ==================== 6. 数据表格区域 ==================== -->
|
||
<el-card shadow="never" class="table-card">
|
||
<div class="section-heading section-heading--compact table-heading">
|
||
<div>
|
||
<h2 class="section-title">课程科目列表</h2>
|
||
<p class="section-description">共 {{ total }} 条数据</p>
|
||
</div>
|
||
</div>
|
||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
|
||
@selection-change="handleSelectionChange">
|
||
<el-table-column type="selection" width="40" align="center" />
|
||
<el-table-column prop="kbh" label="课编号" width="130" show-overflow-tooltip />
|
||
<el-table-column prop="kmc" label="课名称" width="200" show-overflow-tooltip />
|
||
<el-table-column prop="jc" label="简称" width="130" show-overflow-tooltip />
|
||
<el-table-column prop="jysdh" label="教研室代号" width="150" show-overflow-tooltip />
|
||
<el-table-column prop="kclx" label="课程类型" width="150" align="center" />
|
||
<el-table-column prop="pxlx" label="培训类型" width="150" align="center" />
|
||
<el-table-column prop="pxcc" label="培训层次" width="200" align="center" />
|
||
<el-table-column prop="xf" label="学分" align="center" />
|
||
<el-table-column prop="xs" label="学时" width="160" align="center" />
|
||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||
<template slot-scope="{ row }">
|
||
<el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button>
|
||
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<el-pagination
|
||
:current-page="pageNum"
|
||
:page-size="pageSize"
|
||
:total="total"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
class="pagination-wrapper"
|
||
@current-change="handlePageChange"
|
||
@size-change="handleSizeChange"
|
||
/>
|
||
</el-card>
|
||
|
||
<!-- 新增/编辑课程科目弹窗 -->
|
||
<el-dialog
|
||
:visible="dialogVisible"
|
||
:title="dialogTitle"
|
||
width="1000px"
|
||
:close-on-click-modal="false"
|
||
class="add-dialog"
|
||
@update:visible="val => dialogVisible = val"
|
||
>
|
||
<el-form ref="addFormRef" :model="addForm" :rules="rules" label-width="120px" class="add-form" :status-icon="false">
|
||
<el-row :gutter="24">
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课编号" prop="kbh">
|
||
<el-input v-model="addForm.kbh" :disabled="isEdit" placeholder="新增时留空自动生成" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课名称" prop="kmc">
|
||
<el-input v-model="addForm.kmc" placeholder="请输入课名称" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="简称" prop="jc">
|
||
<el-input v-model="addForm.jc" placeholder="请输入简称" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="教研室代号" prop="jysdh">
|
||
<el-input v-model="addForm.jysdh" placeholder="请输入教研室代号" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="学分" prop="xf">
|
||
<el-input-number v-model="addForm.xf" :min="0" :precision="1" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="学时" prop="xs">
|
||
<el-input-number v-model="addForm.xs" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="培训层次" prop="pxcc">
|
||
<el-input v-model="addForm.pxcc" placeholder="请输入培训层次" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="培训类型" prop="pxlx">
|
||
<el-input v-model="addForm.pxlx" placeholder="请输入培训类型" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课程类型" prop="kclx">
|
||
<el-input v-model="addForm.kclx" placeholder="请输入课程类型" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="考试课时" prop="ksks">
|
||
<el-input-number v-model="addForm.ksks" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="成绩分制" prop="cjfz">
|
||
<el-input v-model="addForm.cjfz" placeholder="请输入成绩分制" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="不计入学员平均分" prop="bjrxypjf">
|
||
<el-select v-model="addForm.bjrxypjf" class="w-full">
|
||
<el-option label="否" :value="0" />
|
||
<el-option label="是" :value="1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="理论学时" prop="llxs">
|
||
<el-input-number v-model="addForm.llxs" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="实践学时" prop="sjxs">
|
||
<el-input-number v-model="addForm.sjxs" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="周课时" prop="zks">
|
||
<el-input-number v-model="addForm.zks" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课类型" prop="klx">
|
||
<el-input v-model="addForm.klx" placeholder="请输入课类型" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="考试课时不显示" prop="ksksbxs">
|
||
<el-select v-model="addForm.ksksbxs" class="w-full">
|
||
<el-option label="否" :value="0" />
|
||
<el-option label="是" :value="1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课程统一编号" prop="kctybh">
|
||
<el-input v-model="addForm.kctybh" placeholder="请输入课程统一编号" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="辅导答疑课时" prop="fddyks">
|
||
<el-input-number v-model="addForm.fddyks" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="自修课时" prop="zxks">
|
||
<el-input-number v-model="addForm.zxks" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="修订日期" prop="xdrq">
|
||
<el-input v-model="addForm.xdrq" placeholder="如 2026-08-24" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="节次优选级" prop="jcyxj">
|
||
<el-input v-model="addForm.jcyxj" placeholder="请输入节次优选级" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课程支持方式" prop="kczcfs">
|
||
<el-input v-model="addForm.kczcfs" placeholder="请输入课程支持方式" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="课程建设方式" prop="kcjsfs">
|
||
<el-input v-model="addForm.kcjsfs" placeholder="请输入课程建设方式" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="政治类课程" prop="zzlkc">
|
||
<el-select v-model="addForm.zzlkc" class="w-full">
|
||
<el-option label="否" :value="0" />
|
||
<el-option label="是" :value="1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="考核方式" prop="khfs">
|
||
<el-input v-model="addForm.khfs" placeholder="请输入考核方式" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="形成性成绩分值" prop="xcxcjfz">
|
||
<el-input-number v-model="addForm.xcxcjfz" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="终结性成绩分值" prop="zjxcjfz">
|
||
<el-input-number v-model="addForm.zjxcjfz" :min="0" controls-position="right" class="w-full" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="密级" prop="mj">
|
||
<el-input v-model="addForm.mj" placeholder="请输入密级" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="8">
|
||
<el-form-item label="评选情况" prop="pxqk">
|
||
<el-input v-model="addForm.pxqk" placeholder="请输入评选情况" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="24" :md="24">
|
||
<el-form-item label="备注">
|
||
<el-input v-model="addForm.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<div slot="footer">
|
||
<div class="dialog-footer">
|
||
<el-button @click="handleCancel">取消</el-button>
|
||
<el-button type="primary" :loading="addLoading" @click="handleSubmit">保存</el-button>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { saveAs } from 'file-saver'
|
||
import { listKb as listSubject, addKb as addSubject, updateKb as updateSubject, deleteKb as deleteSubject, getKb, downloadCourseSubjectTemplate } from '@/api/teachOffice/kb'
|
||
|
||
export default {
|
||
name: 'SubjectIndex',
|
||
data() {
|
||
return {
|
||
// ==================== 1. 顶部状态提示 ====================
|
||
statusTip: '请输入查询条件',
|
||
|
||
// ==================== 2. 查询条件 ====================
|
||
searchForm: {
|
||
kmc: '',
|
||
jc: '',
|
||
kmdm: '',
|
||
jysdh: '',
|
||
kclx: '',
|
||
pxlx: '',
|
||
pxcc: ''
|
||
},
|
||
|
||
// ==================== 列表数据 ====================
|
||
loading: false,
|
||
tableData: [],
|
||
total: 0,
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
selectedRows: [],
|
||
|
||
// ==================== 文件上传 ====================
|
||
selectedFile: null,
|
||
coverExist: false,
|
||
|
||
// ==================== 新增/编辑弹窗 ====================
|
||
dialogVisible: false,
|
||
addLoading: false,
|
||
isEdit: false,
|
||
addForm: this.createEmptyForm(),
|
||
rules: {
|
||
kmc: [{ required: true, message: '请输入课名称', trigger: 'blur' }],
|
||
jysdh: [{ required: true, message: '请输入教研室代号', trigger: 'blur' }],
|
||
xf: [{ required: true, message: '请输入学分', trigger: 'blur' }],
|
||
pxcc: [{ required: true, message: '请输入培训层次', trigger: 'blur' }],
|
||
pxlx: [{ required: true, message: '请输入培训类型', trigger: 'blur' }],
|
||
kclx: [{ required: true, message: '请输入课程类型', trigger: 'blur' }],
|
||
ksks: [{ required: true, message: '请输入考试课时', trigger: 'blur' }],
|
||
cjfz: [{ required: true, message: '请输入成绩分制', trigger: 'blur' }],
|
||
llxs: [{ required: true, message: '请输入理论学时', trigger: 'blur' }],
|
||
sjxs: [{ required: true, message: '请输入实践学时', trigger: 'blur' }],
|
||
zks: [{ required: true, message: '请输入周课时', trigger: 'blur' }],
|
||
klx: [{ required: true, message: '请输入课类型', trigger: 'blur' }],
|
||
kctybh: [{ required: true, message: '请输入课程统一编号', trigger: 'blur' }],
|
||
fddyks: [{ required: true, message: '请输入辅导答疑课时', trigger: 'blur' }],
|
||
zxks: [{ required: true, message: '请输入自修课时', trigger: 'blur' }],
|
||
xdrq: [{ required: true, message: '请输入修订日期', trigger: 'blur' }],
|
||
jcyxj: [{ required: true, message: '请输入节次优选级', trigger: 'blur' }],
|
||
kczcfs: [{ required: true, message: '请输入课程支持方式', trigger: 'blur' }],
|
||
kcjsfs: [{ required: true, message: '请输入课程建设方式', trigger: 'blur' }],
|
||
khfs: [{ required: true, message: '请输入考核方式', trigger: 'blur' }],
|
||
xcxcjfz: [{ required: true, message: '请输入形成性成绩分值', trigger: 'blur' }],
|
||
zjxcjfz: [{ required: true, message: '请输入终结性成绩分值', trigger: 'blur' }],
|
||
mj: [{ required: true, message: '请输入密级', trigger: 'blur' }],
|
||
pxqk: [{ required: true, message: '请输入评选情况', trigger: 'blur' }]
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
dialogTitle() {
|
||
return this.isEdit ? '编辑课程科目' : '新增课程科目'
|
||
},
|
||
fileName() {
|
||
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
|
||
}
|
||
},
|
||
mounted() {
|
||
this.fetchList()
|
||
},
|
||
methods: {
|
||
/** 移除空值 */
|
||
cleanPayload(obj) {
|
||
const payload = {}
|
||
Object.keys(obj).forEach(key => {
|
||
const value = obj[key]
|
||
if (value !== '' && value !== null && value !== undefined) {
|
||
payload[key] = value
|
||
}
|
||
})
|
||
return payload
|
||
},
|
||
|
||
/** 创建空白课程科目表单 */
|
||
createEmptyForm() {
|
||
return {
|
||
kbh: '', kmc: '', jysdh: '', bz: '', xh: '', xf: 0, jc: '', xs: 0,
|
||
pxcc: '', pxlx: '', kclx: '', ksks: 0, py: '', gfmc: '', cjfz: '',
|
||
bjrxypjf: 0, jxglbmbh: '', llxs: 0, sjxs: 0, kmdm: '', zks: 0, klx: '',
|
||
ksksbxs: 0, kctybh: '', sydx: '', fddyks: 0, zxks: 0, bb: '', xdrq: '',
|
||
jcyxj: '', kczcfs: '', kcjsfs: '', jsonzd: '', zzlkc: 0, khfs: '',
|
||
xcxcjfz: 0, zjxcjfz: 0, mj: '', pxqk: ''
|
||
}
|
||
},
|
||
|
||
resetForm() {
|
||
this.addForm = this.createEmptyForm()
|
||
},
|
||
|
||
// ==================== 列表加载 ====================
|
||
buildQuery() {
|
||
return this.cleanPayload({
|
||
pageNum: this.pageNum,
|
||
pageSize: this.pageSize,
|
||
kmc: this.searchForm.kmc,
|
||
jc: this.searchForm.jc,
|
||
kmdm: this.searchForm.kmdm,
|
||
jysdh: this.searchForm.jysdh,
|
||
kclx: this.searchForm.kclx,
|
||
pxlx: this.searchForm.pxlx,
|
||
pxcc: this.searchForm.pxcc
|
||
})
|
||
},
|
||
|
||
fetchList() {
|
||
this.loading = true
|
||
listSubject(this.buildQuery())
|
||
.then(res => {
|
||
const data = (res && res.data) || {}
|
||
this.tableData = data.records || []
|
||
this.total = data.total || 0
|
||
this.statusTip = `共检索到 ${this.total} 条记录`
|
||
})
|
||
.finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
|
||
// ==================== 查询 ====================
|
||
handleQuery() {
|
||
this.pageNum = 1
|
||
this.fetchList()
|
||
},
|
||
|
||
handlePageChange(current) {
|
||
this.pageNum = current
|
||
this.fetchList()
|
||
},
|
||
handleSizeChange(size) {
|
||
this.pageSize = size
|
||
this.pageNum = 1
|
||
this.fetchList()
|
||
},
|
||
handleSelectionChange(rows) {
|
||
this.selectedRows = rows
|
||
},
|
||
|
||
// ==================== 删除所选 ====================
|
||
handleBatchDelete() {
|
||
if (this.selectedRows.length === 0) {
|
||
this.$message.warning('请先选择要删除的记录')
|
||
return
|
||
}
|
||
const kbhList = this.selectedRows.map(r => r.kbh)
|
||
this.$confirm(`确定删除所选 ${kbhList.length} 条课程科目吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
const tasks = kbhList.map(kbh => deleteSubject(kbh))
|
||
Promise.all(tasks)
|
||
.then(() => {
|
||
this.$message.success(`已删除 ${kbhList.length} 条记录`)
|
||
this.fetchList()
|
||
})
|
||
.catch(() => {
|
||
this.$message.error('删除失败')
|
||
})
|
||
}).catch(() => {})
|
||
},
|
||
|
||
/** 单条删除 */
|
||
handleDelete(row) {
|
||
this.$confirm(`确定删除课程科目「${row.kmc || row.kbh}」吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
return deleteSubject(row.kbh)
|
||
}).then(() => {
|
||
this.$message.success('删除成功')
|
||
this.fetchList()
|
||
}).catch((err) => {
|
||
if (err && err !== 'cancel') {
|
||
this.$message.error('删除失败')
|
||
}
|
||
})
|
||
},
|
||
|
||
// ==================== 下载 ====================
|
||
handleDownloadTemplate() {
|
||
downloadCourseSubjectTemplate().then(blob => {
|
||
saveAs(blob, '课程课目数据文件模板.xls')
|
||
this.$message.success('模板下载成功')
|
||
}).catch(() => {})
|
||
},
|
||
|
||
// ==================== 文件上传(后端暂未提供) ====================
|
||
handleSelectFile() {
|
||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||
},
|
||
|
||
handleFileChange(e) {
|
||
const input = e.target
|
||
this.selectedFile = (input.files && input.files[0]) || null
|
||
},
|
||
|
||
handleUpload() {
|
||
this.$message.warning('后端暂未提供该接口')
|
||
},
|
||
|
||
// ==================== 新增/编辑弹窗 ====================
|
||
handleOpenDialog() {
|
||
this.isEdit = false
|
||
this.resetForm()
|
||
this.dialogVisible = true
|
||
},
|
||
|
||
handleEdit(row) {
|
||
this.addLoading = true
|
||
getKb(row.kbh)
|
||
.then(res => {
|
||
const data = (res && res.data) || row
|
||
this.isEdit = true
|
||
this.addForm = Object.assign(this.createEmptyForm(), data)
|
||
this.dialogVisible = true
|
||
})
|
||
.finally(() => {
|
||
this.addLoading = false
|
||
})
|
||
},
|
||
|
||
handleSubmit() {
|
||
this.$refs.addFormRef.validate((valid) => {
|
||
if (!valid) return
|
||
this.addLoading = true
|
||
const payload = this.cleanPayload({ ...this.addForm })
|
||
const requestFn = this.isEdit ? updateSubject : addSubject
|
||
requestFn(payload)
|
||
.then(() => {
|
||
this.$message.success(this.isEdit ? '修改成功' : '保存成功')
|
||
this.dialogVisible = false
|
||
this.fetchList()
|
||
})
|
||
.finally(() => {
|
||
this.addLoading = false
|
||
})
|
||
})
|
||
},
|
||
|
||
handleCancel() {
|
||
this.dialogVisible = false
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.app-container {
|
||
padding: 20px;
|
||
}
|
||
|
||
// ==================== 1. 顶部状态提示 ====================
|
||
.status-tip {
|
||
display: inline-block;
|
||
background: #dc3545;
|
||
color: #fff;
|
||
font-size: 12px;
|
||
padding: 3px 10px;
|
||
border-radius: 4px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
// ==================== 2. 查询条件区域 ====================
|
||
.search-card {
|
||
margin-bottom: 16px;
|
||
|
||
.query-field {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 14px;
|
||
min-height: 32px;
|
||
|
||
::v-deep(.el-checkbox) {
|
||
margin-right: 6px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.q-label {
|
||
width: 120px;
|
||
flex-shrink: 0;
|
||
font-size: 13px;
|
||
color: #303133;
|
||
text-align: right;
|
||
margin-right: 10px;
|
||
white-space: nowrap;
|
||
|
||
&.no-check {
|
||
margin-left: 24px;
|
||
}
|
||
}
|
||
|
||
.q-control {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
}
|
||
|
||
.notice {
|
||
font-size: 12px;
|
||
color: #f56c6c;
|
||
margin-top: 8px;
|
||
text-align: left;
|
||
}
|
||
|
||
}
|
||
|
||
// ==================== 3. 操作按钮区域 ====================
|
||
.action-card {
|
||
margin-bottom: 16px;
|
||
|
||
.action-row {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
margin-bottom: 12px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// ==================== 4. 文件上传区域 ====================
|
||
.upload-card {
|
||
margin-bottom: 16px;
|
||
|
||
.upload-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
|
||
.upload-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
|
||
.file-name {
|
||
font-size: 12px;
|
||
color: #999;
|
||
|
||
&.has-file {
|
||
color: #303133;
|
||
}
|
||
}
|
||
}
|
||
|
||
.upload-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// ==================== 5. 红色提示文字 ====================
|
||
.red-tip {
|
||
font-size: 14px;
|
||
color: #f56c6c;
|
||
margin-bottom: 16px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
// ==================== 6. 数据表格区域 ====================
|
||
.table-card {
|
||
.pagination-wrapper {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 16px;
|
||
}
|
||
|
||
::v-deep(.el-table .cell) {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.text-danger {
|
||
color: #f56c6c;
|
||
}
|
||
}
|
||
|
||
// ==================== 新增/编辑弹窗 ====================
|
||
.add-dialog {
|
||
::v-deep(.el-dialog__body) {
|
||
max-height: 70vh;
|
||
overflow: auto;
|
||
}
|
||
}
|
||
|
||
.add-form {
|
||
.w-full {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
.dialog-footer {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 12px;
|
||
}
|
||
|
||
</style>
|