Files
fe-student/src/views/project/ProjectDetails.vue
2024-05-29 09:23:54 +08:00

1089 lines
39 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 style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="pathdetails" style="padding: 30px">
<div class="pdname">
{{ data?.name }}
<el-popover v-if="data?.remark" ref="popover" popper-class="jianjie" placement="right" trigger="hover" :width="300"
:content="data.remark">
<template #reference><span style="font-size: 16px;font-weight: 600;">简介></span></template>
</el-popover>
</div>
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detailL">
<div v-if="data?.stageProcessList" v-for="(i, k) in data?.stageProcessList" :key="k">
<div v-if="i.id == '0' && i.taskProcessList?.length == 0"></div>
<div v-else class="title">
<div class="titleL">{{ i.stageName }}</div>
<div class="titleR" :style="{ display: 'flex' }">
<img src="../../assets/image/pathdetails/circle.png" />
<div class="titleRT"
:style="(i.statusName === '已完成' || i.statusName === '进行中') ? 'color:#0060ff' : 'color:#999'">
{{ i.statusName || (data.unlockMode === 1 ? '未开始' : '未解锁') }}
</div>
</div>
</div>
<div v-if="i.id == '0' && i.taskProcessList?.length == 0"></div>
<!--去掉阶段内按id排序以接口返回顺序排序 .sort((a, b) => { return a.id - b.id; })-->
<div v-else class="course" v-for="(value, index) in (i.taskProcessList).filter(
(e) => !whiteTypes(e.type)
)" :key="index">
<div style="width: 70%">
<div v-if="value.name.length > 50" class="coursename" :title="value.name">
<el-popover ref="popover" placement="right" trigger="hover" :width="300" :content="value.name">
<template #reference></template>
</el-popover>
</div>
<div v-else class="coursename" :title="value.name">{{ value.name }}</div>
<div class="coursetag">
<div v-if="value.flag" class="tag1" style="margin-right: 11px; margin-top: 16px">
必修
</div>
<div v-else class="tag2" style="margin-right: 11px; margin-top: 16px">
选修
</div>
<div class="tag3" style="margin-right: 11px; margin-top: 16px">
{{ TASK_TYPES.typeName[value.type] || "" }}
</div>
</div>
<div v-if="value.type == 1" class="progressBox">
<div>当前进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress :percentage="parseInt(value.currentRatio)" :show-text="false" :stroke-width="8" :color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(parseInt(value.currentRatio) / 20)]
" />
</div>
<div style="font-size: 14px;font-weight: 500;color: #277aff;margin-left: 10px;color:#677d86;">
{{ parseInt(value.currentRatio) }}%
</div>
</div>
</div>
</div>
<el-dropdown trigger="click">
<div v-if="data.unlockMode === 1" class="goclass" @click="toFinish(value, i.stageName, i.id, i.studyModel)" :style="{ background: (value.statusName !== '已结束' && (value.statusName || i.studyModel==0)) ? '#2478ff' : '#999' }">
{{ value.statusName || (i.studyModel==0 ? TASK_TYPES.toName[value.type] : '未解锁')}}
</div>
<div v-else class="goclass" @click="toFinish(value, i.stageName, i.id, i.studyModel)" :style="{ background: (value.statusName !== '已结束' && value.statusName) ? '#2478ff' : '#999' }">
{{ value.statusName || '未解锁' }}
</div>
<!-- <template #dropdown v-if="value.type===2 && value.targetId?.split(',')?.length > 1">
<el-dropdown-menu>
<el-dropdown-item v-for="(name,key) in value.targetName?.split(',')" :key="key" @click="toOffcoursePlanPage(value.targetId?.split(',')[key])">{{ name }}</el-dropdown-item>
</el-dropdown-menu>
</template> -->
</el-dropdown>
</div>
</div>
</div>
<div class="detailR">
<!-- todo #路径详情 课程公告及共享文档缺失-->
<!-- 课程公告及共享文档 -->
<div class="detailRT">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="项目公告" name="first">
<!-- <pre class="notice">{{ data.notice || "暂无公告" }}</pre> -->
<div class="notice">{{ data?.notice || "暂无公告" }}</div>
</el-tab-pane>
<el-tab-pane label="共享文档" name="second">
<div style="padding: 19px 30px 17px 28px">
<div v-for="(value, index) in JSON.parse(data?.attach ? data?.attach : '[]')" :key="index" style="
display: flex;
align-items: center;
margin-bottom: 15px;">
<!-- <img :src="value.img" style="width: 22px; height: 26px"/> -->
<FileTypeImg
:v-model="value.name ? value.name : value.slice(value.lastIndexOf('/') + 1, value.indexOf('-')) + value.slice(value.lastIndexOf('.'))"
:style="{ width: '22px', height: '26px' }"></FileTypeImg>
<div class="sharedocname">{{ value.name }}</div>
<div class="download">
<img src="../../assets/image/download.png" style="width: 16px; height: 15px" />
<div style="margin-left: 7px" @click="downloadFile(value.response.data)">下载</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!-- 课程公告及共享文档 -->
<!-- 个人信息及学习进度 -->
<div class="detailRB">
<div class="info">
<div class="title">
<img style="width: 21px; height: 20px" src="../../assets/image/pathdetails/info.png" />
<div class="text" style="margin-left: 7px">个人信息</div>
<div class="box"></div>
</div>
<!-- todo #路径详情 个人信息缺少img和介绍-->
<div class="teacheritem" :style="{ 'border-bottom': '1px solid rgba(56, 125, 247, 0.2)' }">
<img class="peopleimg" :src="userInfo?.avatar?.includes('upload')?userInfo?.avatar:'/upload'+userInfo?.avatar" />
<div style="margin-left: 17px">
<div class="teacherName">
<div style="margin-right: 5px">
{{ userInfo?.realName }}
</div>
</div>
<div class="introduce">{{ userInfo?.bandDesc }}</div>
</div>
</div>
</div>
<div class="info" style="padding-top: 20px">
<div class="title">
<img style="width: 18px; height: 17px" src="../../assets/image/pathdetails/study.png" />
<div class="text" style="margin-left: 9px">学习进度</div>
<div class="box"></div>
</div>
<div class="rate" v-if="data?.lastLearned">
<div class="ratetext">上次学到:{{ data?.lastLearned }}</div>
<div v-if="data?.lastLearned" class="ratebtn" @click="continueLearn(data?.lastLearnedId)">继续学习</div>
</div>
<div style="margin-top: 16px">
<div class="progressBox">
<div>总进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress :percentage="parseInt((data?.totalProgress || 0) * 100)"
:show-text="false" :stroke-width="8" :color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(((data?.totalProgress || 0) * 100) / 20)]
" />
</div>
<div style="font-size: 14px; font-weight: 500; margin-left: 10px;color:#677d86;">
{{ parseInt((data?.totalProgress || 0) * 100) }}%
</div>
</div>
</div>
</div>
<div style="margin-top: 31px">
<div class="progressBox">
<div>必修进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress :percentage="parseInt((data?.compulsoryProgress || 0) * 100)"
:show-text="false" :stroke-width="8" :color="
{
0: 'rgba(238, 112, 108, 1)',
1: 'rgba(255, 151, 38, 1)',
2: 'rgba(39, 122, 255, 1)',
3: 'rgba(59, 94, 251, 1)',
4: 'rgba(57, 219, 183, 1)',
5: 'rgba(57, 219, 183, 1)',
}[parseInt(((data?.compulsoryProgress || 0) * 100) / 20)]
" />
</div>
<div style="
font-size: 14px;
font-weight: 500;
color: #277aff;
margin-left: 10px;color:#677d86;">
{{parseInt(((data?.compulsoryProgress || 0) * 100)) }}%
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 个人信息及学习进度 -->
<!-- 学员积分及个人完成度排行榜 -->
<div class="detailRB" v-if="data?.rankFlag">
<div class="info">
<div
style="display:flex;justify-content: space-between;align-items: center;height: 56px;padding-left: 27px;padding-right: 27px;">
<div @click="tabChange(1)"
style="font-size: 14px;color: rgba(51, 51, 51, 1);font-weight: 600;cursor: pointer;" :style="{}">积分排行榜
</div>
<!-- <div style="font-size: 14px;color: rgba(51, 51, 51, 1);font-weight: 600;">完成度排行榜</div> -->
<el-select @change="choiceStatus" v-model="stateValue" class="m-2" mode="tags" placeholder="完成度排行榜"
style="width: 130px;border: 0px solid red !important; box-shadow:none !important; ">
<el-option v-for="item in studyProgress" :key="item.value" :label="item.label" :value="item.value" :disabled="item.label.includes('小组') && data?.groupId==null?true:false" :title="item.label.includes('小组') && data?.groupId==null?'当前学员无小组':''"/>
</el-select>
</div>
<!-- line -->
<div style="display: flex;height: 1px;background-color: #ecf5ff;justify-content: space-between;">
<div v-if="tabValue == 1" style="width:90px;height: 2px;background-color: #409EFF;margin-left: 18px;"></div>
<div v-else style="width:90px;height: 2px;background-color: rgba(0,0,0,0);margin-left: 18px;"></div>
<div v-if="tabValue !== 1" style="width:146px;height: 2px;background-color: #409EFF;margin-right: 18px;">
</div>
<div v-else style="width:146px;height: 2px;background-color: rgba(0,0,0,0);margin-right: 18px;"></div>
</div>
<!-- line -->
<div style="width: 100%;display: flex;flex-direction: column;height: 66px;justify-content: center;">
<div style="display: flex;justify-content: space-between;">
<div style="width:90px;margin-left: 50px;font-size: 14px;color: rgba(103, 125, 134, 1);">
我的排名:{{ myIndex }}
</div>
<div style="width:146px;margin-right: -30px;font-size: 14px;color: rgba(103, 125, 134, 1);">
{{ tabValue == 1 ? "项目积分 " : "完成度 " }} {{ tabValue == 1 ? myPoint : myRateStr }}
</div>
</div>
</div>
<!-- 排行榜列表 -->
<div
style="display: flex;padding-top: 30px;padding-bottom: 100px;background: linear-gradient(0deg, rgba(36,120,255,0) 0%, rgba(36,120,255,0.15) 100%);">
<div style="display: flex;justify-content: center;align-items: center;width: 100%;">
<div style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;">排名</div>
<div
style="margin-left: 110px;margin-right: 110px;font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;">
名称
</div>
<div style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;">
{{ tabValue == 1 ? "积分" : "进度" }}
</div>
</div>
</div>
<!-- 学员列表 -->
<div>
<div v-for="(item, i) in tableRankData.slice(0,5)" :key="i"
style="display: flex;justify-content: center;align-items: center;width: 100%;position: relative;top:-60px;margin-bottom: 38px;">
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;position: relative;">
{{ i + 1 == 1 || i + 1 == 2 || i + 1 == 3 ? '' : i + 1 }}
<img v-if="i + 1 == 1" style="width: 24px; height: 24px;" src="../../assets/image/rank1.png" />
<img v-if="i + 1 == 2" style="width: 24px; height: 24px;" src="../../assets/image/rank2.png" />
<img v-if="i + 1 == 3" style="width: 24px; height: 24px;" src="../../assets/image/rank3.png" />
<img v-if="i + 1 == myIndex" style="width: 24px; height: 24px;position: absolute;left:110px;"
src="../../assets/image/rankme.png" />
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:34%;display: flex;justify-content: center;align-items: center;">
<img style="width: 28px; height: 28px;border-radius: 28px;" :src="item?.avatar" />
{{ item.name }}
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;">
{{ tabValue == 1 ? item?.pointsCount : item?.rateStr }}
</div>
</div>
<!-- 我的排名 -->
<div v-if="myIndex > 5"
style="display: flex;justify-content: center;align-items: center;width: 100%;position: relative;top:-60px;margin-bottom: 38px;">
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;">
{{ '...' }}
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:34%;display: flex;justify-content: center;align-items: center;">
{{ '' }}
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;">
{{ '' }}
</div>
</div>
<div v-if="myIndex > 5"
style="display: flex;justify-content: center;align-items: center;width: 100%;position: relative;top:-60px;margin-bottom: 38px;">
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;">
{{ myIndex }}
<img style="width: 24px; height: 24px;position: absolute;left:110px;"
src="../../assets/image/rankme.png" />
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:34%;display: flex;justify-content: center;align-items: center;">
<img style="width: 28px; height: 28px;border-radius: 28px;" :src="tableRankData[myIndex - 1]?.avatar" />
{{ tableRankData[myIndex - 1]?.name }}
</div>
<div
style="font-size: 14px;color:rgba(36, 120, 255, 1);font-weight: 600;width:30%;display: flex;justify-content: center;align-items: center;">
{{ tabValue == 1 ? tableRankData[myIndex - 1]?.pointsCount : tableRankData[myIndex - 1]?.rateStr }}
</div>
</div>
</div>
</div>
</div>
<!-- 学员积分及个人完成度排行榜 -->
</div>
</div>
<!-- 详细信息 -->
<!-- 弹框提示信息 -->
<el-dialog title="" top="347px" v-model="dialogVisible" :show-close="false"
style="display:flex;justify-content:center;align-items:center;height: 283px;padding:0;border-radius: 4px;"
width="502px">
<div style="width:288px;color:#333333;font-size: 22px;font-weight: 600;">{{ dialogVisibleTip }}</div>
<span slot="footer" style="display:inline-block;margin-top:60px;">
<el-button @click="dialogVisible = false" style="width:140px;height:40px;margin-right: 22px;">取消</el-button>
<el-button type="primary" @click="dialogVisible = false" style="width:140px;height:40px;">确定</el-button>
</span>
</el-dialog>
<!-- 开课列表弹框 -->
<el-dialog title="" top="347px" v-model="openCourseVisible" :show-close="false"
style="display:flex;justify-content:center;align-items:center;min-height: 320px;padding:0;border-radius: 4px;"
width="502px">
<div style="display: flex;justify-content:space-between;align-items:center;margin-bottom: 22px;">
<div style="width:288px;color:#333333;font-size: 16px;font-weight: 600;">开课列表</div>
<div
@click="openCourseVisible = false"
style="font-size: 12px;cursor:pointer;">X</div>
</div>
<div style="width: 100%;min-height:210px;margin-top: 12px;">
<div
v-for="item,key in openCourseList"
style="width: 100%;display: flex;justify-content: space-between;align-items: center;margin-bottom: 12px;background: rgb(247, 251, 253);height: 40px;padding: 5px;border-radius: 5px;">
<div style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;width: 320px;">{{ item }}</div>
<div
@click="toOffcoursePlanPage(openCourseIdList[key])"
style="width:60px;height:30px;text-align:center;line-height:30px;background:#0078fc;border-radius:5px;color:#fff;cursor: pointer;">去上课</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {computed, onMounted, ref,watch} from "vue";
import {ElMessage} from "element-plus";
import {request} from "@/api/request";
import {
CompletionList,
EvaluationToLearn,
PointList,
QueryEvaluationTaskStatusOne,
STUDY_RECORD,
SubmitExternalExam,
UPDATE_CURRENT_TASK
} from "@/api/api";
import {useRoute, useRouter} from "vue-router";
import {PROJECT, TASK_TYPES} from "@/api/CONST";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {useStore} from "vuex";
const {
query: { courseId, projectId },
} = useRoute();
const router = useRouter();
const { commit, dispatch, state } = useStore()
const store = useStore()
const userInfo = computed(() => state.userInfo)
const data = computed(() => state.projectInfo)
const errorData = computed(() => state.projectError)
console.log(data)
const trueFalse = ref(false)
onMounted(() => {
if(projectId!=''||projectId!=undefined||projectId!=null){
dispatch('getProjectInfo', { projectId })
}else{
trueFalse.value = true
}
})
watch(()=>trueFalse.value,(val)=>{
dispatch('getProjectInfo', { projectId })
})
watch(()=>errorData.value,(val)=>{
if(val.data == null){
ElMessage.error(val.msg)
window.parent.postMessage({ type: 'navigate', path: '/uc/study/task' }, '*');
}
},{deep:true})
const tableRankData = ref([])
const studyProgress = [
{
value: 2,
label: "个人完成度"
},
{
value: 3,
label: "小组完成度"
}
];
const stateValue = ref(undefined)
const openCourseVisible = ref(false);
const openCourseList = ref([]);
const openCourseIdList = ref([]);
// 完成度选择
const myRate = ref('')
const myRateStr = ref('')
const choiceStatus = (e) => {
tabValue.value = e
stateValue.value = e
// 获取个人完成度
request(CompletionList, { projectId: projectId, type: e === 2 ? 0 : 1 }).then(res => {
tableRankData.value = res.data.datas
myIndex.value = res.data.myIndex
myRate.value = res.data.myRate
myRateStr.value = res.data.myRateStr
})
}
// Tab 展示 --- 默认展示积分排行榜 1 个人完成度 2 小组完成度 3
const tabValue = ref(1)
const tabChange = (tabs) => {
stateValue.value = undefined;
tabValue.value = tabs;
// 获取项目积分
request(PointList, { projectId: projectId }).then(res => {
tableRankData.value = res.data.datas
myIndex.value = res.data.myIndex
myPoint.value = res.data.myPointsCount
})
}
const myIndex = ref('')
const myPoint = ref('')
// 获取项目积分
request(PointList, { projectId: projectId }).then(res => {
tableRankData.value = res.data.datas
myIndex.value = res.data.myIndex
myPoint.value = res.data.myPointsCount
})
const activeName = ref("first");
const handleClick = (tab, event) => {
console.log(tab, event);
};
const path = { 1: "path" };
const dialogVisible = ref(false);
const dialogVisibleTip = ref('该任务无法学习,请联系管理员进行替换!');
// 判断当前任务已结束及时间意义上的结束 提示用户
function judgeTaskIsEnd(type, endTimes, status) {
// type 任务类型 endTime 结束时间 status 任务状态 (状态 0 未完成 1 已完成 2 未开始 -1 已结束)
let isEnd = false;
let nowTime = new Date().getTime();
let endTime = new Date().getTime(endTimes);
switch (type) {
case 1:
status == -1 ? isEnd = true : nowTime > endTime ? isEnd = true : isEnd = false;
break;
//案例么有时间限制
// case 3:
// status == 3 ? isEnd = true : nowTime > endTime ? isEnd = true : isEnd = false;
// break;
case 5:
status == -1 ? isEnd = true : nowTime > endTime ? isEnd = true : isEnd = false;
break;
case 7:
status == -1 ? isEnd = true : nowTime > endTime ? isEnd = true : isEnd = false;
break;
case 10:
status == -1 ? isEnd = true : nowTime > endTime ? isEnd = true : isEnd = false;
break;
}
return isEnd;
}
async function toFinish(d, sName, chapterOrStageId, studyModel) {
console.log(d,'dddd')
if (studyModel != 0 && !d.statusName) {
ElMessage.warning("当前未解锁")
return
}
if(d.statusName == '未解锁'|| d.statusName == ''||!d.hasOwnProperty('statusName')){
ElMessage.warning("当前未解锁")
return
}
if (judgeTaskIsEnd(d.type, data.value.endTime, data.value.status)) {
ElMessage.error("当前任务已结束")
return
}
if (d.type === 2) {
if(!d.targetId){
return ElMessage.error("还未添加开课,请联系管理员!")
}
if(d.targetId.split(',').length>1){
openCourseList.value = d.targetName?.split(',');
openCourseIdList.value = d.targetId?.split(',');
openCourseVisible.value = true;
return
}
}
// 作业过期判断
if (d.type == 4) {
let date1 = new Date(d.endTime).getTime();
let date2 = new Date().getTime();
if (date1 < date2) {
dialogVisibleTip.value = '当前作业已结束';
dialogVisible.value = true;
//return
}
}
// 直播结束时间
if (d.type == 6) {
let date1 = new Date(d.endTime).getTime();
let date2 = new Date().getTime();
if (date1 < date2) {
dialogVisibleTip.value = '当前直播已结束';
dialogVisible.value = true;
//return
}
}
// 考试 停用
if (d.type == 5) {
if (d.taskStatus == 1 || d.taskStatus == 2) {
// ElMessage.error("该任务无法学习,请联系管理员进行替换。")
dialogVisibleTip.value = '该任务无法学习,请联系管理员进行替换!';
dialogVisible.value = true;
return
}
// 此处判断外部考试跳转
if (d.examType == 2) {
// 点击即更新状态 进行中
request(SubmitExternalExam, {
"type": 1,
"taskId": d.id,
"chapterId": chapterOrStageId,
"externalId": d.courseId,
"externalName": d.name,
"targetId": data.value.projectId,
"studentNo": userInfo.value.userNo
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
router.push({
path: '/externalexamination',
query: {
id: d.id,
type: PROJECT,
infoId: data.value.projectId,
courseId: d.courseId,
pName: data.value.name,
sName,
chapterOrStageId,
exname: d.name, // 考试名称
},
});
return
}
}
// 评估 停用
if (d.type == 11) {
if (d.taskStatus == 1 || d.taskStatus == 2) {
// ElMessage.error("该任务无法学习,请联系管理员进行替换。")
dialogVisibleTip.value = '该任务无法学习,请联系管理员进行替换!';
dialogVisible.value = true;
return
}
}
// 其他活动 结束时间
if (d.type == 9) {
let date1 = new Date(d.endTime).getTime();
let date2 = new Date().getTime();
if (date1 < date2) {
dialogVisibleTip.value = '当前活动已结束';
dialogVisible.value = true;
//return
}
}
// 在线课 停用 -- 暂时没有在线课停用标记
if (d.type == 1) {
if (d.taskStatus == 1 || d.taskStatus == 2) {
// ElMessage.error("该任务无法学习,请联系管理员进行替换。")
dialogVisibleTip.value = '该任务无法学习,请联系管理员进行替换!';
dialogVisible.value = true;
return
}
}
// 面授课 停用
if (d.type == 2) {
if (d.taskStatus == 1 || d.taskStatus == 2) {
// ElMessage.error("该任务无法学习,请联系管理员进行替换。")
dialogVisibleTip.value = '该任务无法学习,请联系管理员进行替换!';
dialogVisible.value = true;
return
}
}
// 测评模块 请求接口跳转新的页面 - 新增 暂时未调试 目前无测评数据 2023-02-04
if (d.type == 10) {
if (d.quizTaskId == null) {
// 肯定没有完成测评
// 调用接口 跳转页面
console.log('我是查询测评跳转链接所传递得参数', {
"businessType": "project",
"chapterId": chapterOrStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": projectId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
})
request(EvaluationToLearn, {
"businessType": "project",
"chapterId": chapterOrStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": projectId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
}).then(res => {
console.log(res)
if (res.code == 200) {
let jumpUrl = res.data.quizUrl
// 此处写跳转url
window.open(jumpUrl, '_top')
}
}).catch(err => {
console.log(err)
})
return
} else {
// 进行中 或者 已完成
// 调用接口 判断当前测评状态 跳转页面
console.log('我是查询测评跳转链接所传递得参数', {
"quizTaskId": d.quizTaskId
})
request(QueryEvaluationTaskStatusOne, {
"quizTaskId": d.quizTaskId
}).then(res => {
console.log(res)
if (res.code == 200) {
if (res.data.complete_status == 2) {
ElMessage.error("您已完成测评")
return
} else {
// 重新查询跳转
// 调用接口 跳转页面
console.log('我是查询测评跳转链接所传递得参数', {
"businessType": "project",
"chapterId": chapterOrStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": projectId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
})
request(EvaluationToLearn, {
"businessType": "project",
"chapterId": chapterOrStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": projectId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
}).then(res => {
console.log(res)
if (res.code == 200) {
let jumpUrl = res.data.quizUrl
// 此处写跳转url
window.open(jumpUrl, '_top')
}
}).catch(err => {
console.log(err)
})
return
}
}
}).catch(err => {
console.log(err)
})
return
}
}
if (!TASK_TYPES.path[d.type]) {
ElMessage.error("暂时未开放");
return;
}
//更新学员当前任务
await request(UPDATE_CURRENT_TASK, { id: d.id, type: PROJECT, pid: projectId, name: d.name })
if (d.type == 3 || d.type == 7 || (d.type === 5 && d.examType === 2)) {
console.log(d, data.value)
d.status !== 1 && await request(STUDY_RECORD, {
studentId: userInfo.value.id,
targetId: data.value.projectId,
logo: PROJECT,
type: PROJECT,
stageOrChapterId: chapterOrStageId,
taskId: d.id,
taskType: d.type,
});
}
if (typeof TASK_TYPES.path[d.type] === "string") {
TASK_TYPES.path[d.type] && TASK_TYPES.path[d.type].startsWith("http") && window.open(TASK_TYPES.path[d.type] + d.targetId, '_top');
TASK_TYPES.path[d.type] && TASK_TYPES.path[d.type].startsWith("/") && router.push({
path: TASK_TYPES.path[d.type],
query: {
id: d.id,
type: PROJECT,
infoId: data.value.projectId,
courseId: d.courseId,
pName: data.value.name,
sName,
chapterOrStageId,
btype: 1
},
});
} else if (typeof TASK_TYPES.path[d.type] === "function") {
if(d.type==5){
window.open(TASK_TYPES.path[d.type](d) + d.targetId, "_top")
}else{
TASK_TYPES.path[d.type](d);
}
}
}
function toOffcoursePlanPage(id){
window.open(`${location.protocol}//${location.host}${import.meta.env.VITE_BASE_API}/stu/project/redirectDetail?courseId=${id}`, '_top')
}
function whiteTypes(type) {
return import.meta.env.VITE_TASK_WHITE_TYPE.includes("-" + type + "-");
}
// 查询当前阶段所有任务是否都完成
const queryAllStatus = (data) => {
// status === 1 已完成
console.log(data)
for (let i = 0; i < data.length; i++) {
if (data[i].status !== 1) {
return false
}
}
return true;
}
// 共享文档下载
function downloadFile(url) {
console.log(import.meta.env.VITE_FILE_PATH + url)
window.open(import.meta.env.VITE_FILE_PATH + url);
}
// 继续学习
function continueLearn(lastLearnedId) {
data.value.stageProcessList.forEach(stage => {
stage?.taskProcessList?.forEach(d => {
if (d.id == lastLearnedId) {
toFinish(d, stage.stageName, stage.stageId)
}
})
})
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
.example-showcase .el-loading-mask {
z-index: 9;
}
.el-popper {
z-index: 0 !important;
}
.pathdetails {
.el-dialog__body{
width: 80%;
}
.el-dialog__header {
display: none;
}
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
.return {
position: absolute;
right: 10%;
.text {
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
}
.pdname {
font-size: 20px;
font-weight: 800;
color: #ffffff;
margin-top: 17px;
}
.detailinfo {
width: 100%;
margin-top: 24px;
display: flex;
.detailL {
flex: 1;
margin-right: 20px;
background: #ffffff;
border-radius: 8px;
padding-left: 45px;
padding-right: 45px;
padding-top: 23px;
.title {
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(249, 249, 249, 1);
margin-top: 27px;
margin-bottom: 19px;
.titleL {
font-size: 16px;
font-weight: 800;
color: #333333;
margin-left: 27px;
}
.titleR {
display: flex;
align-items: center;
}
.titleR .titleRT {
font-size: 16px;
font-weight: 800;
color: #0060ff;
margin-right: 73px;
margin-left: 2px;
}
}
.course {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 32px;
margin-left: 26px;
.coursename {
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.coursetag {
display: flex;
flex-wrap: wrap;
}
.progressBox {
font-size: 14px;
font-weight: 500;
color: #677d86;
margin-top: 24px;
.progress {
display: flex;
align-items: center;
}
.progress .el-progress-bar__outer {
background-color: rgba(232, 241, 254, 1);
}
}
.goclass {
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;
display: flex;
align-items: center;
justify-content: center;
margin-right: 37px;
cursor: pointer;
}
}
}
.detailR {
width: 434px;
.detailRT {
min-height: 298px;
background: #ffffff;
border-radius: 8px;
.el-tabs__item {
height: 56px;
padding: 10px 33px 0px 27px;
font-size: 14px;
font-weight: 500;
}
.el-tabs__nav-wrap::after {
background-color: rgba(56, 125, 247, 0.2);
}
.notice {
padding: 15px 43px 30px 47px;
font-size: 14px;
font-weight: 500;
color: #333330;
line-height: 24px;
}
.sharedocname {
width: 259px;
font-size: 14px;
font-weight: 400;
color: #677d86;
margin-left: 20px;
line-height: 24px;
}
.download {
display: flex;
align-items: center;
margin-left: 20px;
cursor: pointer;
font-size: 16px;
font-weight: 400;
color: #2478ff;
}
}
.detailRB {
min-height: 459px;
background: #ffffff;
border-radius: 8px;
margin-top: 17px;
.info .title {
display: flex;
align-items: center;
padding-top: 39px;
position: relative;
margin-left: 48px;
}
.info .title .text {
margin-left: 8px;
font-size: 16px;
color: rgba(51, 51, 51, 1);
font-weight: 800;
}
.info .title .box {
width: 75px;
height: 10px;
background-color: rgba(36, 120, 255, 0.15);
position: absolute;
left: 23px;
top: 53px;
}
.info .teacheritem {
margin-left: 48px;
margin-right: 48px;
margin-top: 30px;
display: flex;
// align-items: center;
}
.info .teacheritem .peopleimg {
width: 60px;
height: 60px;
border-radius: 30px;
}
.info .teacheritem .teacherName {
font-size: 14px;
font-weight: bold;
color: #394145;
display: flex;
align-items: center;
width: 260px;
}
.info .teacheritem .teacherName .teacherMedal {
width: 17px;
height: 19px;
margin-right: 4px;
display: flex;
align-items: center;
}
.info .teacheritem .introduce {
width: 260px;
font-size: 14px;
font-weight: 500;
color: #394145;
margin-top: 14px;
line-height: 24px;
}
.info .rate {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 29px;
margin-left: 48px;
margin-right: 26px;
}
.info .rate .ratetext {
width: 259px;
font-size: 14px;
font-weight: 500;
color: #677d86;
line-height: 24px;
}
.info .rate .ratebtn {
width: 86px;
height: 36px;
border: 1px solid #2478ff;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
color: #2478ff;
line-height: 24px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.info .progressBox {
font-size: 14px;
font-weight: 500;
color: #677d86;
margin-top: 16px;
margin-left: 44px;
.progress {
display: flex;
align-items: center;
}
.progress .el-progress-bar__outer {
background-color: rgba(232, 241, 254, 1);
}
}
}
}
}
}
</style>