Files
fe-student/src/views/faceteach/FaceTeach.vue
2024-02-29 17:31:40 +08:00

790 lines
22 KiB
Vue

<template>
<div
style="
background: #0078fc;
height: 150px;
width: 100%;
position: absolute;
top: 0;
z-index: -9999;
"
></div>
<div class="faceteach" style="padding: 30px">
<!-- 面包屑导航 -->
<div class="crumb">
<div>课程列表</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700">课程详情</div>
<div v-if="pName != ''" class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color: #0073fb">
<img
class="img2"
style="margin-right: 11px; cursor: pointer"
src="../../assets/image/return.png"
/>返回
</el-button
>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- 基本信息 -->
<div class="bascinfo">
<div style="margin-left: 46px">
<div class="title">面授课{{ data.planDto?.name }}</div>
<!-- <div class="time" style="margin-top: 26px">
<img
style="width: 15px; height: 17px"
src="../../assets/image/time.png"
/>
<div style="margin-left: 8px">
{{
dayjs(data.planDto?.beginTime).format("YYYY-MM-DD HH:mm") +
" 至 " +
dayjs(data.planDto?.endTime).format("YYYY-MM-DD HH:mm")
}}
</div>
</div>
<div v-if="data.planDto?.address" class="time" style="margin-top: 23px">
<img
style="width: 16px; height: 18px"
src="../../assets/image/position.png"
/>
<div style="margin-left: 8px">{{ data.planDto?.address }}</div>
</div> -->
</div>
<div>
<div style="display: flex">
<botton
class="btn"
style="margin-right: 20px"
:style="{ background: isAllowSign && !data.signFlag ?'rgb(57, 146, 249)' : '#999' }"
@click="signClick"
>{{ data.signFlag ? "已签到" : "签到" }}
</botton>
<botton
v-if="data.planDto?.evalFlag !== 0"
:style="{
background: `${
new Date(data.planDto?.beginTime).getTime() >
new Date().getTime()
? '#999'
: data.isSurvery
? '#999'
: 'rgb(57, 146, 249)'
}`,
}"
class="btn"
@click="toSurvery"
>{{ data.isSurvery ? "已评估" : "评估" }}
</botton>
</div>
</div>
</div>
<!-- 基本信息 -->
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detail">
<div class="detailT">
<div class="" style="margin-left: 48px; margin-right: 48px">
<div class="title">
<img
style="width: 20px; height: 20px"
src="../../assets/image/course.png"
/>
<div class="text">课程详情</div>
<div class="box"></div>
</div>
<div style="display: flex; align-items: center">
<div class="content" v-html="data.offcourseDto?.intro"></div>
</div>
</div>
</div>
<div class="detailB">
<el-tabs v-model:activeName="activeName" @tab-click="handleClick">
<el-tab-pane label="课程附件" name="first">
<div
v-if="data.planDto?.attach === ''"
style="
font-size: 14px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
margin-left: 40px;
margin-top: 20px;
"
>
此课程无附件
</div>
<div v-else>
<div
v-for="(el, index) in formateArr(data.planDto?.attach)"
:key="index"
class="enclosure"
:style="{ borderBottom: '1px solid rgba(56, 125, 247, 0.2)' }"
>
<div class="enclosureL">
<FileTypeImg
:v-model="
el.name
? el.name
: el.slice(el.lastIndexOf('/') + 1, el.indexOf('-')) +
el.slice(el.lastIndexOf('.'))
"
:style="{
width: '22px',
height: '26px',
marginLeft: '10px',
}"
></FileTypeImg>
<div style="margin-left: 20px">
{{
el.name
? el.name
: el.slice(el.lastIndexOf("/") + 1, el.indexOf("-")) +
el.slice(el.lastIndexOf("."))
}}
</div>
</div>
<div>
<div
v-if="
new Date(data.planDto.beginTime).getTime() >
new Date().getTime()
"
class="download"
>
<img
style="width: 16px; height: 15px"
src="../../assets/image/download.png"
/>
<div
style="margin-left: 5px; color: #999"
@click="downloads(el)"
>
下载
</div>
</div>
<div v-else class="download">
<img
style="width: 16px; height: 15px"
src="../../assets/image/download.png"
/>
<div
style="margin-left: 5px"
@click="download(el.name ? el.response.data : el)"
>
下载
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="课程作业" name="second">
<div class="work" v-if="data.workDto!== null && data.workDto?.workName">
<div>
<div class="question">{{ data.workDto?.workName }}</div>
<div style="margin-top: 16px; display: flex">
<div class="tag1" v-if="data.workDto?.workFlag">必修</div>
<div class="tag3" style="margin-left: 11px">作业</div>
</div>
</div>
<div
:style="{
background:
new Date(data.planDto?.beginTime).getTime() >
new Date().getTime()
? '#999'
: '',
}"
class="submit"
@click="toWork"
>
交作业
</div>
</div>
<div
v-else
style="
font-size: 14px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
margin-left: 40px;
margin-top: 20px;
"
>
此课程无作业
</div>
</el-tab-pane>
<el-tab-pane
label="课程考试"
name="third"
:disabed="dayjs().isBefore(dayjs(data.planDto?.beginTime))"
>
<div class="work" v-if="data.examinationDto?.id">
<div>
<div class="question">
{{ data.examinationDto?.examinationName }}
</div>
<div style="margin-top: 16px; display: flex">
<div
class="tag1"
v-if="data.examinationDto?.examinationFlag">
必修
</div>
<div class="tag3" style="margin-left: 11px">考试</div>
</div>
</div>
<div
:style="{
background:
new Date(data.planDto?.beginTime).getTime() >
new Date().getTime()
? '#999'
: '',
}"
class="submit"
@click="toExamItem(data.examinationDto)">
去考试
</div>
</div>
<div
v-else
style="
font-size: 14px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
margin-left: 40px;
margin-top: 20px;
"
>
此课程无考试
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
<div class="teacher">
<div class="title">
<img
style="width: 21px; height: 23px"
src="../../assets/image/livelecturer.png"
/>
<div class="text">面授课讲师</div>
<div class="box"></div>
</div>
<!-- todo #面授课接口 讲师缺少img和介绍-->
<div class="teacheritem" v-for="(item,index) in teacherItem">
<img class="peopleimg" :src="item.avatar"/>
<div class="nameSpan" style="align-items: flex-start;justify-content:flex-start;flex-direction: column;padding-left: 10px;">
<div class="teacherName" style="padding: 5px 0;">
{{ item.realName }}
</div>
<!-- <div class="introduce">{{ data.planDto?.bandDesc }}</div> -->
<div class="introduce" style="margin: 0;">{{useOrgName(item.orgNamePath)}}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {computed, onBeforeMount, onUnmounted, ref,watch} from "vue";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {request, useRequest,boeRequest} from "@/api/request";
import {STU_OFFCOURSE_DETAIL, TASK_OFFCOURSE_NOTASK_SIGN,} from "@/api/api";
import {useRoute, useRouter} from "vue-router";
import {useUserInfo} from "@/api/utils";
import {ElMessage} from "element-plus";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
import { useOrgName } from "@/hooks/useOrgName.js";
import {BASE, GET_USER_LIST,GET_USER_INFO_OLDURL} from "@/api/ThirdApi";
const router = useRouter();
onBeforeMount(() => dayjs.extend(isBetween));
const returnclick = () => {
router.back();
};
const {
query: { courseId },
} = useRoute();
const { data } = useRequest(STU_OFFCOURSE_DETAIL, {
courseId,
usePermission: true,
});
watch(data, (newVal) => {
// newVal.planDto.offteachers.map(item => teacherInfos(item.teacherId));
const teacherIdsArray = newVal.planDto.offteachers.map(item => item.teacherId);
const teacherItemArr = []
teacherIdsArray.forEach(id => {
teacherItemArr.push(boeRequest(GET_USER_INFO_OLDURL, { userId: id }))
})
Promise.all(teacherItemArr).then(responses => {
responses.map((arr)=>{
const userInfo = arr.result;
userInfo.avatar = userInfo?.avatar
? userInfo?.avatar.includes('upload')
? userInfo?.avatar
: '/upload' + userInfo?.avatar
: '/800e23f7-b58c-4192-820d-0c6a2b7544cc.png';
const index = teacherIdsArray.indexOf(userInfo.userId)
userInfo.realName = newVal.planDto.offteachers[index].teacherName
teacherItem.value.push(userInfo)
})
}).catch(error => {
console.log(error)
})
});
const teacherItem = ref([])
// const teacherInfos = async (id) => {
// const res = await boeRequest(GET_USER_INFO_OLDURL, { userId: id });
// const userInfo = res.result;
// console.log(userInfo,'userInfo')
// userInfo.avatar = userInfo?.avatar
// ? userInfo?.avatar.includes('upload')
// ? userInfo?.avatar
// : '/upload' + userInfo?.avatar
// : '/800e23f7-b58c-4192-820d-0c6a2b7544cc.png';
// teacherItem.value.push(...userInfo)
// }
// const teacherInfo = useUserInfo(computed(() => data.value?.planDto?.offteachers[0].teacherId));
const isAllowSign = computed(() => dayjs().isBetween(dayjs(data.value.planDto?.beginTime).subtract(data.value.planDto?.beforeStart || 0, "minute"), dayjs(data.value.planDto?.afterStart ? data.value.planDto?.beginTime : data.value.planDto?.endTime).add(data.value.planDto?.afterStart || 0, "minute")));
const handleClick = (tab, event) => {
console.log("附件", tab, event);
};
const activeName = ref("first");
const fielPath = ref(import.meta.env.VITE_FILE_PATH);
const download = (url) => {
console.log(fielPath.value + url);
window.open(fielPath.value + url);
};
const downloads = (url) => {
ElMessage.warning("未到开始时间,请耐心等待!");
};
function formateArr(strs) {
let newArr;
try {
newArr = JSON.parse(strs);
} catch {
newArr = strs?.split(",");
}
return newArr;
}
//签到
const signClick = () => {
if (data.value.signFlag) {
return;
}
if (!isAllowSign.value) {
ElMessage.warning("未在允许签到时间范围内");
return;
}
data.value.signFlag = 1;
ElMessage.warning("签到成功");
request(TASK_OFFCOURSE_NOTASK_SIGN, { courseId: courseId, taskId: courseId, type: 3 });
};
function toSurvery() {
if (dayjs().isBefore(data.value.planDto.beginTime)) {
ElMessage.warning("课程未开始,请耐心等待!");
return;
}
if (!data.value.planDto.evalFlag) {
ElMessage.warning("此课程无评估");
return;
}
router.push({
path: "/surveydetail",
query: {
id: data.value.planDto.id,
courseId: data.value.planDto.assessmentId,
pName: "面授课",
infoId: data.value.planDto.id,
chapterOrStageId: 0,
sName: data.value.planDto.name,
type: 3,
isSubmitTrue:data.value.isSurvery
},
});
}
function toWork() {
console.log(data);
if (dayjs().isBefore(data.value.planDto.beginTime)) {
ElMessage.warning("未到开始时间,请耐心等待!");
return;
}
router.push({
path: "/homeworkpage",
query: {
courseId: data.value.planDto.homeWorkId,
// id: taskId,
infoId: data.value.planDto.id,
chapterOrStageId: 0,
type:3,
pName: "面授课",
sName: data.value.planDto.name,
},
});
}
function toExamItem(obj) {
if (data.value.planDto.beginTime) {
let date1 = new Date(data.value.planDto.beginTime).getTime();
let date2 = new Date().getTime();
if (date1 > date2) {
ElMessage.warning("未到开始时间,请耐心等待!");
}
}
console.log("obj", obj, obj.examType);
// 判断内部还是外部考试
if (obj.examType == 2) {
router.push({
path: "/externalexamination",
query: {
courseId: obj.id,
type: 3,
exname: obj.examinationName, // 考试名称
pName: "面授课",
sName: data.value.planDto.name
},
});
} else {
window.open(
window.location.protocol + import.meta.env.VITE_BOE_EXAM_DETAIL_URL + obj.examinationTestId,
"_top"
);
}
}
</script>
<style lang="scss">
.faceteach {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
}
.bascinfo {
width: 100%;
height: 80px;
border-radius: 8px;
background-color: rgba(255, 255, 255, 1);
margin-top: 37px;
display: flex;
justify-content: space-between;
align-items: center;
.btn {
width: 146px;
height: 46px;
background: #2478ff;
border-radius: 4px;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 14px;
font-weight: 800;
line-height: 24px;
cursor: pointer;
margin-right: 96px;
}
.title {
font-size: 20px;
font-weight: 800;
color: #333333;
line-height: 24px;
margin-left: -9px;
}
.time {
font-size: 14px;
color: #6e7b84;
line-height: 24px;
display: flex;
align-items: center;
}
}
.return {
position: absolute;
right: 10%;
.text {
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.detailinfo {
width: 100%;
margin-top: 20px;
display: flex;
align-items: flex-start;
.detail {
flex: 1;
margin-right: 20px;
.detailT {
min-height: 263px;
background: #ffffff;
border-radius: 8px;
color: rgba(51, 51, 51, 1);
.title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
}
.title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.content {
margin-left: 8px;
font-size: 14px;
color: rgba(51, 51, 48, 1);
font-weight: 500;
line-height: 35px;
margin-top: 30px;
padding-bottom: 30px;
}
}
.detailB {
min-height: 363px;
background: #ffffff;
border-radius: 8px;
margin-top: 20px;
.wenxintishi {
display: flex;
justify-content: stretch;
padding: 72px;
}
.el-tabs__item {
height: 69px;
padding: 25px 7px 0px 52px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.enclosure {
height: 89px;
margin-left: 51px;
margin-right: 40px;
// border-bottom: 1px solid rgba(56, 125, 247, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
.enclosureL {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
color: #677d86;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 400;
color: #2478ff;
line-height: 24px;
cursor: pointer;
}
}
.work {
margin-left: 51px;
margin-right: 40px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 37px;
}
.work .question {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 18px;
}
.work .submit {
width: 126px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
font-size: 16px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
.teacher {
width: 434px;
min-height: 500px;
// height: 10%;
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
.title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
margin-left: 48px;
}
.title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.teacheritem {
margin-left: 48px;
margin-right: 48px;
// min-height: 115px;
margin-top: 20px;
padding: 25px 0px;
display: flex;
position: relative;
// align-items: center;
}
.teacheritem .peopleimg {
width: 60px;
height: 60px;
border-radius: 30px;
}
.teacheritem {
.nameSpan {
width: 190px;
display: flex;
align-items: center;
justify-content: center;
.teacherName {
font-size: 14px;
font-weight: bold;
color: #394145;
display: flex;
align-items: center;
}
}
}
.teacheritem {
.nameSpan {
width: 190px;
display: flex;
align-items: center;
justify-content: center;
.teacherName {
font-size: 14px;
font-weight: bold;
color: #394145;
display: flex;
align-items: center;
}
}
}
.teacheritem .introduce {
font-size: 14px;
font-weight: 500;
color: #394145;
margin-top: 14px;
}
.teacheritem .follow {
width: 80px;
height: 30px;
background: #387df7;
border-radius: 4px;
margin-top: 28px;
position: absolute;
right: -25px;
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
}
</style>