Files
fe-student/src/views/roadmap/PathDetails.vue
2023-03-20 19:36:56 +08:00

904 lines
30 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.chapterRemark" ref="popover" popper-class="jianjie" placement="right" trigger="hover"
:width="300" :content="data.chapterRemark">
<template #reference><span style="font-size: 16px;font-weight: 600;">关卡说明></span></template>
</el-popover>
</div>
<!-- 详细信息 -->
<div class="detailinfo">
<div class="detailL">
<div>
<div class="title">
<div class="titleL">{{ data.currentStageName }}</div>
<div class="titleR" :style="{ display: 'flex' }">
<img :src="data.currentChapterCnt ? circle : circle2"/>
<div class="titleRT"
:style="(data.statusName === '已完成' || data.statusName === '进行中') ? 'color:#0060ff' : 'color:#999'">
{{ data.statusName || (data.unlockMode === 1 ? "未开始" : "未解锁") }}
</div>
</div>
</div>
<div class="course" v-for="(value, index) in data.taskBoList?.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>{{ value.name }}</template>
</el-popover>
</div>
<div v-else class="coursename" :title="value.name">
{{ value.name }}
</div>
<div class="coursetag">
<div class="tag1" style="margin-right: 11px; margin-top: 16px" v-if="value.flag">
必修
</div>
<div class="tag2" style="margin-right: 11px; margin-top: 16px" v-if="!value.flag">
选修
</div>
<div class="tag3" style="margin-right: 11px; margin-top: 16px">
{{ TASK_TYPES.typeName[value.type] || "" }}
</div>
<!-- <div-->
<!-- v-for="(item, key) in value.flag"-->
<!-- :key="key"-->
<!-- :class="{1:'tag1',2:'tag2',3:'tag3',4:'tag4'}[item.type]"-->
<!-- style="margin-right: 11px; margin-top: 16px"-->
<!-- >-->
<!-- {{ item.name }}-->
<!-- </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;" :style="{
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)],
}">
{{ parseInt(value.currentRatio) }}%
</div>
</div>
</div>
</div>
<el-dropdown trigger="click">
<div v-if="isStudy=='true'" class="goclass"
:style="{ background: (value.statusName !== '已结束' && (value.statusName || data.unlockMode === 1)) ? '#2478ff' : '#999' }"
@click="toFinish(value)">
{{ value.statusName || (data.unlockMode === 1 ? TASK_TYPES.toName[value.type] : "未解锁") }}
</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">
<!-- 课程公告及共享文档 -->
<div class="detailRT">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="路径说明" name="first">
<div class="notice">
{{ data.remark || "暂无说明" }}
</div>
</el-tab-pane>
<el-tab-pane label="共享文档" name="second" v-if="data.attachSwitch == '1'">
<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"/>
<div style="margin-left: 17px">
<div class="teacherName">
<div style="margin-right: 5px">
{{ userInfo?.realName }}
</div>
<!-- <div v-for="(item, key) in data.userInfoBo?.medal" :key="key">-->
<!-- <img class="teacherMedal" :src="item"/>-->
<!-- </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 v-if="isStudy=='true'" class="rate">
<div class="ratetext">上次学到{{ data.lastLearned }}</div>
<div v-if="data.lastLearned" class="ratebtn" @click="continueLearn(data.lastLearned, data.taskBoList)">
继续学习
</div>
</div>
<div style="margin-top: 16px">
<div class="progressBox">
<div>总进度</div>
<div class="progress">
<div style="width: 291px">
<el-progress
:percentage="parseInt((data.currentChapterCnt || 0) / (data.totalChapterCnt || 1) * 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.currentChapterCnt || 0) / (data.totalChapterCnt || 1) * 100) / 20]
"/>
</div>
<div style="font-size: 14px; font-weight: 500; margin-left: 10px" :style="{
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.currentChapterCnt || 0) / (data.totalChapterCnt || 1) * 100) / 20],
}">
{{ parseInt((data.currentChapterCnt || 0) / (data.totalChapterCnt || 1) * 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.currentReqCnt || 0) / (data.totalReqCnt || 1)) * 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.currentReqCnt || 0) / (data.totalReqCnt || 1)) * 100) / 20)]
"/>
</div>
<div
style="font-size: 14px;font-weight: 500;color: #277aff;margin-left: 10px;"
:style="{
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.currentReqCnt || 0) / (data.totalReqCnt || 1)) * 100) / 20)],
}">
{{ parseInt((data.currentReqCnt || 0) / (data.totalReqCnt || 1) * 100) }}%
</div>
</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>
</div>
</template>
<script setup>
import {computed, onMounted, ref} from "vue";
import circle from "@/assets/image/pathdetails/circle.png";
import circle2 from "@/assets/image/pathdetails/circle2.png";
import {request} from "@/api/request";
import {
STUDY_RECORD,
UPDATE_CURRENT_TASK,
QueryEvaluationTaskStatusOne,
EvaluationToLearn,
SubmitExternalExam
} from "@/api/api";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from "element-plus";
import {ROUTER, TASK_TYPES} from "@/api/CONST";
import FileTypeImg from "@/components/FileTypeImg.vue";
import {useStore} from "vuex";
const {
query: { routerId, routerName, isStudy, chapterId },
} = useRoute();
const router = useRouter();
const returnclick = () => {
router.back();
};
const { commit, dispatch, state } = useStore();
const userInfo = computed(() => state.userInfo);
const data = computed(() => state.routerInfo);
const activeName = ref("first");
onMounted(() => {
dispatch("getRouterInfo", { routerId, chapterId });
});
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 已结束)
console.log(type, endTimes, status);
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) {
if (data.value.unlockMode !== 1 && !d.statusName) {
ElMessage.warning("当前未解锁");
return;
}
if (data.value.endTime && judgeTaskIsEnd(d.type, data.value.endTime, data.value.status)) {
ElMessage.error("当前任务已结束");
return;
}
if (!TASK_TYPES.path[d.type]) {
ElMessage.error("暂时未开放");
return;
}
if (d.type == 2) {
if(!d.targetId){
return ElMessage.error("还未添加开课,请联系管理员!")
}
if(d.targetId.split(',').length>1){
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": 2,
"taskId": d.id,
"chapterId": data.value.currentStageId,
"externalId": d.courseId,
"externalName": d.name,
"targetId": routerId,
"studentNo": userInfo.value.userNo
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
router.push({
path: "/externalexamination",
query: {
id: d.id,
type: ROUTER,
infoId: routerId,
courseId: d.courseId,
pName: data.value.name,
sName: data.value.currentStageName,
chapterOrStageId: data.value.currentStageId,
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;
}
}
//更新学员当前任务
await request(UPDATE_CURRENT_TASK, { id: d.id, type: ROUTER, pid: routerId, 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.id,
logo: ROUTER,
type: ROUTER,
taskType: d.type,
stageOrChapterId: data.value.currentStageId,
taskId: d.id,
});
}
// 测评模块 请求接口跳转新的页面 - 新增 暂时未调试 目前无测评数据 2023-02-04
if (d.type == 10) {
if (d.quizTaskId == null) {
// 肯定没有完成测评
// 调用接口 跳转页面
console.log("我是查询测评跳转链接所传递得参数", {
"businessType": "learningpath",
"chapterId": data.value.currentStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": routerId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
});
request(EvaluationToLearn, {
"businessType": "learningpath",
"chapterId": data.value.currentStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": routerId,
"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": "learningpath",
"chapterId": data.value.currentStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": routerId,
"studentId": userInfo.value.id,
"studentName": userInfo.value.realName
});
request(EvaluationToLearn, {
"businessType": "learningpath",
"chapterId": data.value.currentStageId,
"courseId": d.courseId,
"quizKid": d.targetId,
"routerOrProjectId": routerId,
"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 (d.type == 13) {
// 此处判断跳转项目详情界面
router.push({
path: "/projectdetails",
query: {
projectId: d.courseId
},
});
return;
}
const path = typeof TASK_TYPES.path[d.type] === "string" ? TASK_TYPES.path[d.type] : TASK_TYPES.path[d.type](d);
path && path.startsWith("http") ? window.open(path + d.targetId, "_top") : path.startsWith("/") ?
router.push({
path,
query: {
id: d.id,
type: ROUTER,
infoId: routerId,
courseId: d.courseId,
pName: data.value.name,
sName: data.value.currentStageName,
chapterOrStageId: data.value.currentStageId,
btype: 2
},
}) : "";
}
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 + "-");
}
// 共享文档下载
function downloadFile(url) {
console.log(import.meta.env.VITE_FILE_PATH + url);
window.open(import.meta.env.VITE_FILE_PATH + url);
}
// 继续学习
function continueLearn(taskname, datas) {
console.log("我是当前的列表展示信息", data);
console.log(datas);
let jumpinfo;
for (let i = 0; i < datas.length; i++) {
if (datas[i].name == taskname) {
jumpinfo = datas[i];
}
}
console.log(jumpinfo);
toFinish(jumpinfo);
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
.pathdetails {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
}
.pdname {
font-size: 20px;
font-weight: 800;
color: #ffffff;
margin-top: 17px;
}
.detailinfo {
width: 100%;
margin-top: 24px;
display: flex;
z-index: 2;
.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>