Files
fe-student/src/views/growth/components/roadmap2/index.vue
Pengxiansen 6021687acc 提交
2025-02-19 14:04:39 +08:00

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>