Files
fe-manage/src/components/drawers/AddOpenCourse.vue
2023-03-18 00:32:32 +08:00

1202 lines
31 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>
<a-drawer
:visible="openCourseVisible"
class="drawerStyle addonlineDrawer"
:width="1000"
title="开课"
placement="right">
<div class="drawerMain">
<div class="header">
<div class="headerTitle">开课</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../assets/images/basicinfo/close.png"
@click="closeDrawer"
/>
</div>
<div class="contentMain">
<div class="main_items">
<div class="mi_ipts">
<div class="mii_ipt">
<div class="ipt_name"></div>
<div class="fi_input">
<a-input
v-model:value="params.name"
style="width: 220px; height: 40px; border-radius: 8px"
placeholder="请输入创建人"
maxlength="20"
/>
</div>
</div>
<div class="mii_ipt">
<div class="ipt_name"></div>
<div class="fi_input">
<a-input
v-model:value="params.teacher"
style="width: 220px; height: 40px; border-radius: 8px"
placeholder="请输入教师名称"
maxlength="20"
/>
</div>
</div>
<div class="mii_ipt">
<div class="ipt_name"></div>
<div class="fi_input">
<RangePicker v-model:beginTime="params.createBeginTime" v-model:endTime="params.createEndTime"/>
</div>
</div>
</div>
<div class="mi_btns" style="margin-left: 0">
<div class="btn btn2" @click="search">
<div class="search"></div>
<div class="btnText">搜索</div>
</div>
<div class="btn btn2" @click="reset">
<div class="search"></div>
<div class="btnText">重置</div>
</div>
</div>
</div>
<div class="main_item">
<button class="xkbtn" @click="createNewCourse">新建开课</button>
</div>
<div class="main_table">
<div class="drawerbox">
<BaseTable ref="tableRef" :url="COURSE_PLAN_PAGE" :params="params" :columns="columns"/>
</div>
</div>
</div>
<div class="main_btns">
<button @click="closeDrawer" class="btn2">取消</button>
<button @click="confirm" class="btn2">确定</button>
</div>
</div>
<!--新建开课页面 -->
<a-modal
v-model:visible="offCourseNewVisiable"
style="margin-top: 400px;"
@cancel="handleCancelStu">
<div
class="createschooltime"
>
<div class="cst_header"></div>
<div class="cst_main">
<div class="cstm_header">
<div class="add_icon"></div>
<span>{{ formData.id ? "编辑开课" : "新建开课" }}</span>
<div class="close_exit" @click="handleCancelStu"></div>
</div>
<div class="cstm_title">
<span>面授名称{{ courseName }}</span>
</div>
<div class="cstm_items">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">开课名称</span>
</div>
<div class="b_input">
<NameInput
maxlength="30"
v-model:value="formData.name"
v-model:validated="validated"
:id="formData.id"
show-count
:type="5"
style="width: 440px; height: 40px; border-radius: 8px"
placeholder="请输入开课名称"
></NameInput>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<div class="sign">
</div>
<span style="margin-right: 3px">地点</span>
</div>
<div class="b_input">
<a-input
v-model:value="formData.address"
maxlength="50"
style="width: 440px; height: 40px; border-radius: 8px"
placeholder="请输入详细地点"
/>
<div class="inp_num" style="right: 164px">
<span style="color: #c7cbd2">{{ formData.address.length || 0 }}/50</span>
</div>
</div>
</div>
<div class="cstm_items">
<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 fitems">
<a-range-picker
style="width: 440px; height: 40px; border-radius: 8px"
:show-time="{ format: 'HH:mm' }"
:disabled-date="disabledDate"
format="YYYY-MM-DD HH:mm"
v-model:value="dateTime"
@change="timeChange"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
</div>
<div class="cstm_items">
<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: 440px">
<ProjectManager
v-model:value="formData.teacherId"
v-model:name="formData.teacher"
></ProjectManager>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<span style="margin-right: 3px">考勤设置</span>
</div>
<div style="display: flex; align-items: center">
<div style="margin-right: 10px">签到</div>
<div
style="display: flex; align-items: center; margin-right: 20px"
>
<span>开始前</span>
<a-input-number
:min="0"
:max="999999"
:precision="0"
style="
width: 100px;
height: 32px;
border-radius: 8px;
overflow: hidden;
"
v-model:value="formData.beforeStart"
></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟</span>
</div>
<div style="display: flex; align-items: center">
<span>开始后</span>
<a-input-number
:min="0"
:max="999999"
:precision="0"
style="
width: 100px;
height: 32px;
border-radius: 8px;
overflow: hidden;
"
v-model:value="formData.afterStart"
></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟</span>
</div>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<span style="margin-right: 3px">报名设置</span>
</div>
<div class="b_input">
<CheckBox v-model="formData.applyFlag"
:check-value="1"
:un-check-value="0">
<span style="color: #6d7584">是否允许公开报名</span>
</CheckBox>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<span style="margin-right: 3px">现场参与</span>
</div>
<div class="b_input">
<CheckBox v-model="formData.projectSignFlag"
:check-value="1"
:un-check-value="0">
<span style="color: #6d7584">允许项目内人员临时到场参加(不在本场次培训的人员可以临时签到参加)</span>
</CheckBox>
<CheckBox v-model="formData.signFlag"
:check-value="1"
:un-check-value="0">
<span style="color: #6d7584">允许项目外人员临时到场参加</span>
</CheckBox>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<span style="margin-right: 3px">评估设置</span>
</div>
<div class="b_input">
<CheckBox v-model="formData.evalFlag" :checkValue="1" :un-checkValue="0">
<span style="color: #6d7584">是否需要评估</span>
</CheckBox>
</div>
</div>
<div v-if="formData.evalFlag" class="cstm_items main_item">
<div class="signbox"></div>
<div class="btnbox">
<AssessmentList
v-model:assessmentName="formData.assessmentName"
v-model:assessmentId="formData.assessmentId"
>
<button
class="xkbtn"
style="margin-bottom: 0; margin-top: 0"
>
选择评估
</button>
</AssessmentList>
<div v-if="formData.assessmentId > 0">
<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="cstm_items main_item">
<div class="signbox"></div>
<div class="btnbox">
<add-homework v-model:info="formData.workInfo">
<button class="xkbtn" style="margin-bottom: 0; margin-top: 0">
配置作业
</button>
</add-homework>
<div v-if="formData?.workInfo?.workName">
<a-tag closable @close="logW" color="processing">
<span style="font-size: 14px; line-height: 33px">
{{ formData?.workInfo?.workName }}
</span>
</a-tag>
</div>
</div>
</div>
<div class="cstm_items main_item" style="margin-bottom: 0">
<div class="signbox"></div>
<div class="btnbox">
<add-test v-model:info="formData.examInfo">
<button class="xkbtn" style="margin-bottom: 0; margin-top: 0">
配置考试
</button>
</add-test>
<div v-if="formData?.examInfo?.examinationName">
<a-tag closable @close="logT" color="processing">
<span style="font-size: 14px; line-height: 33px">
{{ formData.examInfo?.examinationName }}
</span>
</a-tag>
</div>
</div>
</div>
<div class="cstm_items items_fj">
<div class="signbox">
<span style="margin-right: 3px"></span>
</div>
<div class="b_input">
<FJUpload v-model:value="formData.attachName"/>
</div>
</div>
<div class="items_btn">
<div class="cstm_btn btn6" @click="handleCancelStu">
<div class="btnText">取消</div>
</div>
<a-button
class="cstm_btn btn6"
@click="coursePlanConfirm"
:loading="validated === 1"
>
确定
</a-button>
</div>
</div>
</div>
</a-modal>
</a-drawer>
</template>
<script setup>
import {defineProps, ref} from "vue";
import {Form, message} from "ant-design-vue";
import FJUpload from "@/components/common/FJUpload";
import CheckBox from "@/components/common/CheckBox";
import RangePicker from "@/components/common/RangePicker";
import ProjectManager from "@/components/project/ProjectManagerNew";
import AddHomework from "@/components/drawers/CommonHomework.vue";
import AddTest from "@/components/drawers/CommonTest.vue";
import NameInput from "@/components/project/NameInput";
import AssessmentList from "@/components/drawers/AssessmentList.vue";
import {COURSE_PLAN_EDIT, COURSE_PLAN_PAGE, DEL_PLAN, EXAM_DETAIL, WORK_DETAIL} from "@/api/apis";
import dayjs from "dayjs";
import BaseTable from "@/components/common/BaseTable";
import {request} from "@/api/request";
import dialog from "@/utils/dialog";
const props = defineProps({
type: Number,
});
const openCourseVisible = ref(false);
const offCourseNewVisiable = ref(false);
const tableRef = ref();
const columns = ref([
{
title: "名称",
dataIndex: "name",
key: "name",
width: "20%",
ellipsis: true,
},
{
title: "场地",
dataIndex: "address",
key: "address",
width: "20%",
align: "center",
},
{
title: "开始时间",
dataIndex: "beginTime",
key: "beginTime",
width: "20%",
align: "center",
},
{
title: "教师",
dataIndex: "teacher",
key: "teacher",
width: "20%",
align: "center",
},
{
title: "学员数",
dataIndex: "studentCnt",
key: "studentCnt",
width: "20%",
align: "center",
},
{
title: "创建时间",
dataIndex: "createTime",
key: "createTime",
width: "20%",
align: "center",
},
{
title: "操作",
dataIndex: "createTime",
key: "createTime",
width: "20%",
align: "center",
customRender: ({ record }) => {
return (
<div class="opa">
<a style="margin-right:10px;" onClick={() => planEdit(record)}>编辑</a>
<a onClick={() => del(record.id)}>删除</a>
</div>
);
},
}
]);
const params = ref({
type: props.type,
offcourseId: "",
draftTaskId: "",
taskId: ""
});
const validated = ref(0);
const dateTime = ref([]);
const courseName = ref();
const formData = ref({
name: "",
address: "",
teacherId: "",
teacher: "",
beforeValue: "",
afterStartValue: "",
applyFlag: 0,
projectSignFlag: 0,
signFlag: 0,
evalFlag: 0,
assessmentName: "",
assessmentId: "",
workInfo: {},
examInfo: {},
attachName: "",
type: props.type,
offcourseId: "",
draftTaskId: "",
taskId: "",
});
const formDataRule = {
name: [
{
required: true,
message: "请输入开课名称",
},
],
beginTime: [
{
required: true,
message: "请选择开始时间",
},
],
endTime: [
{
required: true,
message: "请选择结束时间",
},
],
teacher: [
{
required: true,
message: "请选择教师",
},
],
teacherId: [
{
required: true,
message: "请选择教师",
},
],
};
const { resetFields, validate } = Form.useForm(formData, formDataRule);
function timeChange(time, timeStr) {
formData.value.beginTime = timeStr[0];
formData.value.endTime = timeStr[1];
}
function search() {
tableRef.value.fetch();
}
function reset() {
tableRef.value.reset();
}
const closeDrawer = () => {
openCourseVisible.value = false;
tableRef.value.reset();
};
function confirm() {
closeDrawer();
}
const createNewCourse = () => {
resetFields({
id: null,
type: props.type,
offcourseId: params.value.offcourseId,
draftTaskId: params.value.draftTaskId,
});
dateTime.value = [];
validated.value = 0;
offCourseNewVisiable.value = true;
};
const handleCancelStu = () => offCourseNewVisiable.value = false;
const del = (id) => {
dialog({
content: "确定删除此开课吗?",
ok: async () => {
message.success("删除成功");
tableRef.value.toLoading();
await request(DEL_PLAN(id));
tableRef.value.fetch();
},
});
};
async function coursePlanConfirm() {
await validate().catch(({ errorFields }) => {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过");
});
offCourseNewVisiable.value = false;
tableRef.value.toLoading();
await request(COURSE_PLAN_EDIT, { ...formData.value });
handleCancelStu();
tableRef.value.fetch();
}
function planEdit(record) {
formData.value = { ...record };
formData.value.homeWorkId && request(WORK_DETAIL(formData.value.homeWorkId), {}).then(res => formData.value.workInfo = res.data);
formData.value.testId && request(EXAM_DETAIL(formData.value.testId), {}).then(res => formData.value.examInfo = res.data);
offCourseNewVisiable.value = true;
}
function openDrawer(row) {
openCourseVisible.value = true;
params.value.offcourseId = row.courseId;
params.value.draftTaskId = row.id;
formData.value.offcourseId = row.courseId;
formData.value.draftTaskId = row.id;
courseName.value = row.name;
tableRef.value && tableRef.value.fetch();
}
const disabledDate = (current) => current && current < dayjs().startOf("day");
defineExpose({ openDrawer });
</script>
<style lang="scss">
.ant-drawer-content-wrapper {
width: 1500px !important;
min-width: 1500px !important;
}
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa !important;
}
.sameModal {
.ant-modal {
width: 424px !important;
height: 258px !important;
.ant-modal-content {
width: 424px !important;
height: 258px !important;
.ant-modal-body {
width: 424px !important;
height: 258px !important;
padding: 0 !important;
.delete {
z-index: 999;
width: 424px;
height: 258px;
background: #ffffff;
box-shadow: 0 1px 35px 0 rgba(118, 136, 166, 0.21);
border-radius: 4px;
// position: absolute;
// left: 50%;
// top: 10%;
// transform: translate(-50%, -50%);
.del_header {
position: absolute;
width: calc(100%);
height: 68px;
background: linear-gradient(
rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%
);
}
.del_main {
width: 100%;
position: relative;
.header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.icon {
width: 16px;
height: 16px;
margin-right: 10px;
background-image: url(@/assets/images/taskpage/gan.png);
background-size: 100% 100%;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.body {
width: 100%;
margin: 34px auto 56px auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
// background-color: red;
position: relative;
.back {
position: absolute;
top: 30px;
font-size: 12px;
font-weight: 400;
color: #666666;
}
}
.del_btnbox {
display: flex;
margin: 30px auto;
justify-content: center;
.del_btn {
width: 100px;
height: 40px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
cursor: pointer;
.btnText {
font-size: 14px;
font-weight: 400;
line-height: 40px;
}
}
.btn1 {
border: 1px solid rgba(64, 158, 255, 1);
color: #4ea6ff;
margin-right: 14px;
}
.btn2 {
background-color: #4ea6ff;
color: #ffffff;
}
}
}
}
}
}
}
}
.addrefDrawer {
.drawerMain {
// .main_notice {
// display: flex;
// justify-content: space-between;
// align-items: center;
// margin-bottom: 32px;
// height: 40px;
// background-color: #e9f6fe;
// .mntc_left {
// display: flex;
// align-items: center;
// .title {
// color: rgba(0, 0, 0, 0.65);
// margin-right: 17px;
// }
// .data {
// color: #4ea6ff;
// }
// .notice_icon {
// width: 14px;
// height: 14px;
// margin-right: 9px;
// margin-left: 9px;
// background-image: url(@/assets/images/coursewareManage/gan.png);
// background-size: 100% 100%;
// }
// }
// .mntc_right {
// cursor: pointer;
// }
// }
.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 {
margin-top: 32px;
padding-right: 30px;
flex: 1;
border-right: 1px solid #e8e8e8;
.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;
.ant-input {
height: 100%;
}
.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;
.signbox {
width: 120px;
display: flex;
justify-content: end;
align-items: center;
.sign {
margin-right: 5px;
}
}
.textarea {
width: 423px;
.ant-input {
width: 100%;
}
.ant-input-textarea-show-count {
position: relative;
}
.ant-input-textarea-show-count::after {
position: absolute;
right: 10px;
bottom: 0;
}
.ant-input {
border-radius: 8px;
}
}
}
}
.tableBox {
// margin: 20px 38px 30px;
margin: 10px 35px 0 35px;
th.h {
background-color: #eff4fc !important;
}
.ant-table-tbody
> tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
> td {
background: #f6f9fd;
}
}
.tableBox {
padding-bottom: 20px;
.pa {
// position: absolute;
// bottom: 20px;
// left: 0;
width: 100%;
// height: 20px;
// background-color: red;
display: flex;
justify-content: center;
// margin-bottom: 10px;
// position: absolute;
// bottom: -40px;
.pagination {
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
.main_table {
position: relative;
padding-bottom: 80px;
.ant-checkbox-wrapper {
align-items: center;
margin-top: -2px;
}
.ant-table-selection-column {
padding: 0 !important;
padding-left: 5px !important;
}
.ant-table-thead > tr > th {
background-color: rgba(239, 244, 252, 1);
}
th.h {
background-color: #eff4fc !important;
}
.ant-table-tbody
> tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
> td {
background: #f6f9fd;
}
.pa {
left: 0;
width: 100%;
display: flex;
justify-content: center;
position: absolute;
bottom: 20px;
}
}
.main_btns {
height: 72px;
width: 100%;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 1px 35px 0 rgba(118, 136, 166, 0.16);
.btn1 {
width: 100px;
height: 40px;
border: 1px solid #4ea6ff;
border-radius: 8px;
color: #fff;
background-color: #4ea6ff;
cursor: pointer;
}
.btn2 {
cursor: pointer;
width: 100px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-left: 15px;
color: #fff;
}
}
}
}
.createschooltime {
z-index: 999;
width: 879px;
background: #ffffff;
box-shadow: 0 1px 35px 0 rgba(118, 136, 166, 0.21);
position: absolute;
left: 50%;
top: -100%;
transform: translate(-50%, -50%);
.cst_header {
position: absolute;
width: 100%;
height: 40px;
background: linear-gradient(
rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%
);
}
.cst_main {
width: 100%;
max-height: 700px;
overflow-y: auto;
position: relative;
.cstm_header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.add_icon {
width: 16px;
height: 16px;
margin-right: 10px;
background-image: url(@/assets/images/coursewareManage/add1.png);
background-size: 100% 100%;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.cstm_title {
margin: 10px auto 20px 51px;
font-weight: bold;
}
.cstm_items {
display: flex;
width: 80%;
margin: auto;
align-items: center;
margin-bottom: 23px;
.signbox {
display: flex;
justify-content: end;
width: 100px;
margin-right: 6px;
.sign {
margin-top: -5px;
margin-right: 4px;
}
}
.b_input {
flex: 1;
position: relative;
.upload_box {
display: flex;
cursor: pointer;
.upload_icon {
width: 16px;
height: 16px;
margin-right: 5px;
}
}
.inp_num {
position: absolute;
top: 9px;
right: 10px;
}
}
}
.items_fj {
margin-bottom: 1px;
.fujian {
display: none;
}
.mbl_items12 {
width: 440px;
margin-right: 56px;
.i12_box1 {
display: flex;
align-items: center;
padding: 17px 0 17px 21px;
border: 1px solid #eff4fc;
border-radius: 8px;
margin-bottom: 10px;
.file_img {
width: 27px;
height: 32px;
background-image: url(@/assets/images/coursewareManage/imgs.png);
margin-right: 22px;
img {
width: 100%;
height: 100%;
}
}
.file_detail {
width: 250px;
margin-right: 21px;
.file_updata {
display: flex;
align-items: center;
.updatabox {
position: relative;
width: 230px;
height: 5px;
background-color: rgba(192, 192, 192, 0.25);
border-radius: 3px;
.updatacolor {
position: absolute;
left: 0;
width: 100%;
height: 5px;
background-color: #57c887;
border-radius: 3px;
}
.updatacolor2 {
position: absolute;
left: 0;
width: 80%;
height: 5px;
background-color: #ff7474;
border-radius: 3px;
}
.updatacolor3 {
position: absolute;
left: 0;
width: 60%;
height: 5px;
background-color: #4ea6ff;
border-radius: 3px;
}
.updataxq {
position: absolute;
right: 2px;
top: -30px;
color: #57c887;
}
.updataxq2 {
position: absolute;
right: 2px;
top: -30px;
color: #ff7474;
}
.updataxq3 {
position: absolute;
right: 2px;
top: -30px;
color: #4ea6ff;
}
}
}
}
.file_operation {
display: flex;
.fobox {
margin-right: 5px;
cursor: pointer;
}
}
}
}
}
.items_btn {
display: flex;
justify-content: center;
margin-top: 20px;
margin-bottom: 20px;
.cstm_btn {
width: 100px;
height: 40px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.btnText {
font-size: 14px;
font-weight: 400;
line-height: 40px;
}
}
.btn5 {
border: 1px solid rgba(64, 158, 255, 1);
color: #4ea6ff;
}
.btn6 {
background-color: #4ea6ff;
color: #ffffff;
}
}
}
}
</style>