提交
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div class="top-data">
|
||||
<!-- 销售信息 -->
|
||||
<div class="sales-info">
|
||||
<div class="sales-info-top">
|
||||
<div class="target-info">
|
||||
<h3>年度目标</h3>
|
||||
<div class="target-amount">{{ formatLargeNumber(yearData.target) }}</div>
|
||||
</div>
|
||||
<div class="total-info">
|
||||
<h3>年度总销售额</h3>
|
||||
<div class="total-amount">{{ formatLargeNumber(yearData.actual) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sales-info-cont">
|
||||
<div class="sales-info-bottom">
|
||||
<div class="progress-container">
|
||||
<div class="progress-bg">
|
||||
<div class="progress-bar" :style="{ width: progressWidth }">
|
||||
<div class="progress-info">
|
||||
<div class="play-btn"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-text">{{ progressRate }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-label">完成率</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 年度进度 -->
|
||||
<div class="countdown">
|
||||
<h3>年度进度</h3>
|
||||
<div class="quarters-container">
|
||||
<div v-for="(quarter, index) in quarters" :key="quarter.id"
|
||||
class="quarter-item"
|
||||
:class="{ 'last-quarter': index === quarters.length - 1 }">
|
||||
<div class="quarter-label">{{ quarter.label }}</div>
|
||||
<div class="weeks-container">
|
||||
<div
|
||||
v-for="week in quarter.weeks"
|
||||
:key="week"
|
||||
class="week-circle"
|
||||
:class="{ 'current': week === currentWeek, 'passed': week < currentWeek }"
|
||||
:title="`第${week}周`"
|
||||
>
|
||||
{{ week }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
const emit = defineEmits(['progress-rate'])
|
||||
|
||||
// 年度销售数据
|
||||
const yearData = ref({
|
||||
target: 3500,
|
||||
actual: 2750
|
||||
})
|
||||
|
||||
// 进度条宽度
|
||||
const progressWidth = ref('0%')
|
||||
const progressRate = ref('0.00')
|
||||
|
||||
// 获取当前周数
|
||||
const getCurrentWeek = () => {
|
||||
const now = new Date()
|
||||
const start = new Date(now.getFullYear(), 0, 1)
|
||||
const diff = now - start
|
||||
return Math.floor(diff / (7 * 24 * 60 * 60 * 1000)) + 1
|
||||
}
|
||||
|
||||
const currentWeek = ref(getCurrentWeek())
|
||||
|
||||
// 季度数据
|
||||
const quarters = ref([
|
||||
{ id: 'q1', label: 'Q1', start: 1, end: 13, weeks: [] },
|
||||
{ id: 'q2', label: 'Q2', start: 14, end: 26, weeks: [] },
|
||||
{ id: 'q3', label: 'Q3', start: 27, end: 39, weeks: [] },
|
||||
{ id: 'q4', label: 'Q4', start: 40, end: 52, weeks: [] }
|
||||
])
|
||||
|
||||
// 初始化季度周数
|
||||
quarters.value.forEach(quarter => {
|
||||
for (let i = quarter.start; i <= quarter.end; i++) {
|
||||
quarter.weeks.push(i)
|
||||
}
|
||||
})
|
||||
|
||||
// 获取年度数据(可替换为API调用)
|
||||
const fetchYearData = async () => {
|
||||
// TODO: 替换为实际的API调用
|
||||
// try {
|
||||
// const response = await fetch('/api/year-data')
|
||||
// const data = await response.json()
|
||||
// return data
|
||||
// } catch (error) {
|
||||
// console.error('获取数据失败:', error)
|
||||
// return { target: 0, actual: 0 }
|
||||
// }
|
||||
|
||||
// 当前使用模拟数据
|
||||
console.log('正在获取年度数据...')
|
||||
return {
|
||||
target: 3500,
|
||||
actual: 2750
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化大数字(万元)
|
||||
const formatLargeNumber = (num) => {
|
||||
return num.toLocaleString('zh-CN') + ' 万元'
|
||||
}
|
||||
|
||||
// 启动进度条动画
|
||||
const startProgressAnimation = (targetRate) => {
|
||||
const PROGRESS_STEP = 0.4
|
||||
const PROGRESS_INTERVAL = 20
|
||||
let value = 0
|
||||
let lastTime = 0
|
||||
|
||||
const animateProgress = (currentTime) => {
|
||||
if (!lastTime) lastTime = currentTime
|
||||
const deltaTime = currentTime - lastTime
|
||||
|
||||
if (deltaTime >= PROGRESS_INTERVAL) {
|
||||
value += PROGRESS_STEP
|
||||
if (value >= targetRate) {
|
||||
value = targetRate
|
||||
progressWidth.value = value + '%'
|
||||
return
|
||||
}
|
||||
progressWidth.value = value + '%'
|
||||
lastTime = currentTime
|
||||
}
|
||||
requestAnimationFrame(animateProgress)
|
||||
}
|
||||
|
||||
requestAnimationFrame(animateProgress)
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
onMounted(async () => {
|
||||
// 获取数据
|
||||
yearData.value = await fetchYearData()
|
||||
|
||||
// 计算完成率
|
||||
const rate = ((yearData.value.actual / yearData.value.target) * 100).toFixed(2)
|
||||
progressRate.value = rate
|
||||
|
||||
// 发射进度率事件
|
||||
emit('progress-rate', parseFloat(rate))
|
||||
|
||||
// 延迟启动进度条动画
|
||||
setTimeout(() => {
|
||||
startProgressAnimation(parseFloat(rate))
|
||||
}, 800)
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user