Files
fe-manage/src/components/drawers/AddLive.vue
2023-02-24 14:10:38 +08:00

702 lines
20 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 @click="openDrawer">
<slot></slot>
</div>
<a-drawer :visible="visible" class="drawerStyle addliveDrawer" width="1000" title="添加直播" placement="right">
<div class="drawerMain">
<div class="header">
<div class="headerTitle">
{{ taskIndex >= 0 ? "编辑" : "添加" }}直播
</div>
<img style="width: 29px; height: 29px; cursor: pointer" src="../../assets/images/basicinfo/close.png"
@click="closeDrawer" />
</div>
<div class="contentMain">
<div class="main_left">
<div class="main_item">
<div class="signbox">
<div class="sign">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">直播名称</span>
</div>
<div class="btnbox">
<a-input v-model:value="formData.liveName" style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入直播名称" :maxlength="20" />
</div>
</div>
<div class="main_item" style="margin-top: -10px">
<div class="signbox">
<div class="asterisk_icon">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">直播链接</span>
</div>
<div class="btnbox">
<a-input v-model:value="formData.liveLink" style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入直播链接" :maxlength="100" />
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">直播时间</span>
</div>
<div class="btnbox">
<a-range-picker :show-time="{ format: 'HH:mm' }" :disabled-date="disabledDate"
style="width: 400px; height: 40px; border-radius: 8px" v-model:value="dateTime" format="YYYY-MM-DD HH:mm"
valueFormat="YYYY-MM-DD HH:mm" @change="timeChange" :placeholder="[' 开始时间', ' 结束时间']" />
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">直播时长</span>
</div>
<div class="btnbox">
<a-input-number :min="0" :max="300" :precision="0" style="width: 400px; height: 40px; border-radius: 8px"
v-model:value="formData.liveDuration"></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟</span>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">授课老师</span>
</div>
<div class="select" style="width: 400px">
<ProjectManager v-model:value="formData.liveTeacherId" v-model:name="formData.liveTeacherName">
</ProjectManager>
</div>
</div>
<div class="mbl_items2">
<div class="item_nam">
<div class="asterisk_icon">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 2px">直播封面</span>
</div>
<div class="item_inp">
<a-upload name="avatar" list-type="picture-card" class="avatar-uploader" :show-upload-list="false"
:before-upload="beforeUpload">
<img class="i_upload_img" v-if="imageUrl" :src="imageUrl" alt="avatar" />
<div class="i_upload" v-else>
<div class="addimg">
<div class="heng"></div>
<div class="shu"></div>
</div>
</div>
</a-upload>
<div class="i_bottom">
<div class="tip">
<span style="color: #999999; margin-left: 8px">支持图片格式为jpg/jpeg/png 图片最大为2MB</span>
</div>
</div>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<div class="asterisk_icon">
<img src="@/assets/images/coursewareManage/asterisk.png" alt="" />
</div>
<span style="margin-right: 3px">直播公告</span>
</div>
<div class="textarea">
<a-textarea v-model:value="formData.liveNotice" placeholder="请输入直播公告" allow-clear show-count
:maxlength="200" :rows="6" />
</div>
</div>
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">回放设置</span>
</div>
<div class="btnbox">
<a-switch v-model:checked="formData.livePlayback" @change="getchange(formData.livePlayback)" />
</div>
</div>
<div v-if="formData.livePlayback">
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">回放链接</span>
</div>
<div class="btnbox">
<a-input v-model:value="formData.livePlaybackLink" style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入回放链接" :maxlength="100" />
</div>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">直播说明</span>
</div>
<div class="textarea">
<a-textarea v-model:value="formData.liveExplain" placeholder="请输入直播说明" allow-clear show-count
:maxlength="200" :rows="6" />
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">考勤设置</span>
</div>
<div class="kqszbox">
<div class="qdqtbox">
<div class="qdbtn">
<div class="btntext">签到</div>
</div>
</div>
<div class="setbox">
<div class="timerbox">
<span>直播开始前</span>
<a-input-number :min="0" :max="30" :precision="0" style="
width: 88px;
height: 32px;
border-radius: 8px;
overflow: hidden;
" v-model:value="formData.beforeSignIn"></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟允许签到</span>
</div>
<div class="timerbox">
<span>直播开始后</span>
<a-input-number :min="0" :max="30" :precision="0" style="
width: 88px;
height: 32px;
border-radius: 8px;
overflow: hidden;
" v-model:value="formData.afterSignIn"></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟允许签到</span>
</div>
</div>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">评估</span>
</div>
<div class="btnbox2">
<a-checkbox v-model:checked="formData.isEvaluate" @change="getchanges(formData.isEvaluate)">需要评估
</a-checkbox>
</div>
</div>
<div v-if="formData.isEvaluate" class="main_item">
<div class="signbox"></div>
<div class="btnbox">
<AddInvistRoot v-model:id="formData.assessmentId" v-model:name="formData.assessmentName">
<button class="xkbtn">选择评估</button>
</AddInvistRoot>
<div v-if="formData.assessmentId">
<a-tag closable @close="removePG" color="processing">
<span style="font-size: 14px; line-height: 33px">{{
formData.assessmentName
}}</span>
</a-tag>
</div>
</div>
</div>
<div class="main_item" style="height: 30px">
<div class="signbox">
<span style="margin-right: 3px"></span>
</div>
<div class="btnbox"></div>
</div>
</div>
</div>
<div class="main_btns">
<button class="btn1" @click="closeDrawer">取消</button>
<button class="btn2" @click="confirm">确定</button>
</div>
</div>
</a-drawer>
</template>
<script setup>
import { defineEmits, defineProps, ref } from "vue";
import dayjs from "dayjs";
import ProjectManager from "@/components/project/ProjectManagerNew";
import AddInvistRoot from "@/components/drawers/AddInvistRoot.vue";
import { Form, message } from "ant-design-vue";
import { fileUp } from "../../api/indexEval";
const removePG = () => {
formData.value.assessmentId = "";
formData.value.assessmentName = "";
};
const getchange = (mess) => {
console.log(mess); //输出true或者false
};
const getchanges = (mess) => {
console.log(mess); //输出true或者false
};
const props = defineProps({
type: Number,
taskList: [],
});
const visible = ref(false);
const formData = ref({
liveName: "",
liveLink: "",
liveStartTime: "",
liveEndTime: "",
liveNotice: "",
liveDuration: "",
liveTeacherId: "",
liveTeacherName: "",
liveCover: "",
beforeSignIn: "",
afterSignIn: "",
isEvaluate: false,
assessmentId: "",
assessmentName: "",
livePlayback: "",
});
const emit = defineEmits({});
const taskIndex = ref(-1);
const dateTime = ref([]);
const rulesRef = ref({
liveName: [
{
required: true,
message: "请输入直播名称",
},
],
liveLink: [
{
type: "url",
required: true,
message: "请输入合法的直播链接",
},
],
liveStartTime: [
{
required: true,
message: "请选择开始时间",
},
],
liveEndTime: [
{
required: true,
message: "请选择结束时间",
},
],
liveNotice: [
{
required: true,
message: "请输入直播公告",
},
],
liveDuration: [
{
required: true,
message: "请输入直播时长",
},
],
liveTeacherId: [
{
required: true,
message: "请选择直播教师",
},
],
liveTeacherName: [
{
required: true,
message: "请选择直播教师",
},
],
liveCover: [
{
required: true,
message: "请上传直播封面",
},
],
});
const { resetFields, validate } = Form.useForm(formData, rulesRef);
const closeDrawer = () => {
formData.value.liveCover = "";
imageUrl.value = "";
visible.value = false;
taskIndex.value = -1;
dateTime.value = [];
resetFields();
};
/**
const range = (start, end) => {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
};
*/
function timeChange(time, timeStr) {
formData.value.liveStartTime = timeStr[0];
formData.value.liveEndTime = timeStr[1];
}
const disabledDate = (current) => {
return current && current < dayjs().startOf("day");
};
/**
const disabledRangeTime = () => ({
// disabledHours: () => range(0, 24).splice(4, 20),
disabledMinutes: () => range(30, 60),
disabledSeconds: () => [55, 56],
});
*/
async function confirm() {
// debugger;
console.log("确定按钮:");
await validate().catch(({ errorFields }) => {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过");
});
if (taskIndex.value === -1) {
let list = props.taskList
list.push(
{
name: formData.value.liveName,
type: props.type,
info: { ...formData.value },
duration: dayjs(formData.value.liveEndTime).diff(formData.value.liveStartTime, 'minutes')
})
} else {
const data = props.taskList[taskIndex.value];
data.name = formData.value.liveName;
data.info = formData.value;
data.duration = dayjs(formData.value.liveEndTime).diff(formData.value.liveStartTime, 'minutes')
}
emit("update:taskList", [...props.taskList]);
closeDrawer();
}
function openDrawer(i, row) {
console.log(i, row)
row && (formData.value = { ...row.info });
row && (dateTime.value = [row.info.liveStartTime, row.info.liveEndTime]);
row && (imageUrl.value = row.info.liveCover);
i >= 0 && (taskIndex.value = i);
visible.value = true;
}
defineExpose({ openDrawer });
const imageUrl = ref("");
const beforeUpload = (file) => {
const isJpgOrPng =
file.type === "image/jpg" ||
file.type === "image/jpeg" ||
file.type === "image/png" ||
file.type === "image/svg" ||
file.type === "image/bmp" ||
file.type === "image/gif";
if (!isJpgOrPng) {
message.error("仅支持jpg、gif、png、jpeg、svg、bmp格式!");
return false;
}
let isLt1M = file.size < 2000000;
console.log(file.size, isLt1M)
if (!isLt1M) {
message.error("图片大小超过2MB!");
return false;
}
const formDatas = new FormData();
formDatas.append("file", file);
fileUp(formDatas).then((res) => {
if (res.data.code === 200) {
console.log(res.data.data, 45);
imageUrl.value = process.env.VUE_APP_FILE_PATH + res.data.data;
formData.value.liveCover = process.env.VUE_APP_FILE_PATH + res.data.data;
// state.hasImgName = file.name;
// emit("src", { id: '', src: res.data.data });
}
});
return false;
};
</script>
<style lang="scss">
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa !important;
}
.addliveDrawer {
.drawerMain {
.header {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
margin-left: 24px;
}
}
.contentMain {
display: flex;
justify-content: space-between;
.main_left {
padding-right: 30px;
flex: 1;
border-right: 1px solid #e8e8e8;
margin-top: 32px;
.main_item {
display: flex;
align-items: center;
margin-top: 32px;
margin-bottom: 32px;
.signbox {
width: 120px;
display: flex;
justify-content: end;
align-items: center;
.sign {
margin-right: 5px;
}
}
.btnbox {
display: flex;
flex: 1;
align-items: center;
.xkbtn {
cursor: pointer;
width: 130px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-right: 8px;
color: #fff;
}
}
}
.main_item2 {
display: flex;
align-items: flex-start;
margin-bottom: 32px;
.textarea {
width: 400px;
.ant-input {
width: 100%;
}
.ant-input-textarea-show-count {
position: relative;
}
.ant-input-textarea-show-count::after {
position: absolute;
right: 10px;
bottom: 0px;
}
.ant-input {
border-radius: 8px;
}
}
.signbox {
width: 120px;
display: flex;
justify-content: end;
align-items: center;
.sign {
margin-right: 5px;
}
}
.kqszbox {
.qdqtbox {
margin-left: 5px;
cursor: pointer;
}
.qdbtn,
.qtbtn {
width: 75px;
height: 24px;
background: rgba(56, 139, 225, 0.16);
border-radius: 2px;
border: 1px solid #387df7;
display: flex;
align-items: center;
justify-content: center;
.btntext {
color: #387df7;
}
}
.setbox {
flex-wrap: wrap;
margin-top: 10px;
margin-bottom: 6px;
.timerbox {
margin-top: 22px;
margin-right: 32px;
display: flex;
align-items: center;
flex-wrap: nowrap;
}
}
}
.btnbox2 {
display: flex;
flex-direction: column;
justify-content: flex-start;
.xkbtn {
cursor: pointer;
width: 130px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-right: 16px 8px 32px 0;
color: #fff;
margin-top: 16px;
margin-bottom: 60px;
}
}
}
.mbl_items2 {
display: flex;
align-items: start;
margin-top: 10px;
margin-bottom: 10px;
.i_bottom {
margin-bottom: 30px;
}
.item_nam {
width: 120px;
display: flex;
align-items: center;
justify-content: flex-end;
white-space: nowrap;
.asterisk_icon {
width: 10px;
height: 10px;
margin-right: 5px;
margin-top: -15px;
}
}
.item_inp {
flex: 1;
.i_upload_img {
width: 100px;
height: 100px;
border-radius: 8px;
}
.i_upload {
width: 100px;
height: 100px;
border: 1px solid #4ea6ff;
border-radius: 8px;
text-align: center;
align-items: center;
cursor: pointer;
.addimg {
position: relative;
.heng {
position: absolute;
top: 50px;
left: 25px;
width: 50px;
border: 1px solid #4ea6ff;
}
.shu {
position: absolute;
top: 25px;
left: 50px;
height: 50px;
border: 1px solid #4ea6ff;
}
}
}
.ant-upload.ant-upload-select-picture-card {
border: 0px !important;
}
}
}
}
}
.main_btns {
height: 72px;
width: 100%;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.16);
.btn1 {
width: 100px;
height: 40px;
border: 1px solid #4ea6ff;
border-radius: 8px;
color: #4ea6ff;
background-color: #fff;
cursor: pointer;
}
.btn2 {
cursor: pointer;
width: 100px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-left: 15px;
color: #fff;
}
}
}
}
</style>