beelink/src/views/mine/ReleaseWebcast.vue
2020-10-14 08:57:57 +08:00

560 lines
14 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">直播信息</div>
<a-form-item label="直播标题">
<a-input
size="small"
v-model:value="form.title"
placeholder="请输入您的直播标题"
/>
</a-form-item>
<a-form-item label="直播封面" class="item-cover">
<a-upload list-type="picture" :customRequest="uploadspic">
<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>
</a-form-item>
<a-form-item label="视频介绍" class="video-introduction">
<a-upload list-type="picture" :customRequest="uploads">
<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 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="开始时间">
<!-- <a-input
size="small"
v-model:value="form.startTime"
placeholder="请设置您的开始时间"
/> -->
<a-date-picker @change="startchange" placeholder="请设置您的开始时间" />
</a-form-item>
<a-form-item
label="直播时长"
class="duration"
v-bind="validateInfos.livetime"
>
<a-input
size="small"
v-model:value="form.livetime"
placeholder="请输入直播时间"
/>
<span class="unit">分钟</span>
</a-form-item>
<a-form-item label="直播人数" v-bind="validateInfos.livenumber">
<a-input
size="small"
v-model:value="form.livenumber"
placeholder="请输入直播人数"
/>
</a-form-item>
<a-form-item label="直播简介" class="brief">
<a-textarea
v-model:value="form.desc"
:autoSize="true"
class="brief-textarea"
:maxlength="200"
placeholder="请输入您的直播简介"
/>
<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">发布直播</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="0">
<div class="title">您尚未获得直播资格</div>
<div class="title sub-title">
您被 学生XXX<span class="red">举报发生违规行为</span
>,如有疑问点击反馈
</div>
<div class="confirm-btn">意见反馈</div>
</div>
<div class="notice-container" v-else>
<div class="title">您尚未获得直播资格</div>
<div class="title sub-title">
上一周/月您在平台视频点击量为
<span class="red">第24名</span>要在前
<span class="bule">20</span> 才能获得直播资格
</div>
<rank-list></rank-list>
</div>
</a-modal>
</div>
<nav-bottom></nav-bottom>
</div>
</template>
<script lang="ts">
import {
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 } from "@/utils/common";
import { FromSend, ImgInfo } from "@/types/index";
import { uploadflie } from "@/utils/vod";
import { liveadd } from "@/api";
export default defineComponent({
name: "ReleaseWebcast",
components: {
PlaySquareOutlined,
PlusOutlined,
NavBottom,
RankList,
},
setup() {
// 表单数据
const form = reactive({
title: "",
img: "",
fileid: "",
fileurl: "",
fileduration: 0,
dateline: "",
livetime: "",
livenumber: "",
desc: "",
});
const uploadprogress: Ref<number> = ref(0);
const uploadpicprogress: Ref<number> = ref(0);
const videofile = ref<File>();
const videos = ref<Array<any>>([]);
/**
* 验证直播时间
*/
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;
}
const { resetFields, validate, validateInfos } = useForm(form, rules);
/**
* 表单提交
*/
const subdata = reactive({
title: "",
img: "",
fileid: "",
fileurl: "",
fileduration: "",
dateline: "",
livetime: "",
livenumber: "",
desc: "",
});
const onSubmit = (e: FromSend) => {
e.preventDefault();
validate()
.then(() => {
// console.log(toRaw(form),111);
let subdata = toRaw(form);
// subdata.fileid=picinfo.
console.log(subdata);
liveadd(subdata);
})
.catch((err: unknown) => {
console.log("error", err);
});
};
const isEntitled: Ref<boolean> = ref(true);
/**
* 隐藏无资格提示
*/
function hideNoticeModal(): void {
isEntitled.value = false;
}
/**
* 开始时间设置
*/
function startchange(e: string): void {
let month=new Date(e).getMonth()+1
console.log(new Date(e).getFullYear()+"-"+month+'-'+new Date(e).getDate())
form.dateline =
new Date(e).getFullYear() +
"-" +
month +
"-" +
new Date(e).getDate();
}
/**
* 上传文件
*/
const videoinfo = reactive({
fileId: "",
url: "",
});
const picinfo = reactive({
fileId: "",
url: "",
});
interface AntUpload {
action: string;
data: unknown;
file: File;
}
async function uploads(file: AntUpload) {
console.log(file);
videofile.value = file.file;
videos.value[0].addEventListener("durationchange", () => {
console.log(videos.value[0].duration);
form.fileduration = videos.value[0].duration;
});
let res = await uploadflie(file.file, (info: any) => {
console.log(info);
uploadprogress.value = info.percent.toFixed(2) * 100;
});
console.log(res);
form.fileid = res.fileId;
form.fileurl = res.video.url;
}
async function uploadspic(file: AntUpload) {
let res = await uploadflie(file.file, (info: any) => {
console.log(info);
uploadpicprogress.value = info.percent.toFixed(2) * 100;
});
console.log(res);
// picinfo.fileId=res.fileId
// picinfo.url=res.video.url
form.img = res.video.url;
}
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,
};
},
});
</script>
<style lang="scss" scoped>
.webcast {
width: 100%;
min-width: 700px;
background-color: #ffffff;
padding: 46px;
border-radius: 17px;
position: relative;
::v-deep(.ant-form) {
.title {
font-size: 12px;
font-weight: bold;
color: #111111;
margin-bottom: 28px;
}
.ant-row {
.ant-form-item-label {
width: 60px;
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;
}
}
.item-cover {
.preview-image {
width: 171px;
height: 96px;
}
}
.video-introduction {
.ant-form-item-control-wrapper {
.ant-form-item-children {
display: flex;
align-items: center;
.demand {
line-height: 17px;
font-size: 10px;
font-weight: 500;
color: #808080;
width: 134px;
> p {
margin: 0;
}
}
}
}
}
.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;
}
}
}
}
}
}
</style>