1257 lines
39 KiB
Vue
1257 lines
39 KiB
Vue
<template>
|
||
<div class="batch-create">
|
||
<el-steps :active="stepActive" simple>
|
||
<el-step title="1 基础设置"></el-step>
|
||
<el-step title="2 直播设置"></el-step>
|
||
</el-steps>
|
||
|
||
<template v-if="stepActive === 1">
|
||
<div class="batch-create-container">
|
||
<div class="row">
|
||
<el-button type="primary" @click="addLive">添加直播</el-button>
|
||
</div>
|
||
<div class="row">
|
||
<el-button @click="openDialog(1)">设置直播名称</el-button>
|
||
<el-button @click="openDialog(3)">设置封面</el-button>
|
||
<el-button v-if="zhujiao" @click="openDialog(2)">讲师设置</el-button>
|
||
<el-button @click="change(4)">移除</el-button>
|
||
<span>每次最多支持添加50个直播</span>
|
||
</div>
|
||
<div class="row">
|
||
<el-table
|
||
ref="multipleTable"
|
||
:data="data"
|
||
size="small"
|
||
@selection-change="handleSelectionChange"
|
||
>
|
||
<el-table-column type="selection" width="55"> </el-table-column>
|
||
<el-table-column
|
||
prop="index"
|
||
label="序号"
|
||
width="80"
|
||
></el-table-column>
|
||
<el-table-column prop="title" label="直播名称">
|
||
<template slot-scope="scope">
|
||
<el-input
|
||
v-model="scope.row.title"
|
||
placeholder="直播名称"
|
||
size="small"
|
||
></el-input>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="imgUrl" label="详情封面" width="90">
|
||
<template slot-scope="scope">
|
||
<el-upload
|
||
class="avatar-uploader"
|
||
:show-file-list="false"
|
||
:on-success="res => handleSuccess(res, scope.row)"
|
||
:on-error="handleError"
|
||
:headers="headers"
|
||
action="/admin/common/file/upload"
|
||
:before-upload="beforeUpload"
|
||
>
|
||
<img
|
||
v-if="scope.row.imgUrl"
|
||
:src="scope.row.imgUrl"
|
||
class="avatar"
|
||
/>
|
||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||
<div slot="tip" class="el-upload__tip"></div>
|
||
</el-upload>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="time" label="计划直播时间" width="380">
|
||
<template slot-scope="scope">
|
||
<el-date-picker
|
||
v-model="scope.row.time"
|
||
prop="time"
|
||
type="datetimerange"
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
:picker-options="pickerOptions"
|
||
size="small"
|
||
style="width: 360px;"
|
||
format="yyyy-MM-dd HH:mm"
|
||
>
|
||
</el-date-picker>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column v-if="zhujiao" prop="teacherName" label="讲师名称">
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="150">
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
v-if="zhujiao"
|
||
type="text"
|
||
@click="openDialog(2, scope.row)"
|
||
>讲师设置</el-button
|
||
>
|
||
<el-button type="text" @click="remove(scope.row)"
|
||
>移除</el-button
|
||
>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</div>
|
||
<div class="row text-center">
|
||
<el-button type="primary" @click="nextStep">下一步</el-button>
|
||
</div>
|
||
</template>
|
||
<template v-if="stepActive === 2">
|
||
<div class="batch-create-container">
|
||
<el-form
|
||
ref="ruleForm"
|
||
:model="ruleForm"
|
||
:rules="rules"
|
||
label-width="150px"
|
||
class="demo-ruleForm"
|
||
>
|
||
<el-form-item label="播放类型" prop="playType">
|
||
<el-select v-model="ruleForm.playType" placeholder="请选择播放类型">
|
||
<el-option label="直播" :value="1"></el-option>
|
||
<!-- <el-option label="录播" :value="2"></el-option> -->
|
||
</el-select>
|
||
<el-upload
|
||
v-if="ruleForm.playType === 2"
|
||
class="upload-demo"
|
||
action="/"
|
||
:limit="1"
|
||
:on-change="handleChange"
|
||
:on-remove="
|
||
() => {
|
||
ruleForm.libraryId = null;
|
||
}
|
||
"
|
||
:before-upload="
|
||
rawFile => checkFile(rawFile, ['mp4'], 1024 * 1024 * 1024)
|
||
"
|
||
:http-request="options => myUpload(options)"
|
||
:file-list="fileList"
|
||
>
|
||
<el-button size="small" type="primary">点击上传</el-button>
|
||
<div slot="tip" class="el-upload__tip">
|
||
只能上传mp4文件,且不超过1G
|
||
</div>
|
||
</el-upload>
|
||
</el-form-item>
|
||
<!-- <el-form-item label="视频形式" prop="playStyle">
|
||
<el-radio-group v-model="ruleForm.playStyle">
|
||
<el-radio :label="1">竖屏</el-radio>
|
||
<el-radio :label="2">横屏</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item> -->
|
||
<el-form-item label="本期看点" prop="viewPoint">
|
||
<el-input
|
||
v-model="ruleForm.viewPoint"
|
||
type="textarea"
|
||
maxlength="500"
|
||
show-word-limit
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item v-if="sameAdvisorId" label="所属合集">
|
||
<serial-select
|
||
v-model="ruleForm.serialIds"
|
||
:advisor-id="sameAdvisorId"
|
||
multiple
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item v-if="sameAdvisorId" label="所属课程">
|
||
<course-select
|
||
v-model="ruleForm.courseIds"
|
||
:advisor-id="sameAdvisorId"
|
||
multiple
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="观看限制">
|
||
<el-radio-group v-model="ruleForm.limitType">
|
||
<el-radio :label="1">无限制</el-radio>
|
||
<el-radio v-if="!settingToC" :label="2">手机号登录</el-radio>
|
||
<el-radio :label="3">邀请码观看</el-radio>
|
||
<el-radio v-if="!settingToC" :label="4">微信授权</el-radio>
|
||
<el-radio v-if="!settingToC" :label="5">产品专属直播</el-radio>
|
||
<el-radio :label="6">权限判定</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item v-if="ruleForm.limitType === 5">
|
||
<el-select
|
||
v-model="ruleForm.productType"
|
||
clearable
|
||
placeholder="请选择产品类型"
|
||
style="margin-right:20px"
|
||
>
|
||
<el-option
|
||
v-for="(item, index) in productTypeList"
|
||
:key="index"
|
||
:label="item.productName"
|
||
:value="item.productType"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
<el-select
|
||
v-model="ruleForm.productId"
|
||
style="margin-right:20px"
|
||
filterable
|
||
remote
|
||
reserve-keyword
|
||
placeholder="请选择需要关联的产品"
|
||
:remote-method="remoteMethodProductTwo"
|
||
:loading="loadingProductTwo"
|
||
>
|
||
<el-option
|
||
v-for="item in productListTwo"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item
|
||
v-if="ruleForm.limitType === 3"
|
||
label="邀请码"
|
||
prop="inviteCode"
|
||
>
|
||
<el-input
|
||
v-model="ruleForm.inviteCode"
|
||
maxlength="4"
|
||
show-word-limit
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item
|
||
v-if="ruleForm.limitType === 6"
|
||
label="权限号"
|
||
prop="authorityId"
|
||
>
|
||
<el-input
|
||
v-model="ruleForm.authorityId"
|
||
placeholder="请输入多个权限号,多个权限号可通过逗号区分"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="是否配置购物车">
|
||
<el-radio-group v-model="ruleForm.isCart">
|
||
<el-radio :label="2">不配置</el-radio>
|
||
<el-radio :label="1">配置</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item v-if="ruleForm.isCart === 1 && !settingToC">
|
||
<el-select
|
||
v-model="ruleForm.cartProductType"
|
||
placeholder="请选择配置的产品类型"
|
||
style="margin-bottom:20px;"
|
||
>
|
||
<el-option
|
||
v-for="(item, index) in productTypeList"
|
||
:key="index"
|
||
:label="item.productName"
|
||
:value="item.productType"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
<el-select
|
||
v-model="ruleForm.productListId"
|
||
filterable
|
||
remote
|
||
reserve-keyword
|
||
placeholder="请选择产品"
|
||
:remote-method="remoteMethodProduct"
|
||
:loading="loadingProduct"
|
||
prop="columnId"
|
||
@change="changeItem"
|
||
>
|
||
<el-option
|
||
v-for="item in productList"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
:disabled="
|
||
(ruleForm.cartList || [])
|
||
.map(item => item.productId)
|
||
.includes(item.id)
|
||
"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
<div>
|
||
<el-tag
|
||
v-for="(tag, index) in ruleForm.cartList"
|
||
:key="tag.name"
|
||
:disabled="
|
||
$route.query.type === '2' || $route.query.type === '3'
|
||
"
|
||
style="margin-right:10px"
|
||
:closable="!['2', '3'].includes($route.query.type)"
|
||
type="success"
|
||
@close="deleteCart(index, tag.id)"
|
||
>
|
||
{{ tag.name }}
|
||
</el-tag>
|
||
</div>
|
||
</el-form-item>
|
||
<!-- c端添加H5按钮 -->
|
||
<el-form-item v-if="ruleForm.isCart === 1 && settingToC">
|
||
<el-button type="primary" @click="dialogFormVisible = true"
|
||
>添加自定义产品</el-button
|
||
>
|
||
<div>
|
||
<el-tag
|
||
v-for="(tag, index) in ruleForm.cartList"
|
||
:key="index"
|
||
:disabled="
|
||
$route.query.type === '2' || $route.query.type === '3'
|
||
"
|
||
style="margin-right:10px"
|
||
:closable="!['2', '3'].includes($route.query.type)"
|
||
type="success"
|
||
@close="deleteShopping(index, tag.id)"
|
||
>
|
||
{{ tag.productName }}
|
||
</el-tag>
|
||
</div>
|
||
</el-form-item>
|
||
<!-- 个人主页是否展示 -->
|
||
<el-form-item label="个人主页是否展示">
|
||
<el-radio-group v-model="ruleForm.isShow">
|
||
<el-radio :label="1">是</el-radio>
|
||
<el-radio :label="2">否</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<!-- 互动区展示内容 -->
|
||
<el-form-item label="互动区展示内容">
|
||
<el-radio-group v-model="ruleForm.interactType">
|
||
<el-radio :label="1">全部互动</el-radio>
|
||
<el-radio :label="2">投顾消息</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item label="风险等级">
|
||
<el-select
|
||
v-model="ruleForm.riskLevel"
|
||
placeholder="请选择风险等级"
|
||
clearable
|
||
>
|
||
<el-option label="低风险" :value="1"></el-option>
|
||
<el-option label="中低风险" :value="2"></el-option>
|
||
<el-option label="中风险" :value="3"></el-option>
|
||
<el-option label="中高风险" :value="4"></el-option>
|
||
<el-option label="高风险" :value="5"></el-option>
|
||
</el-select>
|
||
<!-- <p>观看门槛为不限制或手机号登录即可观看的风险等级固定为低风险</p> -->
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="submitForm('ruleForm')"
|
||
>提交</el-button
|
||
>
|
||
<!-- <el-button @click="resetForm('ruleForm')">重置</el-button> -->
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</template>
|
||
|
||
<el-dialog
|
||
v-if="dialogBatchForm.visible"
|
||
:visible.sync="dialogBatchForm.visible"
|
||
:title="dialogBatchForm.title"
|
||
:modal-append-to-body="false"
|
||
:close-on-click-modal="false"
|
||
>
|
||
<div v-if="dialogBatchForm.type === 1">
|
||
<el-input
|
||
v-model="dialogBatchForm.value"
|
||
placeholder="请输入直播名称"
|
||
></el-input>
|
||
<p>
|
||
提示:批量修改的直播将按照“直播名称-1”、“直播名称-2”、“直播名称-3”的规律命名。
|
||
</p>
|
||
</div>
|
||
<div v-else-if="dialogBatchForm.type === 2">
|
||
<adviser-select
|
||
v-model="dialogBatchForm.value"
|
||
:name.sync="dialogBatchForm.name"
|
||
:dept-id="user.user.deptId"
|
||
@init="
|
||
item => {
|
||
dialogBatchForm.value = item.id;
|
||
dialogBatchForm.name = item.name;
|
||
}
|
||
"
|
||
></adviser-select>
|
||
</div>
|
||
<div v-else style="text-align: center;">
|
||
<el-upload
|
||
class="avatar-uploader"
|
||
:show-file-list="false"
|
||
:on-success="res => handleSuccess(res, dialogBatchForm)"
|
||
:on-error="handleError"
|
||
:headers="headers"
|
||
action="/admin/common/file/upload"
|
||
:before-upload="beforeUpload"
|
||
>
|
||
<img
|
||
v-if="dialogBatchForm.imgUrl"
|
||
:src="dialogBatchForm.imgUrl"
|
||
class="avatar"
|
||
/>
|
||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||
<div slot="tip" class="el-upload__tip"></div>
|
||
</el-upload>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="dialogBatchForm.visible = false">取消</el-button>
|
||
<el-button type="primary" @click="change()">确定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<el-dialog
|
||
title="添加自定义产品"
|
||
:visible.sync="dialogFormVisible"
|
||
:modal-append-to-body="false"
|
||
:close-on-click-modal="false"
|
||
@close="cancel()"
|
||
>
|
||
<el-form
|
||
ref="dialogForm"
|
||
:model="dialogForm"
|
||
:rules="rulesDialog"
|
||
label-width="80px"
|
||
>
|
||
<el-form-item label="产品名称" prop="productName">
|
||
<el-input
|
||
v-model="dialogForm.productName"
|
||
placeholder="请输入产品名称"
|
||
autocomplete="off"
|
||
maxlength="20"
|
||
clearable
|
||
show-word-limit
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="产品介绍" prop="productDesc">
|
||
<el-input
|
||
v-model="dialogForm.productDesc"
|
||
type="textarea"
|
||
placeholder="请输入产品介绍"
|
||
autocomplete="off"
|
||
maxlength="100"
|
||
clearable
|
||
show-word-limit
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="封面图">
|
||
<el-upload
|
||
class="avatar-uploader"
|
||
:show-file-list="false"
|
||
:on-success="dialogHandleSuccess"
|
||
:on-error="handleError"
|
||
:headers="headers"
|
||
action="/admin/common/file/upload"
|
||
:before-upload="beforeUpload"
|
||
>
|
||
<img
|
||
v-if="dialogForm.coverImgUrl"
|
||
:src="dialogForm.coverImgUrl"
|
||
class="avatar"
|
||
/>
|
||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||
<div slot="tip" class="el-upload__tip">
|
||
只能上传jpg/png文件,且不超过1MB,建议尺寸104*140px;在直播间推荐产品后悬浮展示在右下角,若本场直播不涉及推送产品的场景,无需上传该封面图
|
||
</div>
|
||
</el-upload>
|
||
</el-form-item>
|
||
<el-form-item label="产品链接" prop="url">
|
||
<el-input
|
||
v-model="dialogForm.url"
|
||
autocomplete="off"
|
||
placeholder="请输入产品链接"
|
||
clearable
|
||
></el-input>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="cancel()">取 消</el-button>
|
||
<el-button type="primary" @click="confirmDialog()">确 定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getToken } from "@/utils/auth";
|
||
import { mapState, mapGetters } from "vuex";
|
||
import SerialSelect from "@/views/serial/components/select2.vue";
|
||
import CourseSelect from "@/views/circle/components/select2.vue";
|
||
import AdviserSelect from "@/views/adviser/components/select.vue";
|
||
import {
|
||
getColumnList,
|
||
tagList,
|
||
uploadSign,
|
||
librarySave,
|
||
infoGet,
|
||
updateStatus,
|
||
packageList,
|
||
batchSave
|
||
} from "@/api/videoLive";
|
||
|
||
import TcVod from "vod-js-sdk-v6";
|
||
import moment from "moment/moment";
|
||
|
||
export default {
|
||
components: { AdviserSelect, SerialSelect, CourseSelect },
|
||
data() {
|
||
var validateInviteCode = (rule, value, callback) => {
|
||
if (!value) {
|
||
return callback(new Error("请输入邀请码"));
|
||
}
|
||
const inviteCode = value.toString();
|
||
const isNum = /^\d{4}$/.test(inviteCode);
|
||
if (inviteCode.length !== 4 || isNaN(inviteCode) || !isNum) {
|
||
return callback(new Error("邀请码必须是4位数字"));
|
||
}
|
||
callback();
|
||
};
|
||
var validateURL = (rule, value, callback) => {
|
||
if (!value) {
|
||
return callback(new Error("请输入产品链接"));
|
||
}
|
||
const urlRegex = /^(http|https):\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/\S*)?$/;
|
||
if (!urlRegex.test(value)) {
|
||
return callback(new Error("无效的产品链接"));
|
||
}
|
||
callback();
|
||
};
|
||
return {
|
||
stepActive: 1,
|
||
multipleSelection: [],
|
||
data: [],
|
||
dialogBatchForm: {
|
||
visible: false,
|
||
type: 1,
|
||
title: "添加直播"
|
||
},
|
||
advisorList: [],
|
||
|
||
id: null,
|
||
type: 1,
|
||
form: {
|
||
status: null,
|
||
reason: "",
|
||
id: null,
|
||
inviteCode: ""
|
||
},
|
||
dialogForm: {
|
||
productName: "",
|
||
productDesc: "",
|
||
productType: 111,
|
||
url: "",
|
||
coverImgUrl: ""
|
||
},
|
||
ruleForm: {
|
||
title: "",
|
||
playType: 1,
|
||
startTime: "",
|
||
endTime: "",
|
||
isColumn: 0,
|
||
viewPoint: "",
|
||
limitType: 1,
|
||
columnId: null,
|
||
isCart: 2,
|
||
authIds: [],
|
||
serialIds: [],
|
||
courseIds: [],
|
||
teacherId: "",
|
||
cartList: [],
|
||
productType: 1,
|
||
cartProductType: 1,
|
||
riskLevel: null,
|
||
playStyle: 2,
|
||
isShow: 1,
|
||
interactType: 1
|
||
},
|
||
time: [],
|
||
loading: false,
|
||
loadingTag: false,
|
||
loadingProduct: false,
|
||
productList: [],
|
||
loadingProductTwo: false,
|
||
productListTwo: [],
|
||
tagIdList: [],
|
||
columnList: [],
|
||
options: [],
|
||
optionsTag: [],
|
||
fileList: [],
|
||
productListId: [],
|
||
headers: {
|
||
Authorization: "Bearer " + getToken(),
|
||
"X-File-Size": 0
|
||
},
|
||
productTypeList: [],
|
||
dialogFormVisible: false,
|
||
rulesDialog: {
|
||
productName: [
|
||
{ required: true, message: "请输入产品名称", trigger: "blur" },
|
||
{ min: 1, max: 50, message: "长度在 1 到 20 个字符", trigger: "blur" }
|
||
],
|
||
productDesc: [
|
||
{ required: true, message: "请输入产品介绍", trigger: "blur" },
|
||
{
|
||
min: 1,
|
||
max: 100,
|
||
message: "长度在 1 到 100 个字符",
|
||
trigger: "blur"
|
||
}
|
||
],
|
||
url: [{ required: true, validator: validateURL, trigger: "blur" }]
|
||
},
|
||
rules: {
|
||
title: [
|
||
{ required: true, message: "请输入标题", trigger: "blur" },
|
||
{ min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" }
|
||
],
|
||
reason: [
|
||
{ required: true, message: "请输入驳回理由", trigger: "blur" },
|
||
{ min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" }
|
||
],
|
||
status: [{ required: true, message: "请选择", trigger: "change" }],
|
||
playType: [
|
||
{ required: true, message: "请选择播放类型", trigger: "change" }
|
||
],
|
||
inviteCode: [{ validator: validateInviteCode, trigger: "blur" }],
|
||
playStyle: [
|
||
{ required: true, message: "请选择视频形式", trigger: "change" }
|
||
],
|
||
isColumn: [{ required: true, message: "请选择", trigger: "change" }],
|
||
viewPoint: [
|
||
{ required: true, message: "请填写本期看点", trigger: "blur" }
|
||
],
|
||
imgUrl: [{ required: true, message: "请上传封面", trigger: "blur" }]
|
||
},
|
||
pickerOptions: {
|
||
disabledDate(time) {
|
||
// 获取当前时间
|
||
const now = new Date();
|
||
// 减去5分钟(5分钟 = 5 * 60 * 1000 毫秒)
|
||
const fiveMinutesAgo = new Date(now.getTime() - 5 * 60 * 1000);
|
||
return time.getTime() < fiveMinutesAgo.getTime();
|
||
}
|
||
}
|
||
};
|
||
},
|
||
computed: {
|
||
...mapGetters(["user"]),
|
||
...mapState({
|
||
settingToC: state => state.settings.settingToC
|
||
}),
|
||
zhujiao() {
|
||
if (!this.user || !this.user.roles) return false;
|
||
return this.user.roles.includes("助教");
|
||
},
|
||
sameAdvisorId() {
|
||
const advisorId = this.data.length > 0 ? this.data[0].teacherId : "";
|
||
|
||
for (const item of this.data) {
|
||
if (advisorId !== item.teacherId) return "";
|
||
}
|
||
|
||
return advisorId;
|
||
}
|
||
},
|
||
methods: {
|
||
nextStep() {
|
||
if (this.data.length === 0) {
|
||
this.$message.error("请添加直播");
|
||
return;
|
||
}
|
||
for (let i = 0; i < this.data.length; i++) {
|
||
const item = this.data[i];
|
||
const index = i + 1;
|
||
if (item.title === "") {
|
||
this.$message.error(`直播${index}名称不能为空`);
|
||
return;
|
||
}
|
||
if (item.imgUrl === "") {
|
||
this.$message.error(`直播${index}封面不能为空`);
|
||
return;
|
||
}
|
||
if (
|
||
!Array.isArray(item.time) ||
|
||
item.time[0] === "" ||
|
||
item.time[1] === ""
|
||
) {
|
||
this.$message.error(`直播${index}时间不能为空`);
|
||
return;
|
||
}
|
||
if (item.teacherId === "") {
|
||
this.$message.error(`直播${index}讲师不能为空`);
|
||
return;
|
||
}
|
||
}
|
||
this.stepActive = 2;
|
||
},
|
||
addLive() {
|
||
if (this.data.length >= 50) {
|
||
this.$message.error("最多只能添加50个直播");
|
||
return;
|
||
}
|
||
|
||
const advisorInfo = (this.user && this.user.advisorInfo) || {};
|
||
const index = this.data.length + 1;
|
||
const last = this.data[this.data.length - 1];
|
||
let title = this.user.user.name + "的直播间-1";
|
||
if (last) {
|
||
const list = last.title.split("-");
|
||
if (list.length === 1) {
|
||
title = list[0] + "-" + index;
|
||
} else if (list.length > 1) {
|
||
const lastIndex = list[list.length - 1];
|
||
const newIndex = isNaN(parseInt(lastIndex))
|
||
? index
|
||
: parseInt(lastIndex) + 1;
|
||
title = list.slice(0, list.length - 1).join("-") + "-" + newIndex;
|
||
}
|
||
}
|
||
const imgUrl = last ? last.imgUrl : "";
|
||
// 当前时间的下一个整点
|
||
const startTime = moment()
|
||
.add(1, "hours")
|
||
.minute(0)
|
||
.second(0)
|
||
.format("YYYY-MM-DD HH:mm:ss");
|
||
const endTime = moment(startTime)
|
||
.add(1, "hours")
|
||
.format("YYYY-MM-DD HH:mm:ss");
|
||
const time = last
|
||
? [
|
||
moment(last.time[0])
|
||
.add(1, "days")
|
||
.format("YYYY-MM-DD HH:mm:ss"),
|
||
moment(last.time[1])
|
||
.add(1, "days")
|
||
.format("YYYY-MM-DD HH:mm:ss")
|
||
]
|
||
: [startTime, endTime];
|
||
const teacherId = (last ? last.teacherId : "") || advisorInfo.id || "";
|
||
const teacherName =
|
||
(last ? last.teacherName : "") || advisorInfo.id || "";
|
||
|
||
this.data.push({
|
||
index,
|
||
title,
|
||
imgUrl,
|
||
time,
|
||
teacherId,
|
||
teacherName
|
||
});
|
||
},
|
||
openDialog(type, row) {
|
||
if (!row && this.multipleSelection.length === 0) {
|
||
this.$message.error("请选择要操作的直播!");
|
||
return;
|
||
}
|
||
const map = {
|
||
1: { title: "设置直播名称", value: "" },
|
||
2: { title: "讲师设置", value: "" },
|
||
3: { title: "设置封面", imgUrl: "" }
|
||
};
|
||
this.current = row;
|
||
this.dialogBatchForm = {
|
||
visible: true,
|
||
type,
|
||
value: "",
|
||
name: "",
|
||
...(map[type] || {})
|
||
};
|
||
},
|
||
change(type) {
|
||
if (!this.current && !this.multipleSelection.length) {
|
||
this.$message.error("请选择要操作的直播!");
|
||
return;
|
||
}
|
||
if (type) {
|
||
this.data = this.data.filter(
|
||
item => !this.multipleSelection.includes(item)
|
||
);
|
||
this.data = this.data.map((item, index) => ({
|
||
...item,
|
||
index: index + 1
|
||
}));
|
||
} else if (this.dialogBatchForm.type === 1) {
|
||
if (this.dialogBatchForm.value) {
|
||
for (let i = 0; i < this.multipleSelection.length; i++) {
|
||
const item = this.multipleSelection[i];
|
||
|
||
item.title = this.dialogBatchForm.value + "-" + (i + 1);
|
||
}
|
||
} else {
|
||
this.$message.error("请输入直播名称!");
|
||
return;
|
||
}
|
||
} else if (this.dialogBatchForm.type === 2) {
|
||
if (this.dialogBatchForm.value) {
|
||
if (this.current) {
|
||
this.current.teacherId = this.dialogBatchForm.value;
|
||
this.current.teacherName = this.dialogBatchForm.name;
|
||
} else {
|
||
for (const item of this.multipleSelection) {
|
||
item.teacherId = this.dialogBatchForm.value;
|
||
item.teacherName = this.dialogBatchForm.name;
|
||
}
|
||
}
|
||
} else {
|
||
this.$message.error("请选择讲师!");
|
||
return;
|
||
}
|
||
} else if (this.dialogBatchForm.type === 3) {
|
||
if (this.dialogBatchForm.imgUrl) {
|
||
for (const item of this.multipleSelection) {
|
||
item.imgUrl = this.dialogBatchForm.imgUrl;
|
||
}
|
||
} else {
|
||
this.$message.error("请上传封面!");
|
||
return;
|
||
}
|
||
}
|
||
this.dialogBatchForm = {
|
||
visible: false
|
||
};
|
||
},
|
||
remove(row) {
|
||
const index = this.data.findIndex(item => item === row);
|
||
if (index === -1) return;
|
||
|
||
this.data.splice(index, 1);
|
||
this.data = this.data.map((item, index) => ({
|
||
...item,
|
||
index: index + 1
|
||
}));
|
||
},
|
||
handleClose() {
|
||
this.$refs.multipleTable.toggleRowSelection(this.data[0]);
|
||
},
|
||
toggleSelection(all) {
|
||
if (all) {
|
||
this.$refs.multipleTable.toggleAllSelection();
|
||
} else {
|
||
this.$refs.multipleTable.clearSelection();
|
||
}
|
||
},
|
||
handleSelectionChange(val) {
|
||
this.multipleSelection = val;
|
||
},
|
||
submitForm(formName) {
|
||
this.$refs[formName].validate(valid => {
|
||
if (valid) {
|
||
// this.ruleForm.startTime = this.time[0] ? dayjs(this.time[0]).format(
|
||
// "YYYY-MM-DD HH:mm:ss"
|
||
// ) : '';
|
||
// this.ruleForm.endTime = this.time[0] ? dayjs(this.time[1]).format(
|
||
// "YYYY-MM-DD HH:mm:ss"
|
||
// ) : '';
|
||
this.ruleForm.playStyle = Number(this.$route.query.playStyle) || 2;
|
||
if (this.ruleForm.playType === 2 && !this.ruleForm.libraryId) {
|
||
this.$message.error("请上传录播视频!");
|
||
return;
|
||
}
|
||
if (this.ruleForm.isCart === 1 && !this.ruleForm.cartList.length) {
|
||
this.$message.error("请配置购物车产品!");
|
||
return;
|
||
}
|
||
if (
|
||
this.ruleForm.limitType === 3 &&
|
||
!this.ruleForm.inviteCode.trim()
|
||
) {
|
||
this.$message.error("请填写邀请码!");
|
||
return;
|
||
}
|
||
if (
|
||
this.ruleForm.limitType === 5 &&
|
||
(!this.ruleForm.productId || !this.ruleForm.productType)
|
||
) {
|
||
this.$message.error("请选择需要关联的产品!");
|
||
return;
|
||
}
|
||
if (this.ruleForm.limitType !== 5) {
|
||
this.ruleForm.productId = null;
|
||
this.ruleForm.productType = null;
|
||
}
|
||
|
||
if (this.settingToC && this.ruleForm.isCart === 1) {
|
||
this.ruleForm.cartList.forEach((item, index) => {
|
||
item.productId = index + 1;
|
||
});
|
||
}
|
||
if (this.settingToC && this.ruleForm.limitType === 1) {
|
||
this.ruleForm.limitType === 2;
|
||
}
|
||
batchSave(
|
||
this.data.map(item => ({
|
||
...this.ruleForm,
|
||
...item,
|
||
startTime: moment(item.time[0]).format("YYYY-MM-DD HH:00:00"),
|
||
endTime: moment(item.time[1]).format("YYYY-MM-DD HH:00:00")
|
||
}))
|
||
).then(data => {
|
||
if (data.code === 0) {
|
||
this.$message({
|
||
message: "操作成功",
|
||
type: "success"
|
||
});
|
||
if (this.$route.query.isZj === "1") {
|
||
this.$router.push("/liveBroadcast/liveBroadcastListZj");
|
||
} else {
|
||
this.$router.push("/liveBroadcast/liveBroadcastList");
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
console.log("error submit!!");
|
||
return false;
|
||
}
|
||
});
|
||
},
|
||
resetForm(formName) {
|
||
this.$refs[formName].resetFields();
|
||
},
|
||
handleSuccess(response, row) {
|
||
setTimeout(() => {
|
||
row.imgUrl = response.data.url;
|
||
}, 100);
|
||
this.$notify({
|
||
title: "封面上传成功",
|
||
type: "success",
|
||
duration: 2500
|
||
});
|
||
},
|
||
dialogHandleSuccess(response) {
|
||
this.dialogForm.coverImgUrl = response.data.url;
|
||
},
|
||
beforeUpload(file) {
|
||
if (file.type !== "image/jpeg" && file.type !== "image/png") {
|
||
this.$message.error("上传只支持jpeg格式和png格式!");
|
||
return false;
|
||
}
|
||
const isLt = file.size / 1024 < 1024;
|
||
if (!isLt) {
|
||
this.$message.error("上传文件大小不能超过 1MB!");
|
||
}
|
||
this.headers["X-File-Size"] = file.size;
|
||
return isLt;
|
||
},
|
||
// 监听上传失败
|
||
handleError(e, file, fileList) {
|
||
const msg = JSON.parse(e.message);
|
||
this.$notify({
|
||
title: msg.message,
|
||
type: "error",
|
||
duration: 2500
|
||
});
|
||
},
|
||
remoteMethod(query) {
|
||
if (this.ruleForm.isColumn === 1 || !query) {
|
||
this.loading = true;
|
||
const queryParams = {
|
||
columnName: query,
|
||
current: 1,
|
||
size: 99,
|
||
status: 3
|
||
};
|
||
getColumnList(queryParams).then(data => {
|
||
this.options = data.data.list;
|
||
this.loading = false;
|
||
});
|
||
} else {
|
||
this.options = [];
|
||
}
|
||
},
|
||
remoteMethodTag(query) {
|
||
this.loadingTag = true;
|
||
const queryParams = {
|
||
name: query,
|
||
current: 1,
|
||
size: 99,
|
||
type: 3,
|
||
status: 1
|
||
};
|
||
tagList(queryParams).then(data => {
|
||
this.optionsTag = data.data.list;
|
||
this.loadingTag = false;
|
||
});
|
||
},
|
||
handleChange(file, fileList) {
|
||
this.fileList = fileList.slice();
|
||
},
|
||
checkFile(rawFile, type, size) {
|
||
// const limitType = type.includes(
|
||
// rawFile.name.substring(rawFile.name.lastIndexOf('.') + 1)
|
||
// )
|
||
if (rawFile.type !== "video/mp4") {
|
||
this.$message.error("上传文件格式有误!");
|
||
return Promise.reject();
|
||
}
|
||
const isLimit = rawFile.size < size;
|
||
if (!isLimit) {
|
||
this.$message.error("上传文件过大!");
|
||
return Promise.reject();
|
||
}
|
||
return Promise.resolve(true);
|
||
},
|
||
myUpload(options) {
|
||
// 视频走腾讯云上传
|
||
return new Promise(resolve => {
|
||
const tcVod = new TcVod({
|
||
getSignature: async () => (await uploadSign()).data
|
||
});
|
||
const uploader = tcVod.upload({
|
||
mediaFile: options.file
|
||
});
|
||
uploader.on("media_progress", info => {
|
||
options.onProgress({
|
||
...info,
|
||
percent: Number((info.percent * 100).toFixed(1))
|
||
});
|
||
});
|
||
uploader.done().then(doneResult => {
|
||
options.onSuccess({});
|
||
librarySave({ fileId: doneResult.fileId }).then(data => {
|
||
if (data.code === 0) {
|
||
this.ruleForm.libraryId = data.data.id;
|
||
} else {
|
||
this.$message.error("获取录播数据失败!");
|
||
}
|
||
});
|
||
resolve(doneResult.fileId);
|
||
});
|
||
});
|
||
},
|
||
getDetail() {
|
||
infoGet({ id: this.id }).then(res => {
|
||
if (res.code === 0) {
|
||
// 是否专栏
|
||
if (res.data.columnId) {
|
||
res.data.isColumn = 1;
|
||
this.remoteMethod();
|
||
// this.options.push({
|
||
// name: res.data.columnName,
|
||
// id: res.data.columnId
|
||
// });
|
||
} else {
|
||
res.data.isColumn = 0;
|
||
}
|
||
// 是否配置购物车
|
||
if (res.data.cartVOList.length) {
|
||
res.data.isCart = 1;
|
||
} else {
|
||
res.data.isCart = 2;
|
||
}
|
||
// 是否录播
|
||
if (res.data.playType === 2) {
|
||
this.fileList = [{ name: res.data.libraryName }];
|
||
}
|
||
if (res.data.cartVOList.length) {
|
||
for (let index = 0; index < res.data.cartVOList.length; index++) {
|
||
res.data.cartVOList[index].id =
|
||
res.data.cartVOList[index].productId;
|
||
res.data.cartVOList[index].name =
|
||
res.data.cartVOList[index].productName;
|
||
}
|
||
res.data.cartList = res.data.cartVOList;
|
||
} else {
|
||
res.data.cartList = [];
|
||
}
|
||
// 计划时间
|
||
this.time = [res.data.startTime, res.data.endTime];
|
||
if (res.data.tagVOList.length) {
|
||
// this.optionsTag = res.data.tagVOList;
|
||
res.data.tagIdList = res.data.tagVOList.map(v => {
|
||
return v.id;
|
||
});
|
||
} else {
|
||
// this.optionsTag = [];
|
||
res.data.tagIdList = [];
|
||
}
|
||
if (this.settingToC && res.data.limitType === 2) {
|
||
res.data.limitType === 1;
|
||
}
|
||
this.ruleForm = res.data;
|
||
} else {
|
||
this.$message.warning("获取直播详情失败!");
|
||
}
|
||
});
|
||
},
|
||
review(formName) {
|
||
this.$refs[formName].validate(valid => {
|
||
if (valid) {
|
||
this.$confirm(`您确定提交审核?`, {
|
||
confirmButtonText: "提交",
|
||
cancelButtonText: "取消",
|
||
type: "warning"
|
||
})
|
||
.then(() => {
|
||
this.form.id = this.id;
|
||
updateStatus(this.form).then(res => {
|
||
if (res.code === 0) {
|
||
this.$message({
|
||
type: "success",
|
||
message: "操作成功!"
|
||
});
|
||
this.$router.push("/liveBroadcast/liveBroadcastManage");
|
||
}
|
||
});
|
||
})
|
||
.catch(() => {});
|
||
}
|
||
});
|
||
},
|
||
remoteMethodProduct(query) {
|
||
this.loadingProduct = true;
|
||
const queryParams = {
|
||
packageName: query,
|
||
current: 1,
|
||
size: 99,
|
||
statusList: [3]
|
||
};
|
||
packageList(queryParams).then(data => {
|
||
this.productList = data.data.list;
|
||
this.loadingProduct = false;
|
||
});
|
||
},
|
||
remoteMethodProductTwo(query) {
|
||
this.loadingProductTwo = true;
|
||
const queryParams = {
|
||
packageName: query,
|
||
current: 1,
|
||
size: 99,
|
||
statusList: [3]
|
||
};
|
||
packageList(queryParams).then(data => {
|
||
this.productListTwo = data.data.list;
|
||
this.loadingProductTwo = false;
|
||
});
|
||
},
|
||
|
||
changeItem(e) {
|
||
let item = null;
|
||
for (let index = 0; index < this.productList.length; index++) {
|
||
if (this.productList[index].id === e) {
|
||
item = this.productList[index];
|
||
}
|
||
}
|
||
console.log(item, this.ruleForm.cartList);
|
||
this.ruleForm.cartList.push({
|
||
productId: item.id,
|
||
productType: this.ruleForm.cartProductType,
|
||
name: item.name
|
||
});
|
||
},
|
||
deleteCart(i, id) {
|
||
this.ruleForm.productListId = null;
|
||
this.ruleForm.cartList.splice(i, 1);
|
||
},
|
||
deleteShopping(i) {
|
||
this.ruleForm.cartList.splice(i, 1);
|
||
},
|
||
getProductList() {
|
||
const queryParams = {
|
||
packageName: "",
|
||
current: 1,
|
||
size: 99,
|
||
statusList: [3]
|
||
};
|
||
packageList(queryParams).then(data => {
|
||
this.productListTwo = data.data.list;
|
||
this.productList = data.data.list;
|
||
});
|
||
},
|
||
confirmDialog() {
|
||
this.$refs.dialogForm.validate(valid => {
|
||
if (valid) {
|
||
this.ruleForm.cartList.push(this.dialogForm);
|
||
this.cancel();
|
||
}
|
||
});
|
||
},
|
||
cancel() {
|
||
this.dialogForm = {
|
||
productName: "",
|
||
productDesc: "",
|
||
productType: 111,
|
||
url: "",
|
||
coverImgUrl: ""
|
||
};
|
||
this.dialogFormVisible = false;
|
||
}
|
||
},
|
||
async mounted() {
|
||
this.getProductList();
|
||
this.remoteMethodTag();
|
||
this.remoteMethod("");
|
||
if (this.$route.query.id) {
|
||
this.id = Number(this.$route.query.id);
|
||
this.type = Number(this.$route.query.type);
|
||
this.getDetail();
|
||
}
|
||
},
|
||
watch: {
|
||
"ruleForm.limitType"(value) {
|
||
if (value === 2) {
|
||
this.ruleForm.riskLevel = 1;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.batch-create {
|
||
padding: 20px;
|
||
|
||
.batch-create-container {
|
||
padding: 20px;
|
||
|
||
.row {
|
||
margin: 10px 0;
|
||
}
|
||
}
|
||
|
||
.text-center {
|
||
text-align: center;
|
||
}
|
||
|
||
::v-deep {
|
||
.el-table__cell {
|
||
padding-bottom: 2px;
|
||
}
|
||
}
|
||
|
||
.avatar-uploader .el-upload {
|
||
border: 1px dashed #d9d9d9;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.avatar-uploader .el-upload:hover {
|
||
border-color: #409eff;
|
||
}
|
||
|
||
.avatar-uploader-icon {
|
||
border: 1px dashed #d9d9d9;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
font-size: 28px;
|
||
color: #8c939d;
|
||
width: 78px;
|
||
height: 78px;
|
||
line-height: 78px;
|
||
text-align: center;
|
||
}
|
||
|
||
.avatar {
|
||
width: 78px;
|
||
height: 78px;
|
||
display: block;
|
||
}
|
||
}
|
||
</style>
|