Files
learning-system-portal/src/views/growth/index.vue
Pengxiansen 15e15ae5d2 提交
2025-02-16 23:22:01 +08:00

367 lines
10 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 class="growth" v-loading="loading" id="scrollContainer">
<div class="growth-left">
<div class="navbar">
<div style="display: flex; flex: 1">
<div class="nav-title">我的专业力必修</div>
<div class="nav-total">
<div class="total-num">{{ totalData.total }}</div>
<div class="total-text">总任务数</div>
</div>
<div class="nav-total">
<div class="total-num">{{ totalData.completed }}</div>
<div class="total-text">已完成数量</div>
</div>
<div class="nav-total">
<div class="total-num">{{ totalData.unfinished }}</div>
<div class="total-text">未完成数量</div>
</div>
</div>
</div>
<div class="growth-item" v-for="item of list" :id="item.id">
<div class="growth-nav">
<div class="growth-name">{{ item.growthName }}</div>
<div class="f-a-c">
<div
class="growth-state"
:style="{
color:
item.learningState === 0
? '#999999'
: item.learningState === 1
? '#6ba158'
: '#F2903D',
}"
>
{{
item.learningState === 0
? "未开始"
: item.learningState === 1
? "已完成"
: "进行中"
}}
</div>
<div class="growth-btn" @click="jumpRouter(item)">去学习</div>
</div>
</div>
<div class="tip-title">说明</div>
<div class="tip-content">
{{ item.description || "暂无说明" }}
</div>
<div class="progress-title">学习进度</div>
<div class="progress-content">
<div class="f-j-b" style="margin-bottom: 10px">
<div class="f-a-c">
<div style="font-weight: 700; font-size: 16px; color: #333333">
必修进度
</div>
<div style="font-size: 20px; color: #999999; margin-left: 12px">
{{ item.requiredTaskCompletedNum }}/{{ item.requiredTaskNum }}
</div>
</div>
<div style="font-weight: bold; font-size: 24px; color: #0077ec">
{{ requiredTaskCompletionRate(item) }}%
</div>
</div>
<el-progress
:stroke-width="8"
:show-text="false"
:percentage="requiredTaskCompletionRate(item)"
></el-progress>
</div>
<div class="progress-content">
<div class="f-j-b" style="margin-bottom: 10px">
<div class="f-a-c">
<div style="font-weight: 700; font-size: 16px; color: #333333">
选修进度
</div>
<div style="font-size: 20px; color: #999999; margin-left: 12px">
{{ item.electiveTaskCompletedNum }}/{{ item.electiveTaskNum }}
</div>
</div>
<div style="font-weight: bold; font-size: 24px; color: #0077ec">
{{ electiveTaskCompletionRate(item) }}%
</div>
</div>
<el-progress
:stroke-width="8"
:show-text="false"
:percentage="electiveTaskCompletionRate(item)"
></el-progress>
</div>
<div class="progress-content">
<div class="f-j-b" style="margin-bottom: 10px">
<div class="f-a-c">
<div style="font-weight: 700; font-size: 16px; color: #333333">
总进度
</div>
<div style="font-size: 20px; color: #999999; margin-left: 12px">
{{ item.totalTaskCompletedNum }}/{{ item.totalTaskNum }}
</div>
</div>
<div style="font-weight: bold; font-size: 24px; color: #0077ec">
{{ totalTaskCompletionRate(item) }}%
</div>
</div>
<el-progress
:stroke-width="8"
:show-text="false"
:percentage="totalTaskCompletionRate(item)"
></el-progress>
</div>
</div>
</div>
<div class="growth-right">
<div class="title">专业力必修</div>
<div
:key="item.id"
class="item-growth"
:class="activeItem.id == item.id ? 'active' : ''"
v-for="item of list"
>
<div class="icon"></div>
<div @click="handlerAnchor(item)">
{{ item.growthName }}
</div>
</div>
</div>
<template v-if="!list.length">
<el-empty :image-size="200"></el-empty>
</template>
</div>
</template>
<script>
import { listData, getTotalGrowthTaskDetail } from "@/api/growth/growthpath";
export default {
data() {
return {
list: [],
loading: false,
totalData: {},
activeItem: {},
};
},
computed: {
// 完成进度
totalTaskCompletionRate() {
return (item) => {
if (item.totalTaskCompletedNum && item.totalTaskNum) {
let num = item.totalTaskCompletedNum / item.totalTaskNum;
num = num * 100;
num = num.toFixed(0);
return Number(num);
} else {
return 0;
}
};
},
// 选修进度
electiveTaskCompletionRate() {
return (item) => {
if (item.electiveTaskCompletedNum && item.electiveTaskNum) {
let num = item.electiveTaskCompletedNum / item.electiveTaskNum;
num = num * 100;
num = num.toFixed(0);
return Number(num);
} else {
return 0;
}
};
},
// 必修进度
requiredTaskCompletionRate() {
return (item) => {
if (item.requiredTaskCompletedNum && item.requiredTaskNum) {
let num = item.requiredTaskCompletedNum / item.requiredTaskNum;
num = num * 100;
num = num.toFixed(0);
return Number(num);
} else {
return 0;
}
};
},
},
methods: {
select(item) {},
jumpRouter(item) {
let studentPath = process.env.VUE_APP_STUDENT_PATH;
let params = encodeURIComponent("routerId=" + item.id);
this.$router.push(
"/forward?to=" + studentPath + "/growthList&params=" + params
);
},
handlerAnchor(item, index) {
this.activeItem = item;
let a = document.createElement("a");
a.href = `#${item.id}`;
document.body.appendChild(a); //将标签DOM放置页面
let dom = document.getElementById(`${item.id}`);
dom.classList.add("handler-add-padding");
a.click();
document.body.removeChild(a);
},
},
created() {
this.loading = true;
listData().then((res) => {
this.activeItem = res.data[0];
this.list = res.data;
this.loading = false;
});
getTotalGrowthTaskDetail().then((res) => {
this.totalData = res.data;
});
// 处理滚动事件的代码
let that = this;
window.addEventListener("scroll", function () {
let dom = document.getElementById(`${that.activeItem.id}`);
dom.classList.remove("handler-add-padding");
});
},
};
</script>
<style lang="less" scoped>
.f-a-c {
display: flex;
align-items: center;
}
.f-j-b {
display: flex;
justify-content: space-between;
}
.f-j-c {
display: flex;
justify-content: center;
}
.growth {
.handler-add-padding {
padding: 100px 38px 66px 40px !important;
margin-top: -80px;
}
display: flex;
.growth-left {
margin-right: 10px;
flex: 1;
.growth-item {
background: #ffffff;
padding: 30px 38px 66px 40px;
margin-bottom: 35px;
.progress-title {
font-weight: 700;
font-size: 20px;
color: #000000;
margin: 28px 0 20px 0;
}
.progress-content {
margin-bottom: 28px;
}
.tip-title {
font-weight: 700;
font-size: 20px;
color: #000000;
margin: 30px 0 10px 0;
}
.tip-content {
font-weight: 700;
font-size: 14px;
color: #333333;
line-height: 40px;
}
.growth-nav {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 28px;
border-bottom: 2px solid #f5f5f5;
}
.growth-name {
font-weight: 500;
font-size: 18px;
color: #0071ed;
}
.growth-state {
font-size: 14px;
margin-right: 18px;
}
.growth-btn {
display: flex;
justify-content: center;
align-items: center;
width: 120px;
height: 36px;
background: #f2903d;
border-radius: 4px;
font-size: 16px;
color: #ffffff;
cursor: pointer;
}
}
.navbar {
display: flex;
align-items: center;
height: 130px;
padding-left: 40px;
margin-bottom: 10px;
color: #ffffff;
background-image: url(../../assets/images/growth/growth-bg.png);
.nav-title {
font-weight: 700;
font-size: 24px;
margin-right: 10%;
}
.nav-total {
// margin-left: 15%;
width: 20%;
}
.total-num {
font-weight: bold;
font-size: 24px;
}
}
}
.growth-right {
width: 30%;
max-width: 464px;
margin-bottom: 35px;
background-color: #ffffff;
padding: 35px 20px 20px 30px;
.title {
font-size: 18px;
color: #000000;
font-weight: 700;
margin-bottom: 30px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-growth {
display: flex;
align-items: center;
border-radius: 5px;
font-size: 14px;
color: #666666;
padding: 10px 20px 10px 8px;
cursor: pointer;
}
.icon {
width: 4px;
height: 4px;
background: #4c5564;
border-radius: 50%;
margin-right: 10px;
}
.active {
background: #e3edfe;
color: #000;
.icon {
background: #0077ec;
}
}
}
}
</style>