380 lines
13 KiB
Vue
380 lines
13 KiB
Vue
<script setup>
|
||
// 引入依赖
|
||
import _ from 'lodash'
|
||
import api from '@/api/course'
|
||
import com_api from '@/api/common'
|
||
import custom from '@/utils/custom'
|
||
// import WarningBar from '@/components/warningBar/warningBar.vue'
|
||
import {ref,onMounted,provide } from 'vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import { useRouter, useRoute } from 'vue-router'
|
||
const router = useRouter()
|
||
const route = useRoute()
|
||
import { useUserStore } from '@/pinia/modules/user'
|
||
const userStore = useUserStore()
|
||
import chapterCom from '../components/chapter.vue'
|
||
// 变量
|
||
const path = ref(import.meta.env.VITE_BASE_API)
|
||
const course_id = ref(0)
|
||
const active = ref(0)
|
||
const form = ref({status:1,is_boutique:-1,is_audition:-1})
|
||
const subjectParams = ref({
|
||
page:1,
|
||
pageSize:100,
|
||
})
|
||
const subjectList = ref([])
|
||
const subjectList_inject =ref([])
|
||
const rules = ref({
|
||
name: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
||
course_category_id: [{ required: true, message: '请选择课程科目', trigger: 'change' }],
|
||
price: [{ required: true, message: '请输入课程价格', trigger: 'blur' }]
|
||
})
|
||
const ruleFormRef = ref(null)
|
||
const chapter_info = ref([])
|
||
const current_subject = ref('')
|
||
const isChange = ref(false)
|
||
// 生命周期
|
||
onMounted(() => {
|
||
course_id.value = route.params.course_id || 0
|
||
if(course_id.value) {
|
||
getCourseInfo()
|
||
}
|
||
getSubject()
|
||
})
|
||
provide('subjectList', subjectList_inject)
|
||
provide('current_subject', current_subject)
|
||
// 方法
|
||
async function getCourseInfo() { // 获取课程信息
|
||
const res = await api.getCourse({id:course_id.value})
|
||
if(res.code === 0) {
|
||
chapter_info.value = res.data.course_ware_json
|
||
res.data.course.price /=100
|
||
form.value = res.data.course
|
||
}
|
||
}
|
||
function stepChangeFunc(type) {
|
||
switch (type) {
|
||
case 1: // 上一步
|
||
active.value -=1
|
||
break;
|
||
case 2: // 下一步
|
||
if(active.value == 0) { // 保存第一步的信息
|
||
// console.log(isChange.value)
|
||
if(isChange.value){
|
||
submitForm(ruleFormRef.value)
|
||
}
|
||
else{
|
||
active.value += 1
|
||
}
|
||
}
|
||
else{
|
||
active.value +=1
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
const submitForm = async (formEl) => {
|
||
if (!formEl) return
|
||
await formEl.validate((valid, fields) => {
|
||
if (valid) {
|
||
console.log('submit!')
|
||
saveStep1()
|
||
} else {
|
||
// console.log('error submit!', fields)
|
||
}
|
||
})
|
||
}
|
||
async function saveStep1() {
|
||
// form.value.course_category_id = subjectList.value.filter((item,i) => {
|
||
// return item.name === form.value.subject
|
||
// })[0].id
|
||
form.value.subject = custom.get_course_category_name(form.value.course_category_id)
|
||
form.value.price = parseFloat(form.value.price)<0?0:form.value.price
|
||
if(!checkFreeTestFromPrice()) {
|
||
ElMessage({
|
||
type: 'warning',
|
||
message: '赠送价格不能超过课程价格!'
|
||
})
|
||
}
|
||
let params = {
|
||
step1:{
|
||
...form.value
|
||
}
|
||
}
|
||
params.step1.price = parseInt(parseFloat(params.step1.price)*100)
|
||
let func_name =''
|
||
if(course_id.value) { // 编辑
|
||
params.course_id = parseInt(course_id.value)
|
||
func_name = 'editCourse'
|
||
}
|
||
else{ // 新增
|
||
func_name = 'addCourse'
|
||
}
|
||
const res = await api[func_name](params)
|
||
if(res.code === 0) {
|
||
active.value += 1
|
||
course_id.value = res.data
|
||
current_subject.value = form.value.subject
|
||
ElMessage({
|
||
type: 'success',
|
||
message: '操作成功!'
|
||
})
|
||
}
|
||
}
|
||
async function getSubject(){ // 获取课程分类
|
||
const res = await api.getSubjectList(subjectParams.value)
|
||
if(res.code === 0) {
|
||
// subjectList.value = custom.getStdSubject(res.data.records)
|
||
// subjectList.value = custom.addTreeFormatSubject(res.data.records,'id')
|
||
subjectList_inject.value = custom.addTreeFormatSubject(_.cloneDeep(res.data.records),'name')
|
||
subjectList.value = custom.addTreeFormatSubject( _.cloneDeep(res.data.records),'id')
|
||
//
|
||
}
|
||
}
|
||
async function uploadAction(file){//图片上传 非oss
|
||
file.status = 'uploading';
|
||
file.message = '上传中...';
|
||
//开始上传
|
||
const content = new FormData();
|
||
//上传图片需要转换二进制这里要用到FormData
|
||
content.append("file", file.file);
|
||
content.append("type", '1');
|
||
const res=await com_api.upload(content);
|
||
if(res.code==200){
|
||
file.status = 'done';
|
||
file.message = '上传成功';
|
||
file.url = res.data.full_path;
|
||
this.courseForm.cover = file.url
|
||
}
|
||
else{
|
||
file.status = 'failed';
|
||
file.message = '上传失败';
|
||
}
|
||
//重新赋值 img/视频
|
||
|
||
// var val_arr = []
|
||
// for(let item of topicInfo.value[topic_index.value].answer_img_arr){
|
||
// if(item.uid==file.file.uid){
|
||
// item.url=file.url
|
||
// }
|
||
// val_arr.push(item.url)
|
||
// }
|
||
// topicInfo.value[topic_index.value].answer_img = val_arr.join(",")
|
||
// const exercises_info = {
|
||
// ...topicInfo.value[topic_index.value],
|
||
// answer_img: topicInfo.value[topic_index.value].answer_img
|
||
// }
|
||
// card_submit_data(exercises_info)
|
||
}
|
||
function handleAvatarSuccess(res) {
|
||
form.value.cover = res.data.file.url
|
||
handlerChange()
|
||
}
|
||
function handleIntroSuccess(res) {
|
||
form.value.intro = res.data.file.url
|
||
handlerChange()
|
||
}
|
||
function beforeAvatarUpload(file) {
|
||
const isLt05M = file.size / 1024 / 1024 < 20
|
||
const isJPG = file.type.indexOf('image/') === -1
|
||
if (isJPG) {
|
||
ElMessage.error('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件')
|
||
}
|
||
if (!isLt05M) {
|
||
ElMessage.error('上传头像图片大小不能超过 2M!')
|
||
}
|
||
return !isJPG && isLt05M
|
||
}
|
||
|
||
function handlerChange(e) {
|
||
// console.log(e)
|
||
isChange.value = true
|
||
}
|
||
function freeTestFunc() { // 免费试卷数量
|
||
if(!checkFreeTestFromPrice()) {
|
||
ElMessage({
|
||
type: 'warning',
|
||
message: '赠送价格不能超过课程价格!'
|
||
})
|
||
}
|
||
handlerChange()
|
||
}
|
||
const STD_TEST_PRICE = 4.9
|
||
function checkFreeTestFromPrice() { // 检查免费试卷分数是否合理
|
||
let flag = true
|
||
if(form.value.free_test && form.value.price) {
|
||
if(parseInt(form.value.free_test) * STD_TEST_PRICE > parseFloat(form.value.price)) {
|
||
flag = false
|
||
}
|
||
}
|
||
return flag
|
||
}
|
||
// 审核相关
|
||
const verifyVisible = ref(false)
|
||
const verifyForm = ref({})
|
||
function checkCourseFunc() { // 审核
|
||
// console.log(form.value)
|
||
if(form.value.status === 2 || form.value.status === 4 ) { // 未审核 或 未通过
|
||
verifyForm.value.is_pass = -1
|
||
}
|
||
else{
|
||
verifyForm.value.is_pass = 1
|
||
}
|
||
verifyForm.is_pass = form.value.status
|
||
verifyVisible.value = true
|
||
}
|
||
function transferStateFromVerify(v_state) {
|
||
let state = 0
|
||
if(v_state === 1) { // 审核通过
|
||
// state = form.value.status
|
||
state = 3
|
||
}
|
||
else{ // 审核拒绝
|
||
state = 4
|
||
}
|
||
return state
|
||
}
|
||
function closeVerifyVisibleDialog() {
|
||
verifyVisible.value = false
|
||
}
|
||
async function enterVerifyDialog() { // 审核提交
|
||
const status = transferStateFromVerify(verifyForm.value.is_pass)
|
||
// console.log(status)
|
||
const res = await api.verifyCourse({
|
||
course_id:parseInt(course_id.value),
|
||
status
|
||
})
|
||
if(res.code === 0) {
|
||
ElMessage({
|
||
type: 'success',
|
||
message: '操作成功!'
|
||
})
|
||
// closeVerifyVisibleDialog()
|
||
// getCourseList()
|
||
verifyVisible.value = false
|
||
getCourseInfo()
|
||
}
|
||
else{
|
||
ElMessage({
|
||
type: 'warning',
|
||
message: res.msg
|
||
})
|
||
}
|
||
}
|
||
function goListFunc() {
|
||
router.push({name:'courseManage'})
|
||
}
|
||
</script>
|
||
<template>
|
||
<div>
|
||
<!-- 步骤条-->
|
||
<div class="gva-search-box">
|
||
<el-steps :active="active" finish-status="success" simple style="margin-bottom: 20px">
|
||
<el-step title="课程信息" />
|
||
<el-step title="添加章节" />
|
||
</el-steps>
|
||
</div>
|
||
<!-- 表单区域-->
|
||
<div class="gva-table-box">
|
||
<!-- step1-->
|
||
<el-form ref="ruleFormRef" v-if="active == 0" :model="form" :rules="rules" label-width="120px" style="width: 50%">
|
||
<el-form-item label="课程名称" prop="name">
|
||
<el-input disabled placeholder="请输入课程名称" v-model="form.name" @change="handlerChange" />
|
||
</el-form-item>
|
||
<el-form-item label="课程分类" prop="course_category_id">
|
||
<!-- <el-select disabled v-model="form.subject" placeholder="请选择" @change="handlerChange">-->
|
||
<!-- <el-option-->
|
||
<!-- v-for="item in subjectList"-->
|
||
<!-- :key="item.id"-->
|
||
<!-- :label="item.name"-->
|
||
<!-- :value="item.name"-->
|
||
<!-- />-->
|
||
<!-- </el-select>-->
|
||
<el-tree-select v-model="form.course_category_id" :data="subjectList" :disabled="true" :render-after-expand="false" />
|
||
</el-form-item>
|
||
<el-form-item label="封面">
|
||
<el-upload
|
||
disabled
|
||
class="avatar-uploader"
|
||
:action="`${path}/fileUploadAndDownload/upload`"
|
||
:headers="{ 'x-token': userStore.token }"
|
||
:show-file-list="false"
|
||
:on-success="handleAvatarSuccess"
|
||
:before-upload="beforeAvatarUpload"
|
||
>
|
||
<img v-if="form.cover" :src="form.cover" class="avatar" />
|
||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||
</el-upload>
|
||
</el-form-item>
|
||
<el-form-item label="价格(元)" prop="price">
|
||
<el-input disabled @change="handlerChange" placeholder="请输入课程价格" type="number" v-model="form.price" />
|
||
</el-form-item>
|
||
<el-form-item label="课程简介">
|
||
<!-- <el-input @change="handlerChange" v-model="form.intro" type="textarea" />-->
|
||
<el-upload
|
||
disabled
|
||
class="avatar-uploader"
|
||
:action="`${path}/fileUploadAndDownload/upload`"
|
||
:headers="{ 'x-token': userStore.token }"
|
||
:show-file-list="false"
|
||
:on-success="handleIntroSuccess"
|
||
:before-upload="beforeAvatarUpload"
|
||
>
|
||
<img v-if="form.intro" :src="form.intro" class="avatar" />
|
||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||
</el-upload>
|
||
</el-form-item>
|
||
<!-- <el-form-item label="包含试听">-->
|
||
<!-- <el-switch @change="handlerChange" v-model="form.is_audition" active-text="是" inactive-text="否" :active-value="1" :inactive-value="-1" />-->
|
||
<!-- </el-form-item>-->
|
||
<el-form-item label="赠送试卷">
|
||
<el-input disabled @change="freeTestFunc" placeholder="请输入需要赠送的试卷份数,如:1" v-model="form.free_test" />
|
||
<div style="color:gray;font-size: 12px" v-if="form.free_test">总计{{(STD_TEST_PRICE*form.free_test).toFixed(2)}} 元</div>
|
||
</el-form-item>
|
||
<el-form-item label="设置精品">
|
||
<el-switch @change="handlerChange" v-model="form.is_boutique" active-text="是" inactive-text="否" :active-value="1" :inactive-value="-1" />
|
||
</el-form-item>
|
||
<el-form-item label="课程状态">
|
||
<el-switch disabled @change="handlerChange" v-model="form.status" active-text="上架" inactive-text="下架" :active-value="1" :inactive-value="-1" />
|
||
</el-form-item>
|
||
<el-form-item style="display: none">
|
||
<el-button type="primary" @click="submitForm(ruleFormRef)">
|
||
Create
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<!-- step2-->
|
||
<div class="chapter-part" v-if="active == 1">
|
||
<chapter-com @reload="getCourseInfo" :chapter_info="chapter_info" :course_id="course_id"/>
|
||
</div>
|
||
<div class="btn-box" style="text-align: right">
|
||
<el-button v-if="active>0" @click="stepChangeFunc(1)">上一步</el-button>
|
||
<el-button v-if="active<1" @click="stepChangeFunc(2)">下一步</el-button>
|
||
<el-button v-if="form.status === 2" type="primary" @click="checkCourseFunc">审核</el-button>
|
||
<el-button plain @click="goListFunc">返回课程列表</el-button>
|
||
</div>
|
||
</div>
|
||
<!-- 审核窗口-->
|
||
<el-dialog v-model="verifyVisible" :before-close="closeVerifyVisibleDialog" title="审核课程">
|
||
<el-form :model="verifyForm" label-width="80px">
|
||
<el-form-item label="是否通过" prop="is_free">
|
||
<el-switch v-model="verifyForm.is_pass" active-text="通过" inactive-text="拒绝" :active-value="1" :inactive-value="-1" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button size="small" @click="closeVerifyVisibleDialog">取 消</el-button>
|
||
<el-button size="small" type="primary" @click="enterVerifyDialog">确 定</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
<style scoped>
|
||
.avatar-uploader .avatar {
|
||
width: 178px;
|
||
height: 178px;
|
||
display: block;
|
||
}
|
||
</style>
|