|
|
@@ -0,0 +1,172 @@
|
|
|
+<template>
|
|
|
+ <div class="page-container">
|
|
|
+ <div class="page-header">
|
|
|
+ <h2 class="page-title">课前资料</h2>
|
|
|
+ <div class="filter-bar">
|
|
|
+ <el-select v-model="filterClassId" placeholder="全部班次" clearable style="width:200px" @change="fetchList">
|
|
|
+ <el-option v-for="c in classList" :key="c.id" :label="c.name" :value="c.id" />
|
|
|
+ </el-select>
|
|
|
+ <el-button type="primary" icon="el-icon-plus" @click="openEdit()">新增资料</el-button>
|
|
|
+ <el-button icon="el-icon-refresh" @click="fetchList">刷新</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table :data="list" v-loading="loading" border stripe style="width:100%">
|
|
|
+ <el-table-column prop="id" label="ID" width="80" />
|
|
|
+ <el-table-column prop="title" label="资料标题" min-width="200" />
|
|
|
+ <el-table-column label="适用班次" width="140">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag v-if="scope.row.classId" size="small" type="warning">班次 #{{ scope.row.classId }}</el-tag>
|
|
|
+ <el-tag v-else size="small" type="info">通用</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="sort" label="排序" width="80" />
|
|
|
+ <el-table-column prop="fileUrl" label="文件地址" min-width="220" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="createdAt" label="创建时间" width="170" />
|
|
|
+ <el-table-column label="操作" width="120" fixed="right">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="small" @click="openEdit(scope.row)">编辑</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <el-empty v-if="!loading && list.length === 0" description="暂无课前资料" />
|
|
|
+
|
|
|
+ <el-dialog :title="form.id ? '编辑资料' : '新增资料'" :visible.sync="dialogVisible" width="560px">
|
|
|
+ <el-form :model="form" label-width="90px">
|
|
|
+ <el-form-item label="资料标题" required>
|
|
|
+ <el-input v-model="form.title" placeholder="如:课前预习手册" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="适用班次">
|
|
|
+ <el-select v-model="form.classId" placeholder="留空 = 通用资料" clearable style="width:100%">
|
|
|
+ <el-option v-for="c in classList" :key="c.id" :label="c.name" :value="c.id" />
|
|
|
+ </el-select>
|
|
|
+ <div class="form-tip">留空则所有班次学员可见(通用资料)</div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="文件地址">
|
|
|
+ <el-input v-model="form.fileUrl" placeholder="https://…(图片/PDF 链接,可后补)" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="排序">
|
|
|
+ <el-input-number v-model="form.sort" :min="0" :max="9999" />
|
|
|
+ <div class="form-tip">数字越小越靠前展示</div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="saving" @click="handleSave">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { materialList, materialSave } from '@/api/material'
|
|
|
+import { classList as fetchClasses } from '@/api/class'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'Materials',
|
|
|
+ data: function () {
|
|
|
+ return {
|
|
|
+ list: [],
|
|
|
+ classList: [],
|
|
|
+ filterClassId: null,
|
|
|
+ loading: false,
|
|
|
+ saving: false,
|
|
|
+ dialogVisible: false,
|
|
|
+ form: {
|
|
|
+ id: null,
|
|
|
+ title: '',
|
|
|
+ classId: null,
|
|
|
+ fileUrl: '',
|
|
|
+ sort: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted: function () {
|
|
|
+ this.loadClasses()
|
|
|
+ this.fetchList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadClasses: function () {
|
|
|
+ var self = this
|
|
|
+ fetchClasses().then(function (res) {
|
|
|
+ self.classList = res.data || []
|
|
|
+ }).catch(function () {
|
|
|
+ self.$message.error('获取班级列表失败')
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fetchList: function () {
|
|
|
+ var self = this
|
|
|
+ self.loading = true
|
|
|
+ materialList({ classId: self.filterClassId || undefined }).then(function (res) {
|
|
|
+ self.list = res.data || []
|
|
|
+ }).catch(function () {
|
|
|
+ self.$message.error('获取课前资料失败')
|
|
|
+ }).finally(function () {
|
|
|
+ self.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ openEdit: function (row) {
|
|
|
+ this.form = {
|
|
|
+ id: row ? row.id : null,
|
|
|
+ title: row ? row.title : '',
|
|
|
+ classId: row ? row.classId : null,
|
|
|
+ fileUrl: row ? row.fileUrl : '',
|
|
|
+ sort: row ? row.sort : 0
|
|
|
+ }
|
|
|
+ this.dialogVisible = true
|
|
|
+ },
|
|
|
+ handleSave: function () {
|
|
|
+ var self = this
|
|
|
+ if (!self.form.title || !self.form.title.trim()) {
|
|
|
+ self.$message.warning('请填写资料标题')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ self.saving = true
|
|
|
+ materialSave({
|
|
|
+ id: self.form.id,
|
|
|
+ title: self.form.title.trim(),
|
|
|
+ classId: self.form.classId || null,
|
|
|
+ fileUrl: self.form.fileUrl || null,
|
|
|
+ sort: self.form.sort || 0
|
|
|
+ }).then(function () {
|
|
|
+ self.$message.success('保存成功')
|
|
|
+ self.dialogVisible = false
|
|
|
+ self.fetchList()
|
|
|
+ }).catch(function () {
|
|
|
+ self.$message.error('保存失败')
|
|
|
+ }).finally(function () {
|
|
|
+ self.saving = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.page-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.page-title {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-tip {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ margin-top: 4px;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+</style>
|