mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/fe-student.git
synced 2025-12-10 11:26:49 +08:00
360 lines
6.7 KiB
Vue
360 lines
6.7 KiB
Vue
<template>
|
|
<div
|
|
style="transform-origin: top left; width: 1920px; height: 1122px"
|
|
class="roadmap"
|
|
>
|
|
<el-scrollbar height="1122px">
|
|
<div
|
|
class="path-container"
|
|
:style="{
|
|
height: `${Number(position(stageProcessList.length - 1).topNum) + 100}px`,
|
|
}"
|
|
>
|
|
<div
|
|
class="path-item"
|
|
@click="toFinish(item)"
|
|
:style="position(index)"
|
|
v-for="(item, index) of stageProcessList"
|
|
>
|
|
<template v-if="leftOfRight(index) === 'right'">
|
|
<div class="circle-right">
|
|
<div></div>
|
|
</div>
|
|
</template>
|
|
<div class="item-container">
|
|
<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>
|
|
</div>
|
|
<template v-if="leftOfRight(index) === 'left'">
|
|
<div class="circle-left">
|
|
<div></div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</el-scrollbar>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import { computed } from "vue";
|
|
const emit = defineEmits("toFinish");
|
|
const propas = defineProps({
|
|
stageProcessList: Array,
|
|
});
|
|
let left = [1, 2, 3, 7, 8, 11, 16, 17, 22, 25, 27, 30, 32];
|
|
let right = [
|
|
0, 4, 5, 6, 9, 10, 12, 13, 14, 15, 18, 19, 20, 21, 23, 24, 26, 28, 29, 31, 33,
|
|
34, 35,
|
|
];
|
|
const leftOfRight = (index) => {
|
|
if (left.includes(index % 35)) {
|
|
return "left";
|
|
}
|
|
if (right.includes(index % 35)) {
|
|
return "right";
|
|
}
|
|
};
|
|
const position = (index) => {
|
|
if (index < 0) {
|
|
return {
|
|
top: `0px`,
|
|
right: `0px`,
|
|
topNum: 0,
|
|
};
|
|
}
|
|
let num = index / 35;
|
|
// 获取倍数
|
|
let multiple = num < 1 ? 0 : Number(Math.floor(num));
|
|
|
|
let num2 = index % 35;
|
|
|
|
return {
|
|
top: `${multiple * (5613 + 400) + Number(point[num2].top)}px`,
|
|
right: `${point[num2].right}px`,
|
|
topNum: `${multiple * (5613 + 400) + Number(point[num2].top)}`,
|
|
};
|
|
};
|
|
|
|
const point = [
|
|
{
|
|
top: "-57",
|
|
right: "55",
|
|
},
|
|
{
|
|
top: "-1",
|
|
right: "709",
|
|
},
|
|
{
|
|
top: "108",
|
|
right: "1034",
|
|
},
|
|
{
|
|
top: "241",
|
|
right: "1021",
|
|
},
|
|
{
|
|
top: "281",
|
|
right: "521",
|
|
},
|
|
{
|
|
top: "446",
|
|
right: "176",
|
|
},
|
|
{
|
|
top: "561",
|
|
right: "435",
|
|
},
|
|
{
|
|
top: "598",
|
|
right: "1023",
|
|
},
|
|
{
|
|
top: "702",
|
|
right: "1452",
|
|
},
|
|
{
|
|
top: "902",
|
|
right: "1040",
|
|
},
|
|
{
|
|
top: "1102",
|
|
right: "540",
|
|
},
|
|
{
|
|
top: "1227",
|
|
right: "1140",
|
|
},
|
|
{
|
|
top: "1500",
|
|
right: "1640",
|
|
},
|
|
{
|
|
top: "1644",
|
|
right: "1200",
|
|
},
|
|
{
|
|
top: "1760",
|
|
right: "653",
|
|
},
|
|
{
|
|
top: "1872",
|
|
right: "202",
|
|
},
|
|
{
|
|
top: "2072",
|
|
right: "585",
|
|
},
|
|
{
|
|
top: "2131",
|
|
right: "1106",
|
|
},
|
|
{
|
|
top: "2340",
|
|
right: "1533",
|
|
},
|
|
{
|
|
top: "2545",
|
|
right: "1033",
|
|
},
|
|
{
|
|
top: "2627",
|
|
right: "597",
|
|
},
|
|
{
|
|
top: "2767",
|
|
right: "67",
|
|
},
|
|
{
|
|
top: "2946",
|
|
right: "767",
|
|
},
|
|
{
|
|
top: "3161",
|
|
right: "1184",
|
|
},
|
|
{
|
|
top: "3406",
|
|
right: "484",
|
|
},
|
|
{
|
|
top: "3679",
|
|
right: "-11",
|
|
},
|
|
{
|
|
top: "3830",
|
|
right: "322",
|
|
},
|
|
|
|
{
|
|
top: "3882",
|
|
right: "950",
|
|
},
|
|
{
|
|
top: "4049",
|
|
right: "1383",
|
|
},
|
|
{
|
|
top: "4249",
|
|
right: "492",
|
|
},
|
|
{
|
|
top: "4423",
|
|
right: "151",
|
|
},
|
|
{
|
|
top: "4744",
|
|
right: "501",
|
|
},
|
|
{
|
|
top: "4834",
|
|
right: "1101",
|
|
},
|
|
{
|
|
top: "5066",
|
|
right: "1490",
|
|
},
|
|
{
|
|
top: "5400",
|
|
right: "790",
|
|
},
|
|
{
|
|
top: "5613",
|
|
right: "50",
|
|
},
|
|
];
|
|
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",
|
|
};
|
|
}
|
|
};
|
|
});
|
|
</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%;
|
|
min-height: 200px;
|
|
margin-top: 100px;
|
|
margin-bottom: 50px;
|
|
background-image: url(@/assets/image/growth/path2.png);
|
|
background-size: 100%;
|
|
.path-item {
|
|
position: absolute;
|
|
|
|
display: flex;
|
|
align-items: flex-end;
|
|
cursor: pointer;
|
|
.item-container {
|
|
width: 220px;
|
|
}
|
|
.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;
|
|
}
|
|
.circle-left,
|
|
.circle-right {
|
|
width: 42px;
|
|
height: 42px;
|
|
background: rgba(64, 158, 255, 0.2);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
div {
|
|
width: 30px;
|
|
height: 30px;
|
|
background: #0077ec;
|
|
border-radius: 50%;
|
|
}
|
|
}
|
|
.circle-left {
|
|
margin-left: 30px;
|
|
}
|
|
.circle-right {
|
|
margin-right: 30px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|