beelink/src/views/mine/ReleaseWebcast.vue
2020-12-15 14:52:11 +08:00

848 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="webcast">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<div class="title">{{ lan.$t("zhiboxinxi") }}</div>
<a-form-item :label="lan.$t('zhibobiaoti')" :rules="{ required: true, message: 'Please input Activity name', trigger: 'blur'}">
<a-input
size="small"
v-model:value="form.title"
:placeholder="lan.$t('shuruzhibobiaoti')"
@click="isEntitled = jinzhi"
/>
</a-form-item>
<a-form-item :label="lan.$t('zhibofengmian')" class="item-cover" :rules="{ required: true, message: 'Please input Activity name', trigger: 'blur'}">
<div style="display:flex">
<a-upload
list-type="picture"
:customRequest="uploadspic"
:before-upload="imgs"
>
<div
class="upload-image"
v-if="!viewCover && form.img.length == 0"
>
<PlusOutlined
style="fontsize: 22px"
v-if="uploadpicprogress == 0"
/>
<a-progress
type="circle"
:percent="uploadpicprogress"
:width="80"
v-else
/>
</div>
<div class="upload-image" v-else>
<img
style="width: 100%; height: 100%"
:src="form.img"
/>
</div>
</a-upload>
<div class="demand">
<p>
{{ lan.$t("fengmianyaoqiu") }}
</p>
<p>
1.{{ lan.$t("fengmianyaoqiu1") }}
</p>
<p>
2.{{ lan.$t("fengmianyaoqiu2") }}
</p>
</div>
</div>
</a-form-item>
<a-form-item
:label="lan.$t('vshipinjieshao')"
class="video-introduction"
>
<a-upload
list-type="picture"
:customRequest="uploads"
:before-upload="video"
>
<div class="upload-image" v-if="form.fileurl.length == 0">
<PlaySquareOutlined
style="fontsize: 22px"
v-if="uploadprogress == 0"
/>
<a-progress
type="circle"
:percent="uploadprogress"
:width="80"
v-else
/>
<!-- <video style="display: none" :src="videofile"></video> -->
</div>
<div
class="upload-image upload"
style="position: relative"
v-show="form.fileurl.length != 0"
>
<video
:src="form.fileurl"
:ref="
(el) => {
videos[0] = el;
}
"
class="upload"
></video>
<!-- <a-progress type="circle" :percent="100" :width="80" style="position:absolute;right:35%"/> -->
</div>
</a-upload>
<div class="demand">
<p>
{{ lan.$t("shipinyaoqiu") }}
</p>
<p>1.{{ lan.$t("shipinyaoqiu1") }}</p>
<p>2.{{ lan.$t("shipinyaoqiu2") }}</p>
<p>3.{{ lan.$t("shipinyaoqiu3") }}</p>
</div>
<!-- <div class="demand">
<p class="one-line-hide">视频要求</p>
<p class="one-line-hide">1.上传视频时间要求为30s之内</p>
<p class="one-line-hide">2.支持文件大小100M</p>
<p class="one-line-hide">
3.文件扩展名fivmp4文件扩展名fivmp4
</p>
</div> -->
</a-form-item>
<a-form-item :label="lan.$t('kaishishijian')" @click="isEntitled = jinzhi" :rules="{ required: true, message: 'Please input Activity name', trigger: 'blur'}">
<!-- <a-input
size="small"
v-model:value="form.startTime"
placeholder="请设置您的开始时间"
/> -->
<a-date-picker
class="datesel"
show-time
format="YYYY-MM-DD HH:mm"
:value="form.dateline"
:disabled-date="disabledDate"
@click="isEntitled = jinzhi"
@change="startchange"
:placeholder="lan.$t('shezhikaishishijian')"
:getCalendarContainer="
(triggerNode) => triggerNode.parentNode
"
/>
<div style="color: red;font-size: 0.12rem;line-height: 1.3;">*{{ lan.$t('zhiboshijian') }}</div>
</a-form-item>
<a-form-item
:label="lan.$t('zhiboshichang')"
class="duration"
v-bind="validateInfos.livetime"
:rules="{ required: true, message: 'Please input Activity name', trigger: 'blur'}"
>
<a-input
size="small"
v-model:value="form.livetime"
@click="isEntitled = jinzhi"
:placeholder="lan.$t('shuruzhiboshijian')"
type="number"
/>
<span class="unit">{{ lan.$t("fenzhong") }}</span>
<div style="color: red;font-size: 0.12rem;line-height: 1.3;">*{{ lan.$t('shichangtishi') }}</div>
</a-form-item>
<a-form-item
:label="lan.$t('zhiborenshu')"
v-bind="validateInfos.livenumber"
:rules="{ required: true, message: 'Please input Activity name', trigger: 'blur'}"
>
<a-input
size="small"
v-model:value="form.livenumber"
@click="isEntitled = jinzhi"
:placeholder="lan.$t('shuruzhiborenshu')"
type="number"
/>
<div style="color: red;font-size: 0.12rem;line-height: 1.3;">*{{ lan.$t('renshutishi') }}</div>
</a-form-item>
<a-form-item :label="lan.$t('zhibojianjie')" class="brief">
<a-textarea
v-model:value="form.desc"
@click="isEntitled = jinzhi"
:autoSize="true"
class="brief-textarea"
:maxlength="200"
:placeholder="lan.$t('shuruzhibojianjie')"
/>
<span class="words-number">{{ form.desc.length }}/200</span>
</a-form-item>
<a-form-item :wrapper-col="{ span: 4, offset: 0 }">
<a-button @click="onSubmit">{{ lan.$t("fabuzhibob") }}</a-button>
<a-button style="margin-left:0.15rem;background-color: red;" @click="isquxiao = true" v-if="isbianji">{{ lan.$t("quxiaozhibo") }}</a-button>
</a-form-item>
</a-form>
<div class="modal-container">
<a-modal
centered
:footer="null"
:getContainer="modalNode"
dialogClass="modal-dialog"
v-model:visible="isEntitled"
@cancel="hideNoticeModal"
>
<template v-slot:closeIcon>
<img src="@/static/images/delete.png" class="close" />
</template>
<div class="notice-container report" v-if="lives.status == 1">
<div class="title">{{ lan.$t("wuzhibozige") }}</div>
<div class="title sub-title">
{{ lives.data.msg }}
</div>
<div class="confirm-btn" @click="fankui">
{{ lan.$t("yijianfankui") }}
</div>
</div>
<div class="notice-container" v-else>
<div class="title">{{ lan.$t("wuzhibozige") }}</div>
<div class="title sub-title" v-html="lives.msg">
</div>
<rank-list :list="lives.data"></rank-list>
</div>
</a-modal>
</div>
<a-modal
:title="lan.$t('quxiaozhibo')"
v-model:visible="isquxiao"
:confirm-loading="confirmLoading"
@ok="onquxiao()"
>
<p>{{ lan.$t("querenquxiao") }}</p>
</a-modal>
<nav-bottom></nav-bottom>
<div class="tishi" v-if="!jinzhi">
<img src="@/static/images/gantanhao.png" alt="">
<div>
{{ lan.$t("zhibotishi1") }}<br />
{{ lan.$t("zhibotishi") }}
</div>
</div>
</div>
</template>
<script lang="ts">
import {
computed,
defineComponent,
onBeforeUpdate,
onMounted,
reactive,
Ref,
ref,
toRaw,
} from "vue";
import { PlaySquareOutlined, PlusOutlined } from "@ant-design/icons-vue";
import { useForm } from "@ant-design-vue/use";
import NavBottom from "@/components/NavBottom.vue";
import RankList from "./RankList.vue";
import { previewCover, provenimg, provenvideo } from "@/utils/common";
import { FromSend, ImgInfo } from "@/types/index";
import { uploadflie } from "@/utils/vod";
import { cancellive, getlivest, liveadd, liveinfo, setlive } from "@/api";
import { useRoute } from "vue-router";
import dayjs from "dayjs";
import { message } from "ant-design-vue";
import router from "@/router";
import { useI18n } from "@/utils/i18n";
import store from '@/store';
export default defineComponent({
name: "ReleaseWebcast",
components: {
PlaySquareOutlined,
PlusOutlined,
NavBottom,
RankList,
},
setup() {
let issum = true;
const lan: any = useI18n();
// 表单数据
const form = ref({
title: "",
img: "",
fileid: "",
fileurl: "",
fileduration: 0,
dateline: "",
livetime: "",
livenumber: "",
desc: "",
});
const isquxiao = ref(false)
const uploadprogress: Ref<number> = ref(0);
const uploadpicprogress: Ref<number> = ref(0);
const videofile = ref<File>();
const videos = ref<Array<any>>([]);
const lives = ref<any>({});
const jinzhi = ref(false)
const isEntitled: Ref<boolean> = ref(false);
/**
* 验证直播时间
*/
async function validateaLivetime(
rule: unknown,
value: number
): Promise<string | void> {
console.log(value);
if (value < 30 || value > 120) {
return Promise.reject("*最短30min 最长120min");
} else {
return Promise.resolve();
}
}
/**
* 验证直播人数
*/
const validateLivenumber = async (
rule: unknown,
value: number
): Promise<string | void> => {
console.log(value);
if (value < 1 || value > 4) {
return Promise.reject("**最少1人最多4人");
} else {
return Promise.resolve();
}
};
// 验证规则
const rules = reactive({
livetime: [
{
validator: validateaLivetime,
trigger: "change",
},
],
livenumber: [
{
validator: validateLivenumber,
trigger: "change",
},
],
});
// 是否显示封面预览 封面的路径
const viewCover: Ref<boolean> = ref(false);
const previewImage: Ref<string> = ref("");
/**
* 封面改变触发事件
*/
function coverChange(info: ImgInfo): void {
// console.log(info);
// 获取预览图片
previewCover(info.file).then((url) => (previewImage.value = url));
viewCover.value = true;
// form.cover = fileList;
}
function fankui() {
router.push({ path: "/mine/aboutus", query: { selected: 3 } });
}
const { resetFields, validate, validateInfos } = useForm(form, rules);
/**
* 表单提交
*/
// const subdata = ref({
// title: "",
// img: "",
// fileid: "",
// fileurl: "",
// fileduration: "",
// dateline: "",
// livetime: "",
// livenumber: "",
// desc: "",
// });
/**
* todo 需要后台返回年份
*/
const id = useRoute().query.id;
const isbianji = ref(id);
if (id != null && typeof id == "string") {
liveinfo(parseInt(id)).then((res) => {
form.value = res;
});
}
const seting = computed(() => store.state.seting)
const onSubmit = (e: FromSend) => {
if(jinzhi.value){
isEntitled.value = true;
}
if(!issum){
message.error(lan.$t("shangchuanwancheng"))
return;
}
e.preventDefault();
validate()
.then(() => {
// else if (subdata.fileurl == "") {
// message.error(lan.$t('shipinjieshaoweikong'));
// return;
// }
console.log(seting.value)
console.log(toRaw(form), 111);
const subdata: any = toRaw(form.value);
if (subdata.title == "") {
message.error(lan.$t('zhibobiaotiweikong'));
return;
} else if (subdata.img == "") {
message.error(lan.$t('zhibofengmianweikong'));
return;
} else if (subdata.dateline == "") {
message.error(lan.$t('kaishishijianweikong'));
return;
} else if (subdata.livetime == "") {
message.error(lan.$t('zhiboshichangweikong'));
return;
} else if (subdata.livenumber == "") {
message.error(lan.$t('zhiborenshuweikong'));
return;
} else {
if(subdata.livetime < parseInt(seting.value.timeLowerLimit) || subdata.livetime > parseInt(seting.value.timeCeiling)){
// console.log(subdata.livetime, subdata.livetime < seting.value.timeLowerLimit || subdata.livetime > seting.value.timeCeiling)
message.error(lan.$t('shichangtishi'));
return ;
}
if(subdata.livenumber > parseInt(seting.value.numberCeiling) || subdata.livenumber < parseInt(seting.value.lowerLimit)){
message.error(lan.$t('renshutishi'));
return ;
}
if (!lives.value.status) {
// subdata.fileid=picinfo.
if (id != undefined && id) {
/**
* todo 提交会报错 编辑直播
*/
subdata.id = id;
setlive(subdata)
} else {
console.log(subdata);
console.log(lives.value);
liveadd(subdata);
}
} else {
message.error(lan.$t('wuzhibozigeale'));
}
}
})
.catch((err: unknown) => {
console.log("error", err);
});
};
/**
* 隐藏无资格提示
*/
function hideNoticeModal(): void {
isEntitled.value = false;
}
/**
* 开始时间设置
*/
function startchange(e: string): void {
// const month = new Date(e).getMonth()+1
// console.log(new Date(e).getFullYear()+"-"+month+'-'+new Date(e).getDate())
// console.log(e.toString())
const time = dayjs(new Date(e));
const timestr =
time.year() +
"-" +
(time.month() + 1) +
"-" +
time.date() +
" " +
time.hour() +
":" +
time.minute() +
":" +
time.second();
console.log(timestr);
form.value.dateline = timestr;
}
/**
* 上传文件
*/
const videoinfo = reactive({
fileId: "",
url: "",
});
const picinfo = reactive({
fileId: "",
url: "",
});
interface AntUpload {
action: string;
data: unknown;
file: File;
}
const ifallowupload = ref<boolean>(false);
function beforeUpload(info?: any) {
console.log(info);
if (info.type.split("/")[0] != "video") {
ifallowupload.value = false;
message.error(lan.$t('shipinjieshaoccuowu'));
return;
} else {
ifallowupload.value = true;
}
}
async function uploads(file: AntUpload) {
issum = false;
console.log(file);
videofile.value = file.file;
videos.value[0].addEventListener("durationchange", () => {
console.log(videos.value[0].duration);
form.value.fileduration = videos.value[0].duration;
});
uploadprogress.value = 1;
const res = await uploadflie(file.file, (info: any) => {
console.log(info);
// const jindu = info.percent.toFixed(2) * 100
let jindu: number = info.percent.toFixed(2) * 100;
jindu = parseInt(jindu + "");
uploadprogress.value = jindu > 0 ? jindu : 1;
});
console.log(res);
form.value.fileid = res.fileId;
form.value.fileurl = res.video.url;
issum = true;
}
const ifallowpic = ref<boolean>(false);
async function uploadspic(file: AntUpload) {
uploadpicprogress.value = 1;
const res = await uploadflie(file.file, (info: any) => {
console.log(info);
let jindu: number = info.percent.toFixed(2) * 100;
jindu = parseInt(jindu + "");
uploadpicprogress.value = jindu || 1;
});
console.log(res);
// picinfo.fileId=res.fileId
// picinfo.url=res.video.url
form.value.img = res.video.url;
}
getlivest().then((res) => {
if (res) {
isEntitled.value = true;
lives.value = res;
jinzhi.value = true;
}
});
function beforeUploadpic(info?: any) {
console.log(info);
if (info.type.split("/")[0] != "image") {
message.error(lan.$t('fengmiangeshi'));
ifallowpic.value = false;
return;
} else {
ifallowpic.value = true;
}
}
function disabledDate(current: any){
console.log(current + 0)
const now = dayjs().date(dayjs().date() - 1);
const enow = dayjs().date(dayjs().date() + parseInt(seting.value.releaseLiveDay) - 1);
return current && (current < now || current > enow);
}
function onquxiao(){
isquxiao.value = false;
if (id != null && typeof id == "string") {
cancellive(parseInt(id), 3).then((res)=>{
if(res){
router.push("/regime/live")
}
})
}
}
function video(file: any){
if(jinzhi.value){
isEntitled.value = true;
return false;
}
return provenvideo(file)
}
function imgs(file: any){
if(jinzhi.value){
isEntitled.value = true;
return false;
}
return provenimg(file)
}
const view = computed(()=>store.state.seting.views)
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
modalNode: () =>
document.getElementsByClassName("modal-container")[0],
validateInfos,
resetFields,
viewCover,
previewImage,
coverChange,
form,
onSubmit,
isEntitled,
hideNoticeModal,
uploads,
uploadprogress,
videoinfo,
uploadspic,
uploadpicprogress,
picinfo,
startchange,
videofile,
videos,
lives,
beforeUploadpic,
ifallowpic,
beforeUpload,
ifallowupload,
fankui,
lan,
disabledDate,
isbianji,
onquxiao,
isquxiao,
video,
imgs,
jinzhi,
view
};
},
});
</script>
<style lang="scss" scoped>
.webcast {
width: 100%;
min-width: 700px;
background-color: #ffffff;
padding: 46px;
border-radius: 17px;
position: relative;
.tishi{
position: absolute;
top: 60px;
right: 64px;
line-height: 0.17rem;
font-size: 15px;
font-weight: 500;
color: #808080;
display: flex;
align-items: center;
color:#07ad97;
> img{
width: 40px;
margin-right: 10px;
}
}
::v-deep(.ant-form) {
.title {
font-size: 12px;
font-weight: bold;
color: #111111;
margin-bottom: 28px;
}
.ant-row {
.ant-form-item-label {
width: 130px;
margin: 0 30px 0 17px;
> label {
font-size: 12px;
font-weight: 500;
color: #808080;
&::after {
content: "";
}
}
}
.upload {
width: 171px;
height: 96px;
}
.upload-image {
width: 171px;
height: 96px;
border: 1px solid #dcdfe0;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 17px;
}
.ant-input {
width: 171px;
padding: 6px 11px;
border-radius: 3px;
border: 1px solid #dcdfe0;
font-size: 11px;
color: #3f3f3f;
&::-webkit-input-placeholder {
font-size: 12px;
color: #808080;
}
}
.ant-select {
font-size: 12px;
}
.ant-select-dropdown {
font-size: 12px;
}
.ant-form-explain {
font-size: 10px;
font-weight: 500;
color: #d22d2e;
}
.ant-upload-list {
display: none;
}
.ant-btn {
padding: 0;
width: 63px;
height: 23px;
background: #08ae98;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
color: #ffffff;
// &:hover{
// background: #08ae98;
// }
}
}
.item-cover {
.preview-image {
width: 171px;
height: 96px;
}
}
.demand {
line-height: 17px;
font-size: 10px;
font-weight: 500;
color: #808080;
// width: 134px;
> p {
margin: 0;
}
}
.video-introduction {
.ant-form-item-control-wrapper {
.ant-form-item-children {
display: flex;
align-items: center;
}
}
}
.duration {
.unit {
margin-left: 18px;
font-size: 12px;
font-weight: 500;
color: #808080;
}
}
.brief {
position: relative;
.ant-input {
width: 359px;
}
.brief-textarea {
min-height: 85px;
padding-bottom: 30px;
}
.words-number {
position: absolute;
right: 11px;
bottom: -11px;
font-size: 11px;
font-weight: 500;
color: #7f7f7f;
user-select: none;
}
}
}
.modal-container {
::v-deep(.modal-dialog) {
.close {
width: 14px;
height: 14px;
}
.ant-modal-content {
box-sizing: border-box;
padding: 25px 30px;
width: 569px;
background: #ffffff;
box-shadow: 0px 4px 6px 0px rgba(102, 102, 102, 0.07);
border-radius: 28px;
.notice-container {
.title {
font-size: 11px;
font-weight: bold;
color: #111111;
margin-bottom: 16px;
}
.sub-title {
.red {
color: #d12c2d;
}
.bule {
color: #0dbba3;
}
}
.confirm-btn {
display: inline-block;
background: #07ad97;
border-radius: 2px;
font-size: 9px;
font-weight: 500;
color: #ffffff;
text-align: center;
cursor: pointer;
user-select: none;
height: 22px;
line-height: 22px;
padding: 0 17px;
}
}
.report {
.sub-title {
margin-bottom: 50px;
}
}
}
}
}
.datesel{
&::v-deep(.ant-calendar-time-picker-select){
width: 50% !important;
&:last-child{
display: none;
}
}
}
}
</style>