|
@@ -8,29 +8,29 @@
|
|
<img src="@assets/about-banner-s2.png" alt="" srcset="">
|
|
<img src="@assets/about-banner-s2.png" alt="" srcset="">
|
|
|
|
|
|
<!-- 数据模块 -->
|
|
<!-- 数据模块 -->
|
|
- <div class="data-stats">
|
|
|
|
|
|
+ <div class="data-stats" ref="dataStatsRef">
|
|
<div class="stats-item">
|
|
<div class="stats-item">
|
|
- <div class="stats-number">31</div>
|
|
|
|
|
|
+ <div class="stats-number">{{ animatedStats.avgAge }}</div>
|
|
<div class="stats-label">员工平均年龄</div>
|
|
<div class="stats-label">员工平均年龄</div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-item">
|
|
<div class="stats-item">
|
|
- <div class="stats-number">83%</div>
|
|
|
|
|
|
+ <div class="stats-number">{{ animatedStats.education }}%</div>
|
|
<div class="stats-label">本科学历以上占比</div>
|
|
<div class="stats-label">本科学历以上占比</div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-item">
|
|
<div class="stats-item">
|
|
- <div class="stats-number">57%</div>
|
|
|
|
|
|
+ <div class="stats-number">{{ animatedStats.technical }}%</div>
|
|
<div class="stats-label">专业技术人员占比</div>
|
|
<div class="stats-label">专业技术人员占比</div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-item">
|
|
<div class="stats-item">
|
|
- <div class="stats-number">38%</div>
|
|
|
|
|
|
+ <div class="stats-number">{{ animatedStats.professional }}%</div>
|
|
<div class="stats-label">行业专业技术人才占比</div>
|
|
<div class="stats-label">行业专业技术人才占比</div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-divider"></div>
|
|
<div class="stats-item">
|
|
<div class="stats-item">
|
|
- <div class="stats-number">53%</div>
|
|
|
|
|
|
+ <div class="stats-number">{{ animatedStats.senior }}%</div>
|
|
<div class="stats-label">中高级职称人员占比</div>
|
|
<div class="stats-label">中高级职称人员占比</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -94,9 +94,10 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-import { ref, onMounted, computed } from 'vue'
|
|
|
|
|
|
+import { ref, onMounted, computed, onUnmounted } from 'vue'
|
|
import { getCompanyCertList } from '@/api/modules/home'
|
|
import { getCompanyCertList } from '@/api/modules/home'
|
|
import DefaultLayout from '@/layouts/DefaultLayout.vue'
|
|
import DefaultLayout from '@/layouts/DefaultLayout.vue'
|
|
|
|
+import { animateNumber, createNumberAnimationObserver } from '@/utils/numberAnimation'
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: 'AboutPage',
|
|
name: 'AboutPage',
|
|
@@ -117,6 +118,28 @@ export default {
|
|
// 加载状态
|
|
// 加载状态
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
|
|
|
|
|
+ // 数据统计相关
|
|
|
|
+ const dataStatsRef = ref(null)
|
|
|
|
+ const animationObserver = ref(null)
|
|
|
|
+
|
|
|
|
+ // 动画数字状态
|
|
|
|
+ const animatedStats = ref({
|
|
|
|
+ avgAge: 0,
|
|
|
|
+ education: 0,
|
|
|
|
+ technical: 0,
|
|
|
|
+ professional: 0,
|
|
|
|
+ senior: 0
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ // 目标数字
|
|
|
|
+ const targetStats = {
|
|
|
|
+ avgAge: 31,
|
|
|
|
+ education: 83,
|
|
|
|
+ technical: 57,
|
|
|
|
+ professional: 38,
|
|
|
|
+ senior: 53
|
|
|
|
+ }
|
|
|
|
+
|
|
// 证书分类数据
|
|
// 证书分类数据
|
|
const certificateCategories = ref([
|
|
const certificateCategories = ref([
|
|
{
|
|
{
|
|
@@ -211,8 +234,49 @@ export default {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 启动数字动画
|
|
|
|
+ const startStatsAnimation = () => {
|
|
|
|
+ // 为每个统计数字创建动画,添加延迟以创建连续效果
|
|
|
|
+ const delays = [0, 200, 400, 600, 800]
|
|
|
|
+
|
|
|
|
+ Object.keys(targetStats).forEach((key, index) => {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ animateNumber(
|
|
|
|
+ (value) => {
|
|
|
|
+ animatedStats.value[key] = value
|
|
|
|
+ },
|
|
|
|
+ targetStats[key],
|
|
|
|
+ 2000 // 2秒动画时长
|
|
|
|
+ )
|
|
|
|
+ }, delays[index])
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置数字动画观察器
|
|
|
|
+ const setupStatsAnimation = () => {
|
|
|
|
+ if (dataStatsRef.value) {
|
|
|
|
+ animationObserver.value = createNumberAnimationObserver(
|
|
|
|
+ '.data-stats',
|
|
|
|
+ startStatsAnimation,
|
|
|
|
+ {
|
|
|
|
+ threshold: 0.3,
|
|
|
|
+ rootMargin: '0px 0px -50px 0px'
|
|
|
|
+ }
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
loadCertificates()
|
|
loadCertificates()
|
|
|
|
+ // 延迟设置动画观察器,确保DOM已渲染
|
|
|
|
+ setTimeout(setupStatsAnimation, 100)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ onUnmounted(() => {
|
|
|
|
+ // 清理观察器
|
|
|
|
+ if (animationObserver.value) {
|
|
|
|
+ animationObserver.value.disconnect()
|
|
|
|
+ }
|
|
})
|
|
})
|
|
|
|
|
|
return {
|
|
return {
|
|
@@ -229,7 +293,10 @@ export default {
|
|
switchTab,
|
|
switchTab,
|
|
prevSlide,
|
|
prevSlide,
|
|
nextSlide,
|
|
nextSlide,
|
|
- handleImageError
|
|
|
|
|
|
+ handleImageError,
|
|
|
|
+ // 数字动画相关
|
|
|
|
+ dataStatsRef,
|
|
|
|
+ animatedStats
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|