feat: 动画优化
parent
21da1b661a
commit
545731d6d5
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -86,6 +86,7 @@ const percentage = computed(() => {
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 10px 1px var(--progress-start-color);
|
||||
z-index: auto;
|
||||
|
||||
// 条纹效果
|
||||
&::before {
|
||||
|
|
@ -98,7 +99,7 @@ const percentage = computed(() => {
|
|||
background-image: v-bind('props.striped ? "linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)" : "none"');
|
||||
background-size: 40px 40px;
|
||||
opacity: 0.6;
|
||||
z-index: 1;
|
||||
z-index: auto;
|
||||
animation: v-bind('props.animated && props.striped ? "progress-animation 2s linear infinite" : "none"');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ onUnmounted(() => {
|
|||
position: absolute;
|
||||
background-color: var(--color-led-off);
|
||||
border-radius: var(--segment-spacing);
|
||||
|
||||
z-index: auto;
|
||||
&-on {
|
||||
background-color: var(--color-led);
|
||||
// box-shadow: 0 0 var(--glow-radius) var(--color-glow);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,15 @@
|
|||
.text-color{
|
||||
background: linear-gradient(90deg, #8FC8FF 0%, #FFFFFF 100%);
|
||||
position: relative;
|
||||
color: #8FC8FF;
|
||||
&::after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: auto;
|
||||
color: #fff;
|
||||
-webkit-mask: linear-gradient(to bottom, transparent, #000);
|
||||
white-space: nowrap;
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +1,62 @@
|
|||
<template>
|
||||
<div class="h-[358px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">咨询学段<span class="text-[14px]">(已标记)</span></div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[255px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerRightSvg" class="w-[669px] h-[36px]" />
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px]">
|
||||
<AskSectionChart :chart-data="askSectionData.stages || []" />
|
||||
<div class="h-[358px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[255px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[669px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="ml-[9px] font-700 flex items-baseline">
|
||||
<span class="text-[20px] text-color" data-text="咨询学段">咨询学段</span>
|
||||
<span class="text-[14px] text-color" data-text="(已标记)">(已标记)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SvgComponent from "@/components/SvgComponent.vue";
|
||||
import AskSectionChart from "@/views/components/chartsComponents/AskSectionChart.vue";
|
||||
|
||||
const headerLeftSvg = ref("");
|
||||
const headerRightSvg = ref("");
|
||||
|
||||
const getHeaderLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-left.svg?raw");
|
||||
headerLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const getHeaderRightSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-right.svg?raw");
|
||||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/arrow-left.svg?raw");
|
||||
arrowLeftSvg.value = svg;
|
||||
};
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px]">
|
||||
<AskSectionChart :chart-data="askSectionData.stages || []" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
const askSectionData = inject("askSectionData",ref({stages:[]}))
|
||||
<script setup lang="ts">
|
||||
import SvgComponent from "@/components/SvgComponent.vue";
|
||||
import AskSectionChart from "@/views/components/chartsComponents/AskSectionChart.vue";
|
||||
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
border-image-outset: 0px 0px 0px 0px;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("src/assets/svg-img/border-image.png");
|
||||
border-style: solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
const headerLeftSvg = ref("");
|
||||
const headerRightSvg = ref("");
|
||||
|
||||
const getHeaderLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-left.svg?raw");
|
||||
headerLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const getHeaderRightSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-right.svg?raw");
|
||||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/arrow-left.svg?raw");
|
||||
arrowLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const askSectionData = inject("askSectionData", ref({ stages: [] }));
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
border-image-outset: 0px 0px 0px 0px;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("src/assets/svg-img/border-image.png");
|
||||
border-style: solid;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
<template>
|
||||
<div class="border-container">
|
||||
<div class="border-glow"></div>
|
||||
<div class="border-inner p-[2px]">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "BackgroundColor",
|
||||
data() {
|
||||
return {
|
||||
animationFrame: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.startAnimation();
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.animationFrame) {
|
||||
cancelAnimationFrame(this.animationFrame);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startAnimation() {
|
||||
const borderGlow = document.querySelector(".border-glow");
|
||||
let angle = 0;
|
||||
|
||||
const animate = () => {
|
||||
angle = (angle + 1) % 360;
|
||||
if (borderGlow) {
|
||||
borderGlow.style.background = `conic-gradient(
|
||||
from ${angle}deg,
|
||||
hsla(0, 0%, 0%, 0.25),
|
||||
hsla(214, 60%, 34%, 0.2),
|
||||
hsla(220, 74%, 35%, 0.1),
|
||||
hsla(219, 100%, 58%, 0.1),
|
||||
hsla(219, 100%, 58%, 0.2),
|
||||
hsla(219, 100%, 58%, 0.5),
|
||||
hsla(219, 100%, 58%, 0)
|
||||
)`;
|
||||
}
|
||||
this.animationFrame = requestAnimationFrame(animate);
|
||||
};
|
||||
|
||||
animate();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.border-container {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.border-glow {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
background: conic-gradient(
|
||||
from 0deg,
|
||||
hsla(0, 0%, 0%, 0.25),
|
||||
hsla(214, 60%, 34%, 0.2),
|
||||
hsla(220, 74%, 35%, 0.1),
|
||||
hsla(219, 100%, 58%, 0.1),
|
||||
hsla(219, 100%, 58%, 0.2),
|
||||
hsla(219, 100%, 58%, 0.5),
|
||||
hsla(219, 100%, 58%, 0)
|
||||
);
|
||||
border-radius: inherit;
|
||||
filter: blur(2px);
|
||||
pointer-events: none;
|
||||
mix-blend-mode: plus-lighter;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.border-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0.5px solid hsla(236, 100%, 66%, 0.48);
|
||||
border-radius: inherit;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 内容区域样式 */
|
||||
.border-container > :not(.border-glow):not(.border-inner) {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,17 +1,15 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">收费排行榜</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-color text-[20px] ml-[9px] font-700" data-text="收费排行榜">收费排行榜</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col relative">
|
||||
<div class="absolute right-[0] flex items-center justify-end mr-[13px] transform-translate-y-[-50%]">
|
||||
<div class="w-[296px] h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<div class="flex items-center justify-end mr-[13px] transform-translate-y-[-50%] h-0">
|
||||
<div class="text-[15px] text-[#84E8FF]">更多</div>
|
||||
<SvgComponent :content="moreArrowSvg" class="w-[14px] h-[22px]" />
|
||||
</div>
|
||||
|
|
@ -55,15 +53,15 @@
|
|||
watch(
|
||||
() => chargingRankingData.value,
|
||||
() => {
|
||||
initData()
|
||||
initData();
|
||||
},
|
||||
);
|
||||
|
||||
const initData = () => {
|
||||
if(chargingRankingData.value.paymentRanks){
|
||||
products.value = chargingRankingData.value.paymentRanks
|
||||
}
|
||||
}
|
||||
if (chargingRankingData.value.paymentRanks) {
|
||||
products.value = chargingRankingData.value.paymentRanks;
|
||||
}
|
||||
};
|
||||
|
||||
const headerLeftSvg = ref("");
|
||||
const headerRightSvg = ref("");
|
||||
|
|
@ -124,6 +122,7 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<div class="w-[144px]">
|
||||
<div class="relative w-[144px] h-[113px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">今日获客</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic">{{ gainData.toDayAcq || 0 }}</span>
|
||||
<span class="text-[18px]">人</span>
|
||||
<div class="leading-[1] flex items-baseline mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic text-color" :data-text="gainData.toDayAcq || 0">{{ gainData.toDayAcq || 0 }}</span>
|
||||
<span class="text-[18px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<SvgComponent :content="hexagonalBoxSvg" class="box-light absolute" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<div class="w-[144px]">
|
||||
<div class="relative w-[144px] h-[113px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">总获客</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic">{{gainData.acqTotal}}</span>
|
||||
<span class="text-[18px]">人</span>
|
||||
<div class="leading-[1] flex items-baseline mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic text-color" :data-text="gainData.acqTotal || 0">{{gainData.acqTotal || 0}}</span>
|
||||
<span class="text-[18px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<SvgComponent :content="hexagonalBoxSvg" class="box-light absolute" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<div class="w-[144px]">
|
||||
<div class="relative w-[144px] h-[113px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">今日流失</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic">{{ gainData.toDayOutFlow || 0 }}</span>
|
||||
<span class="text-[18px]">人</span>
|
||||
<div class="leading-[1] flex items-baseline mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic text-color" :data-text="gainData.toDayOutFlow || 0">{{ gainData.toDayOutFlow || 0 }}</span>
|
||||
<span class="text-[18px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<SvgComponent :content="hexagonalBoxSvg" class="box-light absolute" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,20 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">线下详情</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-[20px] ml-[9px] font-700 text-color" data-text="线下详情">线下详情</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<div class="ml-[22px] relative mt-[13px]">
|
||||
<div class="flex items-center justify-center">
|
||||
<ProportionCharts :chart-data="chartData" class="z-2 relative" />
|
||||
<SvgComponent :content="paymentChartSvg" class="w-[143px] h-[143px] absolute top-0 left-[50%] z-1 transform-translate-x-[-50%]" />
|
||||
</div>
|
||||
<div class="ml-[22px] relative mt-[13px] flex items-center justify-center">
|
||||
<ProportionCharts :chart-data="chartData" class="" />
|
||||
<div class="leading-[1] absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] z-3 flex items-center flex-col font-700 italic">
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent flex items-baseline">
|
||||
<div class="text-[25px]">{{ offlineTotal }}</div>
|
||||
<div class="text-[20px]">人</div>
|
||||
<div class="flex items-baseline">
|
||||
<div class="text-[25px] text-color" :data-text="offlineTotal">{{ offlineTotal }}</div>
|
||||
<div class="text-[20px] text-color" data-text="人">人</div>
|
||||
</div>
|
||||
<div class="text-[#FFFFFF] text-[16px] text-shadow-[0px_2px_2px_rgba(12,32,72,0.42)] mt-[7px]">线下</div>
|
||||
</div>
|
||||
|
|
@ -57,11 +52,6 @@
|
|||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const paymentChartSvg = ref("");
|
||||
const getPaymentChartSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/payment-chart.svg?raw");
|
||||
paymentChartSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
|
|
@ -98,13 +88,13 @@
|
|||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
getPaymentChartSvg();
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/custom-border.scss";
|
||||
@use "@/styles/text-color.scss";
|
||||
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,20 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">线上详情</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-color text-[20px] ml-[9px] font-700" data-text="线上详情">线上详情</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<div class="ml-[22px] relative mt-[13px]">
|
||||
<div class="flex items-center justify-center">
|
||||
<ProportionCharts :chart-data="chartData" class="z-2 relative" />
|
||||
<SvgComponent :content="paymentChartSvg" class="w-[143px] h-[143px] absolute top-0 left-[50%] z-1 transform-translate-x-[-50%]" />
|
||||
</div>
|
||||
<div class="ml-[22px] relative mt-[13px] flex items-center justify-center">
|
||||
<ProportionCharts :chart-data="chartData" class="" />
|
||||
<div class="leading-[1] absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] z-3 flex items-center flex-col font-700 italic">
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent flex items-baseline">
|
||||
<div class="text-[25px]">{{ onlineTotal }}</div>
|
||||
<div class="text-[20px]">人</div>
|
||||
<div class="flex items-baseline">
|
||||
<div class="text-[25px] text-color" :data-text="onlineTotal">{{ onlineTotal }}</div>
|
||||
<div class="text-[20px] text-color" data-text="人">人</div>
|
||||
</div>
|
||||
<div class="text-[#FFFFFF] text-[16px] text-shadow-[0px_2px_2px_rgba(12,32,72,0.42)] mt-[7px]">线上</div>
|
||||
</div>
|
||||
|
|
@ -57,11 +52,6 @@
|
|||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const paymentChartSvg = ref("");
|
||||
const getPaymentChartSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/payment-chart.svg?raw");
|
||||
paymentChartSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
|
|
@ -98,7 +88,6 @@
|
|||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
getPaymentChartSvg();
|
||||
|
||||
initData();
|
||||
});
|
||||
|
|
@ -106,6 +95,7 @@
|
|||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/custom-border.scss";
|
||||
@use "@/styles/text-color.scss";
|
||||
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
<template>
|
||||
<div class="h-[358px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">经营趋势</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[255px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[255px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[669px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center flex leading-[30px] items-baseline">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-[20px] ml-[9px] font-700 text-color" data-text="经营趋势">经营趋势</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px]">
|
||||
<OperatingTrendsChart :chartDataArray="acqTrend" @date-change="handleDateChange" />
|
||||
|
|
@ -70,6 +68,8 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<div class="w-[216px]">
|
||||
<div class="relative w-[154px] h-[124px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">总缴费</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent mb-[15px] z-10 font-700">
|
||||
<span class="text-[40px] italic">{{paymentData.chargeTotal}}</span>
|
||||
<span class="text-[20px]">人</span>
|
||||
<div class="mb-[15px] z-10 font-700 leading-[1] flex items-baseline">
|
||||
<span class="text-[40px] italic text-color" :data-text="`${paymentData.chargeTotal || 0}`">{{paymentData.chargeTotal ||0}}</span>
|
||||
<span class="text-[20px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<SvgComponent :content="lightningBoxSvg" class="box-light absolute" />
|
||||
</div>
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
<YProgress :percentage="Math.round(paymentData.chargeTotal/paymentData.estimatedTotal * 100)" height="12px" class="mt-[7px]" />
|
||||
</div>
|
||||
<div class="ml-[4px] relative w-[143px] h-[143px]">
|
||||
<ProportionCharts :chart-data="chartData" class="z-2 relative" />
|
||||
<SvgComponent :content="paymentChartSvg" class="w-[143px] h-[143px] absolute top-0 left-0 z-1" />
|
||||
<ProportionCharts :chart-data="chartData" class="" />
|
||||
<div
|
||||
class="text-[18px] text-[#fff] font-700 text-shadow-[0_0_10px_rgba(12,32,72,0.42)] italic absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] z-3">
|
||||
缴费
|
||||
|
|
@ -78,16 +77,10 @@
|
|||
lightningBoxSvg.value = svg;
|
||||
};
|
||||
|
||||
const paymentChartSvg = ref("");
|
||||
const getPaymentChartSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/payment-chart.svg?raw");
|
||||
paymentChartSvg.value = svg;
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
getGroupBackgroundSvg();
|
||||
getLightningBoxSvg();
|
||||
getPaymentChartSvg();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,25 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">六纬志愿</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-[20px] ml-[9px] font-700 text-color" data-text="六纬志愿">六纬志愿</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col relative">
|
||||
<div class="absolute right-[0] flex items-center justify-end mr-[13px] transform-translate-y-[-50%]">
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<div class="flex items-center justify-end mr-[13px] transform-translate-y-[-50%] h-0">
|
||||
<div class="text-[15px] text-[#84E8FF]">更多</div>
|
||||
<SvgComponent :content="moreArrowSvg" class="w-[14px] h-[22px]"/>
|
||||
<SvgComponent :content="moreArrowSvg" class="w-[14px] h-[22px]" />
|
||||
</div>
|
||||
<div class="flex items-baseline leading-[1] mt-[29px] mx-[27px]">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">总获客</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[40px] font-700 italic pr-[4px]">{{ sixStatisticsData.total || 0 }}</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[18px] font-700">人</div>
|
||||
<div class="text-[40px] font-700 italic pr-[4px] text-color" :data-text="sixStatisticsData.total || 0">{{ sixStatisticsData.total || 0 }}</div>
|
||||
<div class="text-[18px] font-700 text-color" data-text="人">人</div>
|
||||
<SvgIcon name="arrow-up" class="text-[9px] text-[#4AFFA2] ml-[9px]" />
|
||||
</div>
|
||||
<SixStatisticsChart :chartData="sixStatisticsData.items ||[]"/>
|
||||
<SixStatisticsChart :chartData="sixStatisticsData.items || []" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -56,7 +54,7 @@
|
|||
moreArrowSvg.value = svg;
|
||||
};
|
||||
|
||||
const sixStatisticsData = inject("sixStatisticsData",ref<{total:number,items:{data:string,total:number}[]}>({total:0,items:[]}))
|
||||
const sixStatisticsData = inject("sixStatisticsData", ref<{ total: number; items: { data: string; total: number }[] }>({ total: 0, items: [] }));
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
|
|
@ -68,6 +66,7 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
|
|
|
|||
|
|
@ -1,41 +1,39 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">学生来源</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-color text-[20px] ml-[9px] font-700" data-text="学生来源">学生来源</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<StudentSourceChart class="w-full h-full" :chartData="chartData" :ringSize="0.8" />
|
||||
<div class="flex items-center justify-between mx-[20px] my-[33px]">
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-col ml-[9px] items-center justify-center">
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent font-700">
|
||||
<span class="text-[18px]">{{ onlineTotal }}</span>
|
||||
<span class="text-[14px]">人</span>
|
||||
<div class="font-700 flex items-baseline">
|
||||
<span class="text-[18px] text-color" :data-text="onlineTotal">{{ onlineTotal }}</span>
|
||||
<span class="text-[14px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<span class="text-[#C7F0FF] text-[12px]">线上来源</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-col ml-[9px] items-center justify-center">
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent font-700">
|
||||
<span class="text-[18px]">{{ offlineTotal }}</span>
|
||||
<span class="text-[14px]">人</span>
|
||||
<div class="font-700 flex items-baseline">
|
||||
<span class="text-[18px] text-color" :data-text="offlineTotal">{{ offlineTotal }}</span>
|
||||
<span class="text-[14px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<span class="text-[#C7F0FF] text-[12px]">线下来源</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-col ml-[9px] items-center justify-center">
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent font-700">
|
||||
<span class="text-[18px]">{{ unMarkTotal }}</span>
|
||||
<span class="text-[14px]">人</span>
|
||||
<div class="font-700 flex items-baseline">
|
||||
<span class="text-[18px] text-color" :data-text="unMarkTotal">{{ unMarkTotal }}</span>
|
||||
<span class="text-[14px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
<span class="text-[#C7F0FF] text-[12px]">未标记</span>
|
||||
</div>
|
||||
|
|
@ -80,36 +78,35 @@
|
|||
};
|
||||
|
||||
const askSectionData = inject("askSectionData", ref<{ online: any[]; offline: any[] }>({ online: [], offline: [] }));
|
||||
const gainData = inject("gainData",ref({acqTotal:0}))
|
||||
const gainData = inject("gainData", ref({ acqTotal: 0 }));
|
||||
|
||||
|
||||
const onlineTotal = ref(0);
|
||||
const offlineTotal = ref(0);
|
||||
const unMarkTotal = ref(0)
|
||||
const unMarkTotal = ref(0);
|
||||
const chartData = ref<any[]>([]);
|
||||
watch(
|
||||
() => askSectionData.value,
|
||||
() => {
|
||||
initData()
|
||||
initData();
|
||||
},
|
||||
);
|
||||
|
||||
const initData = () => {
|
||||
if (askSectionData.value.online && askSectionData.value.online.length > 0) {
|
||||
onlineTotal.value = askSectionData.value.online.reduce((acc, curr) => acc + curr.total, 0);
|
||||
}
|
||||
if (askSectionData.value.offline && askSectionData.value.offline.length > 0) {
|
||||
offlineTotal.value = askSectionData.value.offline.reduce((acc, curr) => acc + curr.total, 0);
|
||||
}
|
||||
if(gainData.value.acqTotal && askSectionData.value.offline && askSectionData.value.online){
|
||||
unMarkTotal.value = gainData.value.acqTotal - offlineTotal.value - onlineTotal.value
|
||||
}
|
||||
chartData.value = [
|
||||
{ name: "线下", value: offlineTotal.value, itemStyle: { color: "rgba(147, 219, 255, 1)" } },
|
||||
{ name: "线上", value: onlineTotal.value, itemStyle: { color: "rgb(79, 214, 169)" } },
|
||||
{name:'未标记',value: unMarkTotal.value,itemStyle: { color: "#FF4E4E" }}
|
||||
];
|
||||
}
|
||||
onlineTotal.value = askSectionData.value.online.reduce((acc, curr) => acc + curr.total, 0);
|
||||
}
|
||||
if (askSectionData.value.offline && askSectionData.value.offline.length > 0) {
|
||||
offlineTotal.value = askSectionData.value.offline.reduce((acc, curr) => acc + curr.total, 0);
|
||||
}
|
||||
if (gainData.value.acqTotal && askSectionData.value.offline && askSectionData.value.online) {
|
||||
unMarkTotal.value = gainData.value.acqTotal - offlineTotal.value - onlineTotal.value;
|
||||
}
|
||||
chartData.value = [
|
||||
{ name: "线下", value: offlineTotal.value, itemStyle: { color: "rgba(147, 219, 255, 1)" } },
|
||||
{ name: "线上", value: onlineTotal.value, itemStyle: { color: "rgb(79, 214, 169)" } },
|
||||
{ name: "未标记", value: unMarkTotal.value, itemStyle: { color: "#FF4E4E" } },
|
||||
];
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
|
|
@ -123,6 +120,7 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
|
|
|
|||
|
|
@ -2,16 +2,13 @@
|
|||
<div class="w-max h-max relative">
|
||||
<SvgComponent :content="groupSvg" class="w-[312px] h-[210px]" />
|
||||
<div class="w-full h-full absolute top-0 left-0 pt-[31px] pb-[21px] pl-[14px] pr-[19px] flex items-center">
|
||||
<div class="w-[144px]">
|
||||
<div class="relative w-[144px] h-[113px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">今日缴费</div>
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent mb-[15px] z-10 font-700">
|
||||
<span class="text-[34px] italic">{{paymentData.toDayTotal || 0}}</span>
|
||||
<span class="text-[18px]">人</span>
|
||||
</div>
|
||||
<SvgComponent :content="hexagonalBoxSvg" class="box-light absolute" />
|
||||
<div class="relative w-[144px] h-[113px] flex items-center flex-col">
|
||||
<div class="text-[#44C1EF] italic text-[20px] font-700">今日缴费</div>
|
||||
<div class="mb-[15px] z-10 font-700 leading-[1] flex items-baseline">
|
||||
<span class="text-[34px] italic text-color" :data-text="paymentData.toDayTotal">{{paymentData.toDayTotal || 0}}</span>
|
||||
<span class="text-[18px] text-color" data-text="人">人</span>
|
||||
</div>
|
||||
|
||||
<SvgComponent :content="hexagonalBoxSvg" class="box-light absolute" />
|
||||
</div>
|
||||
<div class="relative ml-[12px]">
|
||||
<SvgComponent :content="paymentBorderSvg" class="w-[127px] h-[104px] z-1" />
|
||||
|
|
|
|||
|
|
@ -1,50 +1,46 @@
|
|||
<template>
|
||||
<div class="w-[296px] h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<div class="relative h-[36px]">
|
||||
<div class="absolute top-[50%] translate-y-[-50%] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent text-[20px] ml-[9px] font-700">获客排行榜</div>
|
||||
</div>
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
</div>
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
</div>
|
||||
<div class="w-full h-[calc(100%-36px)] mt-[36px] flex flex-col relative">
|
||||
<div class="absolute right-[0] flex items-center justify-end mr-[13px] transform-translate-y-[-50%]">
|
||||
<div class="text-[15px] text-[#84E8FF]">更多</div>
|
||||
<SvgComponent :content="moreArrowSvg" class="w-[14px] h-[22px]" />
|
||||
</div>
|
||||
<div class="mt-[26px] mx-[16px]">
|
||||
<RankingTable :value="products" :columns="columns" header-class="custom-table-header" body-class="custom-table-body">
|
||||
<template #rank="{index }">
|
||||
<SvgComponent :content="goldMedalSvg" class="w-[34px] h-[20px]" v-if="index===0"/>
|
||||
<SvgComponent :content="silverMedalSvg" class="w-[34px] h-[20px]" v-if="index===1"/>
|
||||
<SvgComponent :content="bronzeMedalSvg" class="w-[34px] h-[20px]" v-if="index===2"/>
|
||||
<span class="text-[14px] font-600" v-if="index > 2">{{ index + 1 }}</span>
|
||||
</template>
|
||||
|
||||
<template #name="{data}">
|
||||
<span class="text-[#C0EEFF] text-[14px]">{{ data.name }}</span>
|
||||
</template>
|
||||
|
||||
</RankingTable>
|
||||
</div>
|
||||
<div class="h-[320px] relative bg-[#082059]">
|
||||
<div class="flex h-full custom-border absolute top-0 left-0">
|
||||
<SvgComponent :content="headerLeftSvg" class="w-[188px] h-[36px]" />
|
||||
<SvgComponent :content="headerRightSvg" class="w-[108px] h-[36px]" />
|
||||
<div class="absolute top-[2px] left-[15px] flex items-center">
|
||||
<SvgComponent :content="arrowLeftSvg" class="w-[15px] h-[18px]" />
|
||||
<div class="text-color text-[20px] ml-[9px] font-700" data-text="获客排行榜">获客排行榜</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SvgComponent from "@/components/SvgComponent.vue";
|
||||
import RankingTable from "@/components/table/RankingTable.vue";
|
||||
|
||||
const columns = [
|
||||
{ field: "rank", header: "名次", align: "justify-center",width:'68px' },
|
||||
{ field: "name", header: "姓名", align: "justify-left",width:'100px' },
|
||||
{ field: "total", header: "获客人数", align: "justify-center",width:'96px' },
|
||||
];
|
||||
|
||||
let products = ref<any[]>([]);
|
||||
<div class="w-[296px] h-[calc(100%-36px)] mt-[36px] flex flex-col">
|
||||
<div class="flex items-center justify-end mr-[13px] transform-translate-y-[-50%] h-0">
|
||||
<div class="text-[15px] text-[#84E8FF]">更多</div>
|
||||
<SvgComponent :content="moreArrowSvg" class="w-[14px] h-[22px]" />
|
||||
</div>
|
||||
<div class="mt-[26px] mx-[16px]">
|
||||
<RankingTable :value="products" :columns="columns" header-class="custom-table-header" body-class="custom-table-body">
|
||||
<template #rank="{ index }">
|
||||
<SvgComponent :content="goldMedalSvg" class="w-[34px] h-[20px]" v-if="index === 0" />
|
||||
<SvgComponent :content="silverMedalSvg" class="w-[34px] h-[20px]" v-if="index === 1" />
|
||||
<SvgComponent :content="bronzeMedalSvg" class="w-[34px] h-[20px]" v-if="index === 2" />
|
||||
<span class="text-[14px] font-600" v-if="index > 2">{{ index + 1 }}</span>
|
||||
</template>
|
||||
<template #name="{ data }">
|
||||
<span class="text-[#C0EEFF] text-[14px]">{{ data.name }}</span>
|
||||
</template>
|
||||
</RankingTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SvgComponent from "@/components/SvgComponent.vue";
|
||||
import RankingTable from "@/components/table/RankingTable.vue";
|
||||
|
||||
const columns = [
|
||||
{ field: "rank", header: "名次", align: "justify-center", width: "68px" },
|
||||
{ field: "name", header: "姓名", align: "justify-left", width: "100px" },
|
||||
{ field: "total", header: "获客人数", align: "justify-center", width: "96px" },
|
||||
];
|
||||
|
||||
let products = ref<any[]>([]);
|
||||
const chargingRankingData = inject(
|
||||
"chargingRankingData",
|
||||
ref<{
|
||||
|
|
@ -56,104 +52,105 @@
|
|||
|
||||
watch(
|
||||
() => chargingRankingData.value,
|
||||
() => {PageTransitionEvent
|
||||
initData()
|
||||
() => {
|
||||
PageTransitionEvent;
|
||||
initData();
|
||||
},
|
||||
);
|
||||
|
||||
const initData = () => {
|
||||
if(chargingRankingData.value.acqRanks){
|
||||
products.value = chargingRankingData.value.acqRanks
|
||||
}
|
||||
}
|
||||
|
||||
const headerLeftSvg = ref("");
|
||||
const headerRightSvg = ref("");
|
||||
|
||||
const getHeaderLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-left-sort.svg?raw");
|
||||
headerLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const getHeaderRightSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-right-sort.svg?raw");
|
||||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/arrow-left.svg?raw");
|
||||
arrowLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const moreArrowSvg = ref("");
|
||||
const getMoreArrowSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/more-arrow.svg?raw");
|
||||
moreArrowSvg.value = svg;
|
||||
};
|
||||
|
||||
const goldMedalSvg = ref("")
|
||||
const getGoldMedalSvg = async () => {
|
||||
const {default: svg} = await import("/src/assets/svg-img/gold-medal.svg?raw");
|
||||
goldMedalSvg.value = svg
|
||||
if (chargingRankingData.value.acqRanks) {
|
||||
products.value = chargingRankingData.value.acqRanks;
|
||||
}
|
||||
|
||||
const silverMedalSvg = ref("")
|
||||
const getSilverMedalSvg = async () => {
|
||||
const {default: svg} = await import("/src/assets/svg-img/silver-medal.svg?raw");
|
||||
silverMedalSvg.value = svg
|
||||
}
|
||||
|
||||
const bronzeMedalSvg = ref("")
|
||||
const getBronzeMedalSvg = async () => {
|
||||
const {default: svg} = await import("/src/assets/svg-img/bronze-medal.svg?raw");
|
||||
bronzeMedalSvg.value = svg
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
|
||||
getMoreArrowSvg();
|
||||
|
||||
getGoldMedalSvg();
|
||||
getSilverMedalSvg();
|
||||
getBronzeMedalSvg();
|
||||
};
|
||||
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
border-image-outset: 0px 0px 0px 0px;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("src/assets/svg-img/border-image.png");
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
:deep(.custom-table-header) {
|
||||
tr{
|
||||
background-color: rgb(14, 39, 97);
|
||||
th{
|
||||
padding: 13px 10px;
|
||||
color:#44C1EF;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
}
|
||||
const headerLeftSvg = ref("");
|
||||
const headerRightSvg = ref("");
|
||||
|
||||
const getHeaderLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-left-sort.svg?raw");
|
||||
headerLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const getHeaderRightSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/header-bg-right-sort.svg?raw");
|
||||
headerRightSvg.value = svg;
|
||||
};
|
||||
|
||||
const arrowLeftSvg = ref("");
|
||||
const getArrowLeftSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/arrow-left.svg?raw");
|
||||
arrowLeftSvg.value = svg;
|
||||
};
|
||||
|
||||
const moreArrowSvg = ref("");
|
||||
const getMoreArrowSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/more-arrow.svg?raw");
|
||||
moreArrowSvg.value = svg;
|
||||
};
|
||||
|
||||
const goldMedalSvg = ref("");
|
||||
const getGoldMedalSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/gold-medal.svg?raw");
|
||||
goldMedalSvg.value = svg;
|
||||
};
|
||||
|
||||
const silverMedalSvg = ref("");
|
||||
const getSilverMedalSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/silver-medal.svg?raw");
|
||||
silverMedalSvg.value = svg;
|
||||
};
|
||||
|
||||
const bronzeMedalSvg = ref("");
|
||||
const getBronzeMedalSvg = async () => {
|
||||
const { default: svg } = await import("/src/assets/svg-img/bronze-medal.svg?raw");
|
||||
bronzeMedalSvg.value = svg;
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
getHeaderLeftSvg();
|
||||
getHeaderRightSvg();
|
||||
getArrowLeftSvg();
|
||||
|
||||
getMoreArrowSvg();
|
||||
|
||||
getGoldMedalSvg();
|
||||
getSilverMedalSvg();
|
||||
getBronzeMedalSvg();
|
||||
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
.custom-border {
|
||||
border-image-slice: 27 27 27 27;
|
||||
border-image-width: 1px 1px 2px 1px;
|
||||
border-image-outset: 0px 0px 0px 0px;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("src/assets/svg-img/border-image.png");
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
:deep(.custom-table-header) {
|
||||
tr {
|
||||
background-color: rgb(14, 39, 97);
|
||||
th {
|
||||
padding: 13px 10px;
|
||||
color: #44c1ef;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.custom-table-body){
|
||||
tr{
|
||||
td{
|
||||
padding: 10px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.custom-table-body) {
|
||||
tr {
|
||||
td {
|
||||
padding: 10px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -277,11 +277,11 @@
|
|||
type: "group",
|
||||
right: 97,
|
||||
top: 0,
|
||||
z: 100,
|
||||
// z: 100,
|
||||
children: [
|
||||
{
|
||||
type: "image",
|
||||
z: 100,
|
||||
// z: 100,
|
||||
style: {
|
||||
image: `data:image/svg+xml;charset=utf-8,${currentMode.value === "week" ? activeButtonSvgBase64 : buttonSvgBase64}`,
|
||||
width: 72,
|
||||
|
|
@ -292,7 +292,7 @@
|
|||
},
|
||||
{
|
||||
type: "text",
|
||||
z: 100,
|
||||
// z: 100,
|
||||
style: {
|
||||
text: "按周",
|
||||
x: 36,
|
||||
|
|
@ -312,11 +312,11 @@
|
|||
type: "group",
|
||||
right: 15,
|
||||
top: 0,
|
||||
z: 100,
|
||||
// z: 100,
|
||||
children: [
|
||||
{
|
||||
type: "image",
|
||||
z: 100,
|
||||
// z: 100,
|
||||
style: {
|
||||
image: `data:image/svg+xml;charset=utf-8,${currentMode.value === "month" ? activeButtonSvgBase64 : buttonSvgBase64}`,
|
||||
width: 72,
|
||||
|
|
@ -327,7 +327,7 @@
|
|||
},
|
||||
{
|
||||
type: "text",
|
||||
z: 100,
|
||||
// z: 100,
|
||||
style: {
|
||||
text: "按月",
|
||||
x: 36,
|
||||
|
|
@ -451,7 +451,7 @@
|
|||
{
|
||||
type: "bar",
|
||||
id: "axisOverlayBar",
|
||||
zlevel: 1,
|
||||
// zlevel: 1,
|
||||
silent: false,
|
||||
barWidth: "100%",
|
||||
data: chartData.value.dates.map(() => 500), // 使用y轴的最大值
|
||||
|
|
@ -495,7 +495,7 @@
|
|||
type: "bar",
|
||||
barWidth: 40,
|
||||
barGap: "-100%",
|
||||
zlevel: 10,
|
||||
// zlevel: 10,
|
||||
silent: true,
|
||||
animation: true,
|
||||
data: chartData.value.dates.map((_: any, index: number) => {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,26 @@
|
|||
gap: 0,
|
||||
},
|
||||
],
|
||||
graphic: [
|
||||
{
|
||||
id: "circle-rotate",
|
||||
elements: [
|
||||
{
|
||||
type: "image",
|
||||
left: "center",
|
||||
top: "center",
|
||||
style: {
|
||||
image: "/images/rotate-circle.webp",
|
||||
width: 143,
|
||||
height: 143,
|
||||
fill:"transparent"
|
||||
},
|
||||
z: 2,
|
||||
cursor: "point",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
animation: true,
|
||||
animationDuration: 500,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="relative flex-1">
|
||||
<div class="particle-base"></div>
|
||||
<div ref="chartRef" class="w-full h-full"></div>
|
||||
<div
|
||||
class="absolute left-50% top-50% transform-translate-x-[-50%] transform-translate-y-[-50%] bg-gradient-to-b from-[#8FC8FF] to-white bg-clip-text text-transparent flex items-end leading-[1] z-[2]">
|
||||
<span class="text-[24px] font-700">{{ total }}</span>
|
||||
<span class="text-[16px] font-700">人</span>
|
||||
class="absolute left-50% top-50% transform-translate-x-[-50%] transform-translate-y-[-50%] flex items-baseline">
|
||||
<span class="text-[24px] font-700 text-color" :data-text="total">{{ total }}</span>
|
||||
<span class="text-[16px] font-700 text-color" data-text="人">人</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -236,47 +238,47 @@
|
|||
},
|
||||
],
|
||||
graphic: [
|
||||
{
|
||||
id: "backgroundImg",
|
||||
elements: [
|
||||
{
|
||||
type: "image",
|
||||
left: "center",
|
||||
top: "33%",
|
||||
style: {
|
||||
image: "/images/particleBase.png",
|
||||
width: 254,
|
||||
height: 106,
|
||||
},
|
||||
z: 0,
|
||||
cursor: "point",
|
||||
origin: [127, 53],
|
||||
keyframeAnimation: [
|
||||
{
|
||||
duration: 1600,
|
||||
loop: true,
|
||||
keyframes: [
|
||||
{
|
||||
percent: 0,
|
||||
scaleX: 1.1,
|
||||
scaleY: 1.1,
|
||||
},
|
||||
{
|
||||
percent: 0.3,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
},
|
||||
{
|
||||
percent: 1,
|
||||
scaleX: 1.1,
|
||||
scaleY: 1.1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// id: "backgroundImg",
|
||||
// elements: [
|
||||
// {
|
||||
// type: "image",
|
||||
// left: "center",
|
||||
// top: "33%",
|
||||
// style: {
|
||||
// image: "/images/particleBase.png",
|
||||
// width: 254,
|
||||
// height: 106,
|
||||
// },
|
||||
// z: 0,
|
||||
// cursor: "point",
|
||||
// origin: [127, 53],
|
||||
// // keyframeAnimation: [
|
||||
// // {
|
||||
// // duration: 1600,
|
||||
// // loop: true,
|
||||
// // keyframes: [
|
||||
// // {
|
||||
// // percent: 0,
|
||||
// // scaleX: 1.1,
|
||||
// // scaleY: 1.1,
|
||||
// // },
|
||||
// // {
|
||||
// // percent: 0.3,
|
||||
// // scaleX: 1,
|
||||
// // scaleY: 1,
|
||||
// // },
|
||||
// // {
|
||||
// // percent: 1,
|
||||
// // scaleX: 1.1,
|
||||
// // scaleY: 1.1,
|
||||
// // },
|
||||
// // ],
|
||||
// // },
|
||||
// // ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
@ -328,4 +330,32 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped lang="scss">
|
||||
@use "@/styles/text-color.scss";
|
||||
|
||||
.particle-base {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 60%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 254px;
|
||||
height: 106px;
|
||||
background-image: url('/images/particleBase.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
animation: scaleAnimation 1.6s infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
@keyframes scaleAnimation {
|
||||
0% {
|
||||
transform: translate(-50%, -50%) scale(1.1);
|
||||
}
|
||||
30% {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
100% {
|
||||
transform: translate(-50%, -50%) scale(1.1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="main-bg flex flex-col scrollbar-hide h-screen overflow-auto">
|
||||
<div class="main-bg flex flex-col scrollbar-hide h-screen overflow-y-auto">
|
||||
<header class="relative flex items-center">
|
||||
<SvgComponent :content="headerSvg" class="w-full h-[98px]" />
|
||||
<SvgComponent :content="titleSvg" class="w-[50%] h-[69px] absolute top-0 left-50% translate-x-[-50%]" />
|
||||
|
|
@ -30,13 +30,13 @@
|
|||
<OperatingTrends class="flex-1" />
|
||||
<AskSection class="flex-1" />
|
||||
</div>
|
||||
<div class="flex items-center px-[24px] overflow-x-auto">
|
||||
<StudentSource class="min-w-[296px] max-w-[296px]" />
|
||||
<OnLineStatus class="ml-[20px] min-w-[296px] max-w-[296px]" />
|
||||
<OfflineStatus class="ml-[20px] min-w-[296px] max-w-[296px]" />
|
||||
<SixStatistics class="ml-[20px] min-w-[296px] max-w-[296px]" />
|
||||
<ChargingRanking class="ml-[20px]" />
|
||||
<WinCustomer class="ml-[20px]" />
|
||||
<div class="grid grid-cols-6 gap-[20px] items-center px-[24px] ">
|
||||
<StudentSource class="" />
|
||||
<OnLineStatus class="" />
|
||||
<OfflineStatus class="" />
|
||||
<SixStatistics class="" />
|
||||
<ChargingRanking class="" />
|
||||
<WinCustomer class="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -184,6 +184,5 @@
|
|||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue