|
@@ -75,55 +75,67 @@
|
|
|
</el-col>
|
|
|
|
|
|
<!-- 分类管理 -->
|
|
|
- <el-dialog :visible.sync="categoryManageVisible" title="分类管理" width="600px">
|
|
|
- <el-table :data="categoryList" style="width: 100%" max-height="400">
|
|
|
- <el-table-column prop="label" label="分类名称" width="180"></el-table-column>
|
|
|
+ <el-dialog :visible.sync="categoryManageVisible" title="分类管理" width="800px" top="6.5vh">
|
|
|
+ <el-table :data="categoryList" style="width: 100%" height="60vh" border>
|
|
|
+ <el-table-column prop="label" label="分类名称"></el-table-column>
|
|
|
<el-table-column label="封面" width="180">
|
|
|
<template slot-scope="scope">
|
|
|
<img v-if="scope.row.coverImage" :src="scope.row.coverImage" class="category-cover-image" />
|
|
|
<span v-else>无封面</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column label="是否上架" width="80">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span style="color: #5cb87a;" v-if="scope.row.status == 1">上架</span>
|
|
|
+ <span style="color: #909399;" v-else>下架</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="操作" width="180">
|
|
|
<template slot-scope="scope">
|
|
|
- <el-button size="mini" type="primary" @click="setCategoryCover(scope.$index, scope.row)">设置封面</el-button>
|
|
|
+ <el-button size="mini" type="primary" @click="addEditCategory(scope.row)">编辑</el-button>
|
|
|
<el-button size="mini" type="danger" @click="deleteCategory(scope.$index, scope.row)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
- <div style="margin-top: 20px;">
|
|
|
- <el-form :inline="true" :model="newCategory" class="demo-form-inline">
|
|
|
- <el-form-item label="分类名称">
|
|
|
- <el-input v-model="newCategory.label" placeholder="请输入分类名称"></el-input>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <el-button type="primary" @click="addCategory">添加</el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- </div>
|
|
|
- <span slot="footer" class="dialog-dialog">
|
|
|
+ <span slot="footer" class="classificationOperation">
|
|
|
+ <el-button type="primary" @click="addEditCategory()">新增分类</el-button>
|
|
|
<el-button @click="categoryManageVisible = false">关 闭</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
-
|
|
|
- <!-- 设置分类封面 -->
|
|
|
- <el-dialog :visible.sync="coverDialogVisible" title="设置分类封面" width="500px">
|
|
|
- <div class="cover-upload-container">
|
|
|
- <el-upload
|
|
|
- class="cover-uploader"
|
|
|
- action="#"
|
|
|
- :show-file-list="false"
|
|
|
- :on-change="handleCoverChange"
|
|
|
- :auto-upload="false"
|
|
|
- :before-upload="beforeCoverUpload">
|
|
|
- <img v-if="coverImageUrl" :src="coverImageUrl" class="cover-image" />
|
|
|
- <i v-else class="el-icon-plus cover-uploader-icon"></i>
|
|
|
- </el-upload>
|
|
|
- <div class="cover-tip">请上传分类封面图片,建议尺寸 16:9</div>
|
|
|
+ <!-- 新建分类 -->
|
|
|
+ <el-dialog :visible.sync="newCategoryDialogVisible" title="新建/编辑分类" width="800px" top="6.5vh">
|
|
|
+ <div class="newCategoryDialog">
|
|
|
+ <div class="newCategoryDialog-item">
|
|
|
+ <div class="newCategoryDialog-item-label">分类名称:</div>
|
|
|
+ <el-input v-model.trim="newCategoryDialogForm.label" placeholder="请输入内容" clearable size="small" style="flex: 1"></el-input>
|
|
|
+ </div>
|
|
|
+ <div class="newCategoryDialog-item">
|
|
|
+ <div class="newCategoryDialog-item-label">分类封面:</div>
|
|
|
+ <el-upload
|
|
|
+ class="cover-uploader"
|
|
|
+ :show-file-list="false"
|
|
|
+ auto-upload
|
|
|
+ accept="image/*"
|
|
|
+ :http-request="categoryCoverUpload">
|
|
|
+ <img v-if="newCategoryDialogForm.coverImage" :src="newCategoryDialogForm.coverImage" class="cover-preview">
|
|
|
+ <i v-else class="el-icon-plus cover-uploader-icon"></i>
|
|
|
+ <div v-if="newCategoryDialogForm.coverImage" class="cover-mask">
|
|
|
+ <el-link icon="el-icon-view" type="success" @click.stop="previewImage(newCategoryDialogForm.coverImage)" :underline="false">查看</el-link>
|
|
|
+ <el-link icon="el-icon-edit" type="success" :underline="false" style="margin-left: 10px;">修改</el-link>
|
|
|
+ </div>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ <div class="newCategoryDialog-item">
|
|
|
+ <div class="newCategoryDialog-item-label">是否上架:</div>
|
|
|
+ <el-radio-group v-model="newCategoryDialogForm.status">
|
|
|
+ <el-radio :label="0">下架</el-radio>
|
|
|
+ <el-radio :label="1">上架</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <span slot="footer" class="dialog-footer">
|
|
|
- <el-button @click="coverDialogVisible = false">取 消</el-button>
|
|
|
- <el-button type="primary" @click="saveCategoryCover">确 定</el-button>
|
|
|
+ <span slot="footer" class="classificationOperation">
|
|
|
+ <el-button @click="newCategoryDialogVisible = false">关 闭</el-button>
|
|
|
+ <el-button type="primary" :disabled="!newCategoryDialogForm.label" :loading="newCategoryDialogLoading" @click="saveCategory()">保存</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
|
|
@@ -196,6 +208,10 @@
|
|
|
<el-button type="primary" @click="saveVideo()" :disabled="!displayVideoList.length || displayVideoList.some(video => video.videoError) || displayVideoList.some(video => video.videoLoading)" size="small" :loading="saveVideoLoading">保存视频</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <viewer ref="imageWrapper" :images="previewImages" style="opacity: 1;position: absolute;top: -9999px;">
|
|
|
+ <img v-for="(image, index) in previewImages" :src="image" :key="index" />
|
|
|
+ </viewer>
|
|
|
</section>
|
|
|
</template>
|
|
|
|
|
@@ -207,6 +223,7 @@ import 'quill/dist/quill.bubble.css'
|
|
|
// 导入富文本
|
|
|
import { quillEditor } from 'vue-quill-editor'
|
|
|
import addVideoCom from './addVideo.vue'
|
|
|
+import { post, checkAndAddUpload } from '../../api'
|
|
|
export default {
|
|
|
components: {
|
|
|
quillEditor, // 富文本
|
|
@@ -304,9 +321,80 @@ export default {
|
|
|
displayVideoList: [],
|
|
|
videiListTime: null,
|
|
|
saveVideoLoading: false,
|
|
|
+
|
|
|
+ // 新建/编辑分类
|
|
|
+ newCategoryDialogVisible: false,
|
|
|
+ newCategoryDialogForm: {},
|
|
|
+ previewImages: [],
|
|
|
+ newCategoryDialogLoading: false
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
+ saveCategory() {
|
|
|
+ this.newCategoryDialogLoading = true
|
|
|
+ const { label, value, coverImage, status } = this.newCategoryDialogForm;
|
|
|
+ post('/course-type/editCourseTypeInfo', {
|
|
|
+ id: value,
|
|
|
+ typeName: label,
|
|
|
+ coverImageUrl: coverImage,
|
|
|
+ status: status
|
|
|
+ }).then(res => {
|
|
|
+ if(res.code == 'ok') {
|
|
|
+ this.newCategoryDialogVisible = false
|
|
|
+ this.$message.success('保存成功!');
|
|
|
+ this.batchManage()
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg);
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ this.newCategoryDialogLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ categoryCoverUpload(file) {
|
|
|
+ console.log(file, '<==== file')
|
|
|
+ const isImage = file.file.type.includes('image');
|
|
|
+ if (!isImage) {
|
|
|
+ this.$message.error('只能上传图片文件!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('multipartFile', file.file);
|
|
|
+
|
|
|
+ this.http.uploadFile('/common/uploadFile', formData, res => {
|
|
|
+ if (res.code === "ok") {
|
|
|
+ this.newCategoryDialogForm.coverImage = checkAndAddUpload(res.data);
|
|
|
+ this.$message.success('图片上传成功');
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg || '上传失败');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ previewImage(url) {
|
|
|
+ this.previewImages = [url];
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.imageWrapper && this.$refs.imageWrapper.$viewer) {
|
|
|
+ this.$refs.imageWrapper.$viewer.show();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ addEditCategory(row = false) {
|
|
|
+ if(!row) {
|
|
|
+ this.newCategoryDialogForm = {
|
|
|
+ label: '',
|
|
|
+ value: '',
|
|
|
+ coverImage: '',
|
|
|
+ status: 1
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.newCategoryDialogForm = {
|
|
|
+ ...row,
|
|
|
+ coverImage: checkAndAddUpload(row.coverImage),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.newCategoryDialogVisible = true
|
|
|
+ },
|
|
|
coursePriceBlur(val) {
|
|
|
if(!this.courseForm.coursePrice) {
|
|
|
this.courseForm.coursePrice = 0
|
|
@@ -433,7 +521,8 @@ export default {
|
|
|
this.categoryList = res.data.map(item => ({
|
|
|
label: item.typeName,
|
|
|
value: item.id,
|
|
|
- coverImage: item.coverImage || ''
|
|
|
+ coverImage: item.coverImage || '',
|
|
|
+ status: item.status
|
|
|
}));
|
|
|
|
|
|
// 同步更新下拉选项
|
|
@@ -1140,4 +1229,72 @@ export default {
|
|
|
position: relative;
|
|
|
top: -8px;
|
|
|
}
|
|
|
+.classificationOperation {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+.newCategoryDialog {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+.newCategoryDialog-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: row;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+.newCategoryDialog-item-label {
|
|
|
+ width: 120px;
|
|
|
+ text-align: right;
|
|
|
+ margin-right: 20px;
|
|
|
+}
|
|
|
+.cover-uploader {
|
|
|
+ border: 1px dashed #d9d9d9;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ width: 200px;
|
|
|
+ height: 150px;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-uploader:hover {
|
|
|
+ border-color: #409EFF;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-uploader:hover .cover-mask {
|
|
|
+ opacity: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-mask {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ opacity: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-uploader-icon {
|
|
|
+ font-size: 28px;
|
|
|
+ color: #8c939d;
|
|
|
+ width: 200px;
|
|
|
+ height: 150px;
|
|
|
+ line-height: 150px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-preview {
|
|
|
+ width: 200px;
|
|
|
+ height: 150px;
|
|
|
+ object-fit: cover;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
</style>
|