You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

820 lines
30 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="type === 'add' ? '新增课程' : '编辑课程'"
:form="form" :rules='rules' :hasIscheck="true" @mysubmit="mysubmit">
<template v-slot:step>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold;display:none">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>
</div>
<div class="xy-table-item-content">
<el-steps :active="active" finish-status="success" simple>
<el-step title="课程信息"></el-step>
<el-step title="报名信息"></el-step>
</el-steps>
</div>
</div>
</template>
<template v-slot:type v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>课程体系:
</div>
<div class="xy-table-item-content">
<el-select v-model="form.type" @change="changeType" placeholder="请选择体系" clearable style="width: 100%;">
<el-option v-for="item in courseTypesList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:name v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>课程名称:
</div>
<div class="xy-table-item-content">
<el-input v-model="form.name" placeholder="请输入课程名称" clearable style="width: 100%;"></el-input>
</div>
</div>
</template>
<template v-slot:is_virtual v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>是否为虚拟课程:
</div>
<div class="xy-table-item-content">
<el-select v-model="form.is_virtual" placeholder="请选择" clearable style="width: 100%;">
<el-option v-for="item in false_or_true" :key="item.id" :label="item.value" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:url v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>资讯链接:
</div>
<div class="xy-table-item-content">
<el-select @change="changeUrl" filterable remote v-model="form.url" :remote-method="remoteMethod" :loading="loading"
placeholder="请输入关键词查询资讯" clearable style="width: 100%;">
<el-option v-for="item in zixunList" :key="item.id" :label="item.title" :value="item.titleurl">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:year v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>所属年份:
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 100%;" v-model="form.year" type="year" value-format="yyyy" format="yyyy">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:dateRange v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>开课日期:
</div>
<div class="xy-table-item-content">
<el-date-picker @change="changeDateRange" style="width: 100%;" v-model="form.dateRange" type="daterange"
range-separator="至" value-format="yyyy-MM-dd" format="yyyy-MM-dd" start-placeholder="开课日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:total v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>开课人数:
</div>
<div class="xy-table-item-content">
<el-input style="width: 100%;" v-model="form.total" placeholder="请输入开课人数" clearable></el-input>
</div>
</div>
</template>
<template v-slot:sign_start_date v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>报名开始日期:
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 100%;" v-model="form.sign_start_date" type="date" value-format="yyyy-MM-dd"
format="yyyy-MM-dd" placeholder="报名开始日期">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:sign_end_date v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>报名截止日期:
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 100%;" v-model="form.sign_end_date" type="date" value-format="yyyy-MM-dd"
format="yyyy-MM-dd" placeholder="报名截止日期">
</el-date-picker>
</div>
</div>
</template>
<!-- <template v-slot:status v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>状态:
</div>
<div class="xy-table-item-content">
<el-select style="width: 100%;" v-model="form.status" @change="changeStatus" placeholder="请选择">
<el-option v-for="item in course_status" :key="item.id" :label="item.value" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template> -->
<!-- 未排课时显示签到地点选点 -->
<template v-slot:address_detail v-if="active===0 && form.is_arrange===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>签到地点:
</div>
<div class="xy-table-item-content">
<avue-input-map v-model="addrMapForm" :params="mapparams" style="width:100%" placeholder="请选择地图" />
</div>
</div>
</template>
<template v-slot:is_fee v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>课程类型:
</div>
<div class="xy-table-item-content">
<el-radio-group style="width:100%" v-model="form.is_fee">
<el-radio :label="1">付费</el-radio>
<el-radio :label="0">公益</el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-slot:is_arrange v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>是否排课:
</div>
<div class="xy-table-item-content">
<el-radio-group style="width:100%" v-model="form.is_arrange" @change="onIsArrangeChange">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-slot:show_txl v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>是否显示通讯录:
</div>
<div class="xy-table-item-content">
<el-radio-group style="width:100%" v-model="form.show_txl">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-slot:show_mobile v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>是否显示联系方式:
</div>
<div class="xy-table-item-content">
<el-radio-group style="width:100%" v-model="form.show_mobile">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-slot:auto_schoolmate v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>已审核学员是否自动进入校友库
</div>
<div class="xy-table-item-content">
<el-radio-group style="width:100%" v-model="form.auto_schoolmate">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-slot:qun_image_id v-if="active===0 && form.is_fee===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold;">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>群聊二维码400*400
</div>
<div class="xy-table-item-content">
<el-upload :action="action" class='upload-demo' :on-exceed="onExceedQun" :limit="1" list-type="picture-card"
accept=".PNG,.jpg,.jpeg,.bmp,.svg" :file-list="qunList" ref="pictureUpload" :auto-upload="true"
:on-success="uploadSuccessQun" :on-remove="uploadRemoveQun">
<i class="el-icon-plus"></i>
</el-upload>
</div>
</div>
</template>
<template v-slot:image_id v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold;">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>课程封面690*400
</div>
<div class="xy-table-item-content">
<el-upload :action="action" class='upload-demo' :on-exceed="onExceed" :limit="1" list-type="picture-card"
accept=".PNG,.jpg,.jpeg,.bmp,.svg" :file-list="imgList" ref="pictureUpload" :auto-upload="true"
:on-success="uploadSuccess" :on-remove="uploadRemove">
<i class="el-icon-plus"></i>
</el-upload>
</div>
</div>
</template>
<template v-slot:publicize_ids v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold;">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>课程宣传页宽750
</div>
<div class="xy-table-item-content">
<el-upload :action="action" multiple class='upload-demo' list-type="picture-card" :file-list="publicizeList"
ref="pictureUpload" :auto-upload="true" :on-success="uploadSuccesspublic" :on-remove="uploadRemovepublic">
<i class="el-icon-plus"></i>
</el-upload>
</div>
</div>
</template>
<template v-slot:content v-if="active===0">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>课程简介:
</div>
<div class="xy-table-item-content">
<my-tinymce v-if="showTinymce" @input="saveContent" :value="form.content"></my-tinymce>
</div>
</div>
</template>
<!-- 自定义报名 表单 -->
<template v-slot:applylabel v-if="active===1">
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold;display:none">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>
</div>
<div class="xy-table-item-content" style="min-height: 300px;">
<div>
<el-dialog id="template-dialog" :title="'模板表单'"
style="position: relative; inset: 0 0 0 0; height: 100%;padding:20px 0" width="90%" top="0px"
:visible="true" :modal="false" :append-to-body="false" :show-close="false"
:modal-append-to-body="false">
<template v-slot:title>
<Button v-if="formList.length>0" ghost type="primary" @click="editForm('editor')">编辑表单</Button>
<Button v-else ghost type="primary" @click="editForm('add')">新增表单</Button>
</template>
<el-form
style="min-height: 300px;display: flex;flex-wrap: wrap;justify-content: space-between;padding: 0 4%;"
label-width="80px" label-position="top" size="small">
<!-- <el-divider>基础字段</el-divider>
<el-form-item :label="i.name" :required="
i.rule ? !!i.rule.includes('required') : false
" v-for="(i, index) in defaultFormList">
<el-input placeholder="基础字段" :disabled="true"></el-input>
</el-form-item>
<el-divider>选填字段</el-divider>
<el-form-item :label="i.name" v-for="(i, index) in selectFormList">
<el-input placeholder="选填字段" :disabled="true"></el-input>
</el-form-item> -->
<el-divider>表单字段</el-divider>
<el-form-item style="flex-basis: 45%;" :label="i.name || '字段名称'" :required="
i.rule ? !!i.rule.includes('required') : false
" v-for="(i, index) in formList">
<formSlotRender :config="i" :index="index"></formSlotRender>
</el-form-item>
</el-form>
</el-dialog>
</div>
</div>
</div>
</template>
<template v-slot:footerContent>
<Button ghost type="primary" v-if="active===1" @click="active=0">上一步</Button>
<!-- <Button ghost type="primary" v-if="active===0" @click="next">下一步</Button> -->
<Button type="primary" ghost @click="checkSubmit" v-if="active===0">保存并下一步</Button>
<Button type="primary" ghost v-if="active===1" @click="closeSubmit(0)">保存待发布</Button>
<Button type="primary" v-if="active===1" @click="closeSubmit(1)">完成并发布</Button>
</template>
</xy-dialog>
<!-- 发布提示 -->
<el-dialog title="是否确认发布" :visible.sync="showTips" width="30%">
<div style="padding: 30px;font-size: 24px;text-indent: 2em;">请确认报名表单无误后再发布。</div>
<span slot="footer" class="dialog-footer">
<el-button @click="showTips = false">取 消</el-button>
<el-button type="primary" @click="saveSubmit">确 定</el-button>
</span>
</el-dialog>
<applyForm ref="applyForm" @refresh="getFormList"></applyForm>
</div>
</template>
<script>
import myMixins from "@/mixin/selectMixin.js";
import formMixins from "@/mixin/formMixin.js";
import {
show,
save
} from "@/api/course/index.js"
import {
index as formIndex
} from "@/api/course/form";
import {
deepCopy
} from "@/utils";
import applyForm from "../components/applyForm.vue";
import formSlotRender from "@/views/system/components/formSlotRender.vue";
import axios from 'axios'
export default {
mixins: [myMixins, formMixins],
components: {
applyForm,
formSlotRender
},
data() {
return {
isShow: false,
showTips: false,
type: 'add',
active: 0,
id: '',
course_signs_count: 0,
action: `${process.env.VUE_APP_UPLOAD_API}`,
showTinymce: false,
courseTypesList: [],
imgList: [],
qunList: [],
publicizeList: [],
form: {
step: '', // 控制课程 课表
type: '',
name: '',
is_virtual: 0, //虚拟课程0否1是
url: '',
year: '',
dateRange: '',
total: '',
sign_start_date: '',
sign_end_date: '',
status: 0,
address_detail: '',
longitude: '',
latitude: '',
is_fee: 1,
is_arrange: 1,
show_txl: 1,
show_mobile: 0,
auto_schoolmate: 0,
qun_image_id: '',
image_id: '',
publicize_ids: [],
content: '',
applylabel: '',
url_title:''
},
rules: {
name: [{
required: true,
message: '请输入标题'
}],
type: [{
required: true,
message: '请选择课程体系'
}],
sign_start_date: [{
required: true,
message: '请选择报名开始日期'
}],
sign_end_date: [{
required: true,
message: '请选择报名截止日期'
}],
// image_id: [{
// required: true,
// message: '请上传课程封面'
// }],
// qun_image_id: [{
// required: true,
// message: '请上传群聊二维码'
// }],
// content: [{
// required: true,
// message: '请输入课程简介'
// }],
},
// 自定义表单
selectForm: {
page: 1,
page_size: 999,
sort_name: 'sort',
sort_type: 'ASC'
},
formList: [],
loading: false,
zixunList: [],
addrMapForm: [],
mapparams: { zoom: 11 }
}
},
created() {
this.getZxList()
},
methods: {
changeUrl(e){
if(e){
this.zixunList.map(item=>{
if(item.titleurl===e){
this.form.url_title = item.title
}
})
}else{
this.form.url_title = ''
}
},
remoteMethod(query) {
if (query !== '') {
this.loading = true;
this.getZxList(query)
} else {
this.zixunList = [];
}
},
async getZxList(query) {
const proUrl = `${process.env.VUE_APP_PRO_API}`
var baseUrl = proUrl + '/e/extend/news.php'
try {
// 直接调用 axios.get(),传入接口地址和参数
const response = await axios.get(baseUrl, {
params: {
page: 1,
pagesize: 999,
keyword: query
}, // GET 参数(拼在 URL 后)
timeout: 5000 // 超时时间(毫秒)
});
// 请求成功,存储结果
if(response.status===200){
this.zixunList = response.data.rows;
}
this.loading = false
console.log('GET 请求成功:', response);
} catch (error) {
// 请求失败,处理错误
console.error('GET 请求失败:', error);
alert('请求失败:' + (error.response?.data?.msg || '网络错误'));
}
},
changeType(e) {
// if (e == 1) {
// this.form.is_arrange = 1
// this.form.is_fee = 1
// } else {
// this.form.is_arrange = 0
// this.form.is_fee = 0
// }
},
saveContent(e) {
this.form.content = e
},
changeDateRange(e) {
if (e) {
this.form.start_date = e[0]
this.form.end_date = e[1]
} else {
this.form.start_date = ''
this.form.end_date = ''
}
},
beforeUpload(file) {
console.log(file)
const isImage = file.type.includes('image');
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
this.$message.error('请上传正确的图片格式文件');
}
if (!isLt2M) {
this.$message.error('上传文件大小不能超过2MB');
}
return isImage && isLt2M;
},
onExceed(file, fileList) {
this.$Message.warning("课程封面只需上传一张")
},
uploadSuccess(response, file, fileList) {
this.form.image_id = response.id
this.imgList = fileList
},
uploadRemove(file, fileList) {
this.imgList = fileList
this.form.image_id = ''
},
onExceedQun(file, fileList) {
this.$Message.warning("课程封面只需上传一张")
},
uploadSuccessQun(response, file, fileList) {
this.form.qun_image_id = response.id
this.qunList = fileList
},
uploadRemoveQun(file, fileList) {
this.qunList = fileList
this.form.qun_image_id = ''
},
uploadSuccesspublic(response, file, fileList) {
this.publicizeList = fileList
},
uploadRemovepublic(file, fileList) {
this.publicizeList = fileList
},
// 验证form提交规则
mysubmit(e) {
if (e) {
this.submit()
}
},
checkSubmit() {
this.$refs.dialog.submit(true)
},
compareTime(date, sign) {
let date1 = this.$moment(date)
let sign1 = this.$moment(sign)
return sign1.isBefore(date1)
},
submit() {
if (this.id) {
this.form.id = this.id
} else {
this.form.id = ''
}
// 报名截止时间 不能晚于 日程开始时间
if (this.form.start_date && this.form.sign_end_date) {
if (!this.compareTime(this.form.start_date, this.form.sign_end_date)) {
this.$Message.warning("报名截止时间不能晚于课程开始时间")
return
}
}
// return
let pubFiles = []
if (this.publicizeList.length > 0) {
this.publicizeList.map(item => {
if (item.response) {
pubFiles.push(item.response.id)
} else {
pubFiles.push(item.id)
}
})
}
this.form.publicize_ids = pubFiles
this.form.publicize = []
save({
...this.form
}).then(res => {
this.$message({
type: 'success',
message: '保存课程成功',
duration: 2000
})
this.id = res.id
this.$emit('refresh')
this.active = 1
// this.active = 1
})
},
// 发布
saveSubmit() {
this.form.id = this.id
this.form.status = 1
save({
...this.form
}).then(res => {
this.$message({
type: 'success',
message: '发布成功',
duration: 2000
})
this.showTips = false
this.$emit('refresh')
this.isShow = false
})
},
closeSubmit(status) {
// 发布
if (status == 1) {
if (this.formList.length < 1) {
this.$message({
type: 'warning',
message: '需要先创建报名表单才可以发布',
duration: 2000
})
return
}
// 已发布的直接关闭
if (this.form.status === 1) {
this.$emit('refresh')
this.isShow = false
} else {
this.showTips = true
}
} else {
this.form.id = this.id
this.form.status = 0
save({
...this.form
}).then(res => {
this.$message({
type: 'success',
message: '保存成功',
duration: 2000
})
this.$emit('refresh')
this.isShow = false
})
}
},
getDetail() {
show({
id: this.id,
show_relation: ['image', 'qun_image']
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
if (res.image) {
this.imgList.push(res.image)
}
if (res.qun_image) {
this.qunList.push(res.qun_image)
}
this.course_signs_count = res.course_signs_count
this.publicizeList = res.publicize
this.form.dateRange = res.start_date ? [res.start_date, res.end_date] : ''
this.form.status = res.status ? res.status : 0
this.form.is_arrange = res.is_arrange ? res.is_arrange : 0
this.form.is_fee = res.is_fee ? res.is_fee : 0
this.form.is_virtual = res.is_virtual ? res.is_virtual : 0
this.form.show_txl = res.show_txl === 0 ? 0 : 1
this.form.show_mobile = res.show_mobile ? res.show_mobile : 0
this.form.auto_schoolmate = res.auto_schoolmate ? res.auto_schoolmate : 0
this.showTinymce = true
})
},
onIsArrangeChange() {
// 切换是否排课时重置地址相关字段
this.form.address_detail = ''
this.form.longitude = ''
this.form.latitude = ''
this.addrMapForm = []
},
// 下一步
next() {
if (this.id) {
this.active = 1
} else {
this.$Message.warning("请先保存课程信息")
}
},
// 获取自定义表单列表
async getFormList() {
const res = await formIndex({
filter: [{
key: 'course_id',
op: 'eq',
value: this.id
}],
...this.selectForm
})
this.formList = res.data
},
// 打开自定义表单
editForm(type, id) {
// this.$refs.applyForm.formList = deepCopy(this.formList)
if (type === 'add') {
this.$refs.applyForm.showStartTips = true
}
this.$refs.applyForm.course_id = this.id
this.$refs.applyForm.course_signs_count = this.course_signs_count
this.$refs.applyForm.dialogVisible = true
},
onMapChange(val) {
this.addrMapForm = val;
this.form.address_detail = val.address;
this.form.longitude = val.longitude;
this.form.latitude = val.latitude;
}
},
watch: {
addrMapForm(newVal) {
if (Array.isArray(newVal) && newVal.length >= 3) {
this.form.longitude = newVal[0]
this.form.latitude = newVal[1]
this.form.address_detail = newVal[2]
}
},
isShow(newVal) {
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
this.getFormList()
} else {
this.showTinymce = true
}
} else {
this.id = ''
this.course_signs_count = 0
this.showTinymce = false
this.imgList = []
this.qunList = []
this.publicizeList = []
this.active = 0
this.formList = []
this.form = {
step: '', // 控制课程 课表
type: '',
name: '',
is_virtual: 0,
url: '',
year: '',
dateRange: '',
total: '',
sign_start_date: '',
sign_end_date: '',
status: 0,
applylabel: '',
address_detail: '',
longitude: '',
latitude: '',
is_arrange: 1,
is_fee: 1,
show_txl: 1,
show_mobile: 1,
auto_schoolmate: 0,
qun_image_id: '',
image_id: '',
publicize_ids: [],
content: '',
url_title:''
}
this.$refs['dialog'].reset()
}
},
}
}
</script>
<style scoped lang="scss">
::v-deep .content,
::v-deep .step,
::v-deep .applylabel,
::v-deep .image_id,
::v-deep .publicize_ids {
flex-basis: 100%;
}
::v-deep .is_arrange,
::v-deep .is_fee,
::v-deep .show_txl,
::v-deep .show_mobile,
{
flex-basis: 25%;
}
::v-deep .el-step.is-simple .el-step__head {
display: flex
}
</style>