This commit is contained in:
Pengxiansen
2025-02-26 00:00:32 +08:00
parent deba79c17d
commit 5f4ee8bee2
6 changed files with 158 additions and 436 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

View File

@@ -1,382 +0,0 @@
<template>
<div
style="transform-origin: top left; width: 1920px; height: 1122px"
class="roadmap"
>
<div class="path-container">
<div
:class="
(!((item.position + 1) % 2) || item.position === 0) &&
item.position !== 1
? 'path-item-top'
: 'path-item-bottom'
"
@click="toFinish(item)"
:style="point[item.position]"
v-for="(item, index) of stageProcessList"
>
<template v-if="item.position + 1 == 1">
<div style="display: flex">
<div>
<div>
<div class="item-name" style="width: 210px">
{{ item.taskName }}
</div>
<div class="triangle"></div>
</div>
<div class="f-a-c">
<div class="item-progress">
<el-progress
:percentage="parseInt(item.progress)"
:show-text="false"
:stroke-width="6"
:color="stateData(item).progressColor"
/>
</div>
<div
class="item-state"
:style="{
color: stateData(item).color,
background: stateData(item).bgColor,
}"
>
{{ stateData(item).text }}
</div>
</div>
</div>
<div class="item-link1" style="display: flex; align-items: center">
<div class="line1"></div>
<div class="circle1"></div>
</div>
</div>
</template>
<template v-else-if="(item.position + 1) % 2 || item.position === 1">
<div class="item-link">
<div class="circle"></div>
<div class="line"></div>
</div>
<div>
<div class="triangle"></div>
<div class="item-name">{{ item.taskName }}</div>
</div>
<div class="f-a-c" style="margin-top: 9px">
<div class="item-progress">
<el-progress
:percentage="parseInt(item.progress)"
:show-text="false"
:stroke-width="6"
:color="stateData(item).progressColor"
/>
</div>
<div
class="item-state"
:style="{
color: stateData(item).color,
background: stateData(item).bgColor,
}"
>
{{ stateData(item).text }}
</div>
</div>
</template>
<template v-else>
<div>
<div class="item-name">{{ item.taskName }}</div>
<div class="triangle"></div>
</div>
<div class="f-a-c">
<div class="item-progress">
<el-progress
:percentage="parseInt(item.progress)"
:show-text="false"
:stroke-width="6"
:color="stateData(item).progressColor"
/>
</div>
<div
class="item-state"
:style="{
color: stateData(item).color,
background: stateData(item).bgColor,
}"
>
{{ stateData(item).text }}
</div>
</div>
<div class="item-link">
<div class="line"></div>
<div class="circle"></div>
</div>
</template>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from "vue";
const emit = defineEmits("toFinish");
const propas = defineProps({
stageProcessList: Array,
});
const point = [
{
top: "-13px",
right: "258px",
},
{
top: "226px",
right: "128px",
},
{
top: "347px",
right: "341px",
},
{
top: "92px",
right: "455px",
},
{
top: "443px",
right: "561px",
},
{
top: "155px",
right: "673px",
},
{
top: "512px",
right: "780px",
},
{
top: "200px",
right: "893px",
},
{
top: "565px",
right: "1000px",
},
{
top: "232px",
right: "1111px",
},
{
top: "602px",
right: "1220px",
},
{
top: "254px",
right: "1331px",
},
{
top: "630px",
right: "1440px",
},
{
top: "267px",
right: "1551px",
},
{
top: "650px",
right: "1660px",
},
];
const toFinish = (item) => {
emit("toFinish", item);
};
const stateData = computed(() => {
return (item) => {
if (item.completionStatus === "10") {
return {
text: "未解锁",
color: "#666666",
bgColor: "rgba(102, 102, 102, 0.2)",
progressColor: "#AEB3B8",
};
} else if (item.completionStatus === "0") {
return {
text: "未开始",
color: "#666666",
bgColor: "rgba(102, 102, 102, 0.2)",
progressColor: "#AEB3B8",
};
} else if (item.completionStatus === "1") {
return {
text: "已完成",
color: "#0077EC",
bgColor: "rgba(0, 119, 236, 0.2)",
progressColor: "#0077EC",
};
} else if (item.completionStatus === "2") {
return {
text: "进行中",
color: "#F2903D",
bgColor: "rgba(242, 144, 61, 0.2)",
progressColor: "#F2903D",
};
} else if (item.completionStatus === "3") {
return {
text: "已结束",
color: "#666666",
bgColor: "rgba(102, 102, 102, 0.2)",
progressColor: "#AEB3B8",
};
}
};
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.f-a-c {
display: flex;
align-items: center;
}
.roadmap {
background-image: url(@/assets/image/growth/path-bg.png);
background-size: 100%;
background-repeat: no-repeat;
}
.path-container {
position: relative;
width: 100%;
height: 659px;
margin-top: 53px;
background-image: url(@/assets/image/growth/path.png);
.path-item-bottom {
position: absolute;
width: 210px;
cursor: pointer;
.item-progress {
flex: 1;
}
.item-state {
width: 64px;
height: 24px;
border-radius: 6px;
text-align: center;
line-height: 24px;
margin-left: 5px;
}
.item-name {
display: inline-block;
max-width: 210px;
min-width: 80px;
background: linear-gradient(268deg, #3c65f5 0%, #4395f9 100%);
border-radius: 7px;
font-size: 16px;
color: #ffffff;
padding: 14px 10px 14px 15px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.triangle {
width: 0px;
height: 0px;
border: 7px solid transparent;
border-bottom-color: #4391f8;
margin-left: 32px;
padding-top: 10px;
}
.item-link {
position: relative;
.line {
width: 2px;
height: 138px;
margin-left: 39px;
background: linear-gradient(180deg, #ffffff 0%, #0077ec 65%);
border-image: linear-gradient(180deg, #ffffff, #0077ec) 10 10;
}
.circle {
width: 14px;
height: 14px;
background: #ffffff;
border-radius: 50%;
border: 3px solid #0077ec;
position: absolute;
top: 0;
left: 30px;
}
}
}
.path-item-top {
position: absolute;
width: 210px;
cursor: pointer;
.item-progress {
flex: 1;
}
.item-state {
width: 64px;
height: 24px;
border-radius: 6px;
text-align: center;
line-height: 24px;
margin-left: 5px;
}
.item-name {
max-width: 210px;
min-width: 80px;
display: inline-block;
background: linear-gradient(268deg, #3c65f5 0%, #4395f9 100%);
border-radius: 7px;
font-size: 16px;
color: #ffffff;
padding: 14px 10px 14px 15px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.triangle {
width: 0px;
height: 0px;
border: 7px solid transparent;
border-top-color: #4391f8;
margin-left: 32px;
}
.item-link1 {
margin-top: 14px;
height: 20px;
.line1 {
width: 135px;
height: 2px;
background: linear-gradient(-90deg, #ffffff 0%, #0077ec 65%);
border-image: linear-gradient(-90deg, #ffffff, #0077ec) 10 10;
}
.circle1 {
width: 14px;
height: 14px;
background: #ffffff;
border-radius: 50%;
border: 3px solid #0077ec;
}
}
.item-link {
position: relative;
.line {
margin-left: 39px;
width: 2px;
height: 210px;
background: linear-gradient(0deg, #ffffff 0%, #0077ec 65%);
border-image: linear-gradient(0deg, #ffffff, #0077ec) 10 10;
}
.circle {
width: 14px;
height: 14px;
background: #ffffff;
border-radius: 50%;
border: 3px solid #0077ec;
position: absolute;
bottom: 0;
left: 30px;
}
}
}
}
</style>

View File

@@ -20,7 +20,24 @@
<div>
<div>
<div class="item-name" style="width: 210px">
{{ item.taskName }}
<div
style="
display: inline-block;
border-radius: 50%;
line-height: 18px;
text-align: center;
margin-right: 6px;
width: 18px;
height: 18px;
font-size: 12px;
font-weight: 700;
background-color: #fff;
color: #0077ec;
"
>
{{ stageProcessList.length - index }}
</div>
<div style="display: inline">{{ item.taskName }}</div>
</div>
<div class="triangle"></div>
</div>
@@ -61,7 +78,26 @@
</div>
<div>
<div class="triangle"></div>
<div class="item-name">{{ item.taskName }}</div>
<div class="item-name">
<div
style="
display: inline-block;
border-radius: 50%;
line-height: 18px;
text-align: center;
margin-right: 6px;
width: 18px;
height: 18px;
font-size: 12px;
font-weight: 700;
background-color: #fff;
color: #0077ec;
"
>
{{ stageProcessList.length - index }}
</div>
<div style="display: inline">{{ item.taskName }}</div>
</div>
</div>
<div class="f-a-c" style="margin-top: 9px">
<div class="item-progress">
@@ -87,7 +123,26 @@
<template v-else>
<div>
<div class="item-name">{{ item.taskName }}</div>
<div class="item-name">
<div
style="
display: inline-block;
border-radius: 50%;
line-height: 18px;
text-align: center;
margin-right: 6px;
width: 18px;
height: 18px;
font-size: 12px;
font-weight: 700;
background-color: #fff;
color: #0077ec;
"
>
{{ stageProcessList.length - index }}
</div>
<div style="display: inline">{{ item.taskName }}</div>
</div>
<div class="triangle"></div>
</div>
<div class="f-a-c">
@@ -113,7 +168,7 @@
<div class="item-link">
<div
class="line"
:style="{ height: point[item.position].height }"
:style="{ height: point[item.position]?.height }"
></div>
<div class="circle"></div>
</div>

View File

@@ -7,7 +7,9 @@
<div
class="path-container"
:style="{
height: `${Number(position(stageProcessList.length - 1).topNum) + 65}px`,
height: `${
Number(position(stageProcessList.length - 1).topNum) + 65
}px`,
}"
>
<div
@@ -23,7 +25,26 @@
</template>
<div class="item-container">
<div>
<div class="item-name">{{ item.taskName }}</div>
<div class="item-name">
<div
style="
display: inline-block;
border-radius: 50%;
line-height: 18px;
text-align: center;
margin-right: 6px;
width: 18px;
height: 18px;
font-size: 12px;
font-weight: 700;
background-color: #fff;
color: #0077ec;
"
>
{{ stageProcessList.length - index }}
</div>
<div style="display: inline">{{ item.taskName }}</div>
</div>
</div>
<div class="f-a-c" style="margin-top: 9px">
<div class="item-progress">
@@ -244,7 +265,7 @@ const point = [
},
];
const toFinish = (item) => {
emit("toFinish", item);
emit("toFinish", item);
};
const stateData = computed(() => {
return (item) => {
@@ -276,7 +297,7 @@ const stateData = computed(() => {
bgColor: "rgba(242, 144, 61, 0.2)",
progressColor: "#F2903D",
};
}else if (item.completionStatus === "3") {
} else if (item.completionStatus === "3") {
return {
text: "已结束",
color: "#666666",

View File

@@ -64,8 +64,7 @@
/>
<el-button
icon="Search"
style="margin-left: 20px"
type="primary"
style="margin-left: 20px; background-color: #0077ec; color: #fff"
@click="getList"
>搜索</el-button
>
@@ -84,15 +83,16 @@
<div style="display: flex">
<template v-if="stageProcessList && stageProcessList.length">
<div class="growth-list-content" v-loading="loading">
<div class="growth-list-content">
<el-row>
<el-col :span="24" v-for="(value, index) in stageProcessList">
<div class="list-item">
<div class="item-img">
<img
style="width: 100%; height: 100%"
style="width: 110%; height: 110%"
:src="getAssetsFile(value.courseType)"
/>
<div class="item-img-icon">{{ index + 1 }}</div>
</div>
<div class="item-content">
<div>
@@ -394,7 +394,7 @@
</template>
<script setup>
import { computed, onMounted, ref, watch, reactive } from "vue";
import { ElMessage } from "element-plus";
import { ElMessage, ElLoading } from "element-plus";
import { request } from "@/api/request";
import { growthRequest } from "@/api/growthRequest";
import {
@@ -410,7 +410,7 @@ import { useRoute, useRouter } from "vue-router";
import { GROWTH, TASK_TYPES } from "@/api/CONST";
import { useStore } from "vuex";
const {
query: { courseId, routerId },
query: { type, routerId },
} = useRoute();
const router = useRouter();
@@ -476,6 +476,7 @@ const templateClick = () => {
path: "/growthRoadmap",
query: {
routerId: selectGrowth.value.id,
type: queryParams.type,
},
});
};
@@ -503,8 +504,7 @@ const refresh = () => {
queryParams.completionStatus = "";
getList();
};
// 是否加载数据中
const loading = ref(false);
const getList = () => {
let params = {
growthId: selectGrowth.value.id ? selectGrowth.value.id : routerId,
@@ -514,12 +514,15 @@ const getList = () => {
if (params.completionStatus == 3) {
params.completionStatus = "";
}
loading.value = true;
growthRequest(PROFESSIONAL_STUDENT_TASKLIST, params).then((res) => {
console.log(res);
stageProcessList.value = res.data;
loading.value = false;
});
// 是否加载数据中
const loading = ElLoading.service({ fullscreen: true });
growthRequest(PROFESSIONAL_STUDENT_TASKLIST, params)
.then((res) => {
stageProcessList.value = res.data;
})
.finally(() => {
loading.close();
});
};
// 专业力必修列表
const growthList = ref([]);
@@ -534,6 +537,9 @@ const select = (item) => {
};
onMounted(() => {
dispatch("getGrowthInfo", { routerId });
if (type) {
queryParams.type = type;
}
getList();
growthRequest(PROFESSIONAL_STUDENT_LIST).then((res) => {
growthList.value = res.data;
@@ -985,8 +991,10 @@ function toOffcoursePlanPage(item) {
border: 2px solid #f5f5f5;
.list-item {
display: flex;
padding: 29px 0;
border-bottom: 1px solid #d3e3f2;
padding: 40px 0;
// border-bottom: 1px solid #d3e3f2;
border-bottom: 3px #d3e3f2 dashed;
// width: 425px;
}
.item-button {
@@ -1017,7 +1025,22 @@ function toOffcoursePlanPage(item) {
width: 24%;
border-radius: 14px;
overflow: hidden;
position: relative;
.item-img-icon {
display: flex;
justify-content: center;
padding-top: 3px;
position: absolute;
color: #fff;
font-size: 20px;
box-sizing: border-box;
top: 0;
left: 10px;
background-image: url(@/assets/image/growth/listJiaoBiao.png);
background-size: 100% 100%;
width: 27px;
height: 37px;
}
img:hover {
transform: scale(1.1);
transition: all 1s ease;

View File

@@ -25,7 +25,6 @@
</template>
</el-dropdown>
</div>
<template v-if="selectGrowth.template == 1">
<el-affix :offset="0">
<div class="nav">
@@ -89,7 +88,6 @@
<div
:style="{ transform: 'scale(' + transformSize + ')' }"
style="transform-origin: top left"
v-loading="loading"
>
<template v-if="selectGrowth.template == 1">
<Roadmap2
@@ -151,8 +149,7 @@
/>
<el-button
icon="Search"
style="margin-left: 20px"
type="primary"
style="margin-left: 20px; background-color: #0077ec; color: #fff"
@click="getList"
>搜索</el-button
>
@@ -173,7 +170,6 @@
<div
:style="{ transform: 'scale(' + transformSize + ')' }"
style="transform-origin: top left"
v-loading="loading"
>
<template v-if="selectGrowth.template == 1">
<Roadmap2
@@ -194,6 +190,7 @@
</template>
</div>
</template>
<!-- 弹框提示信息 -->
<el-dialog
title=""
@@ -285,7 +282,7 @@
</template>
<script setup>
import { computed, onMounted, onUnmounted, ref, watch, reactive } from "vue";
import { ElMessage } from "element-plus";
import { ElMessage, ElLoading } from "element-plus";
import { request } from "@/api/request";
import { growthRequest } from "@/api/growthRequest";
import Roadmap1 from "./components/roadmap1/index.vue";
@@ -303,7 +300,7 @@ import { useRoute, useRouter } from "vue-router";
import { GROWTH, TASK_TYPES } from "@/api/CONST";
import { useStore } from "vuex";
const {
query: { courseId, routerId },
query: { type, routerId },
} = useRoute();
const router = useRouter();
@@ -326,6 +323,7 @@ const templateClick = () => {
path: "/growthList",
query: {
routerId: selectGrowth.value.id,
type: queryParams.type,
},
});
};
@@ -355,7 +353,6 @@ const refresh = () => {
const stageProcessList = ref([]);
// 是否加载数据中
const loading = ref(false);
const getList = () => {
let params = {
growthId: selectGrowth.value.id ? selectGrowth.value.id : routerId,
@@ -365,27 +362,31 @@ const getList = () => {
if (params.completionStatus == 3) {
params.completionStatus = "";
}
loading.value = true;
growthRequest(PROFESSIONAL_STUDENT_TASKLIST, params).then((res) => {
if (selectGrowth.value.template === "1") {
stageProcessList.value = res.data.reverse();
} else {
let newData = res.data.slice(0, 15).reverse();
// 默认第一个在第一点位
// let num = Number((15 / newData.length).toFixed(0));
// // 默认第一个在第一点位
let num = 15 / newData.length;
stageProcessList.value = newData.map((item, index) => {
// 是否加载数据中
const loading = ElLoading.service({ fullscreen: true });
growthRequest(PROFESSIONAL_STUDENT_TASKLIST, params)
.then((res) => {
if (selectGrowth.value.template === "1") {
stageProcessList.value = res.data.reverse();
} else {
let newData = res.data.slice(0, 15).reverse();
// 默认第一个在第一点位
if (index === 0) {
item.position = 0;
}
item.position = Number(Math.round(index * num));
return item;
});
}
loading.value = false;
});
// let num = Number((15 / newData.length).toFixed(0));
// // 默认第一个在第一点位
let num = 15 / newData.length;
stageProcessList.value = newData.map((item, index) => {
// 默认第一个在第一点位
if (index === 0) {
item.position = 0;
}
item.position = Number(Math.round(index * num));
return item;
});
}
})
.finally(() => {
loading.close();
});
};
// 专业力必修列表
const growthList = ref([]);
@@ -402,6 +403,9 @@ onMounted(() => {
updateWindowWidth(); // 初始化宽度
window.addEventListener("resize", updateWindowWidth);
dispatch("getGrowthInfo", { routerId });
if (type) {
queryParams.type = type;
}
getList();
growthRequest(PROFESSIONAL_STUDENT_LIST).then((res) => {
growthList.value = res.data;
@@ -445,7 +449,7 @@ async function toFinish(d) {
ElMessage.warning(`请先完成“${d.superTaskName}”的学习任务`);
return;
}
if (!d.canLearn && d.completionStatus === '0') {
if (!d.canLearn) {
ElMessage.warning(`学习任务暂未开始`);
return;
}
@@ -744,6 +748,7 @@ function toOffcoursePlanPage(item) {
}
.growth-path-container {
background-color: #ffffff;
min-height: 400px;
}
.growth-type {