|
|
@@ -1,12 +1,10 @@
|
|
|
<template>
|
|
|
<div class="dashboard-editor-container">
|
|
|
- <!-- 新增Banner区域 - 轮播图 -->
|
|
|
- <el-row class="banner-section" >
|
|
|
+ <!-- 轮播图区域(保持不变) -->
|
|
|
+ <el-row class="banner-section">
|
|
|
<el-col :span="24">
|
|
|
<div class="carousel-container">
|
|
|
- <!-- 轮播图 -->
|
|
|
<div class="carousel-wrapper">
|
|
|
- <!-- 图片列表 -->
|
|
|
<div
|
|
|
class="carousel-slide"
|
|
|
:style="{ transform: `translateX(-${currentIndex * 100}%)` }"
|
|
|
@@ -17,54 +15,24 @@
|
|
|
class="carousel-item"
|
|
|
@click="handleBannerClick(item)"
|
|
|
>
|
|
|
- <!-- 背景图片 -->
|
|
|
<img
|
|
|
:src="item.imageUrl"
|
|
|
:alt="item.bannerName"
|
|
|
class="carousel-bg-img"
|
|
|
/>
|
|
|
- <!-- 遮罩层 -->
|
|
|
<div class="carousel-overlay"></div>
|
|
|
-
|
|
|
- <!-- 内容 -->
|
|
|
-<!-- <div class="carousel-content">-->
|
|
|
-<!-- <h2 class="carousel-title">{{ item.title }}</h2>-->
|
|
|
-<!-- <p class="carousel-desc">{{ item.desc }}</p>-->
|
|
|
-<!-- <el-button-->
|
|
|
-<!-- type="primary"-->
|
|
|
-<!-- size="large"-->
|
|
|
-<!-- class="carousel-button"-->
|
|
|
-<!-- @click.stop="handleQueryClick(item)"-->
|
|
|
-<!-- >-->
|
|
|
-<!-- <span style="font-weight: 500;">立即查询</span>-->
|
|
|
-<!-- <el-icon style="margin-left: 8px;">-->
|
|
|
-<!-- <ArrowRight />-->
|
|
|
-<!-- </el-icon>-->
|
|
|
-<!-- </el-button>-->
|
|
|
-<!-- </div>-->
|
|
|
-
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 导航箭头 -->
|
|
|
<div class="carousel-nav">
|
|
|
- <el-button
|
|
|
- circle
|
|
|
- class="nav-btn prev-btn"
|
|
|
- @click="prevSlide"
|
|
|
- >
|
|
|
+ <el-button circle class="nav-btn prev-btn" @click="prevSlide">
|
|
|
<el-icon><ArrowLeft /></el-icon>
|
|
|
</el-button>
|
|
|
- <el-button
|
|
|
- circle
|
|
|
- class="nav-btn next-btn"
|
|
|
- @click="nextSlide"
|
|
|
- >
|
|
|
+ <el-button circle class="nav-btn next-btn" @click="nextSlide">
|
|
|
<el-icon><ArrowRight /></el-icon>
|
|
|
</el-button>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 指示器 -->
|
|
|
<div class="carousel-indicators">
|
|
|
<div
|
|
|
v-for="(item, index) in bannerList"
|
|
|
@@ -81,27 +49,33 @@
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
- <panel-group @handle-set-line-chart-data="handleSetLineChartData" />
|
|
|
+ <!-- 顶部卡片区域,传入真实统计数据 -->
|
|
|
+ <panel-group
|
|
|
+ :total-order="totalOrderStat.totalOrderCount"
|
|
|
+ :jd-order="totalOrderStat.jdOrderCount"
|
|
|
+ :sf-order="totalOrderStat.sfOrderCount"
|
|
|
+ :total-amount="totalOrderStat.totalAmount"
|
|
|
+ @handle-set-line-chart-data="handleSetLineChartData"
|
|
|
+ />
|
|
|
|
|
|
<el-row :gutter="32" class="chart-continer">
|
|
|
<el-col :xs="24" :sm="24" :lg="8" class="chart-section">
|
|
|
<div class="chart-wrapper">
|
|
|
- <div class="chart-title">123</div>
|
|
|
-<!-- <raddar-chart />-->
|
|
|
- <pie-chart-one />
|
|
|
+ <div class="chart-title">订单渠道占比</div>
|
|
|
+ <pie-chart-one :chart-data="pieChartData" />
|
|
|
</div>
|
|
|
</el-col>
|
|
|
<el-col :xs="24" :sm="24" :lg="8" class="chart-section">
|
|
|
<div class="chart-wrapper">
|
|
|
- <div class="chart-title">123</div>
|
|
|
- <pie-chart />
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="24" :sm="24" :lg="8" class="chart-section">
|
|
|
- <div class="chart-wrapper">
|
|
|
- <div class="chart-title">123</div>
|
|
|
-<!-- <bar-chart />-->
|
|
|
- <line-chart :chart-data="lineChartData"/>
|
|
|
+ <div class="chart-title">近7天订单趋势</div>
|
|
|
+ <!-- 传入三个系列数据、X轴标签和当前可见系列 -->
|
|
|
+ <line-chart
|
|
|
+ :jd-data="jdCounts"
|
|
|
+ :sf-data="sfCounts"
|
|
|
+ :total-data="totalCounts"
|
|
|
+ :x-axis-data="xAxisLabels"
|
|
|
+ :visible-series="visibleSeries"
|
|
|
+ />
|
|
|
</div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -109,93 +83,70 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, onUnmounted } from 'vue'
|
|
|
+import { ref, onMounted, onUnmounted, computed } from 'vue'
|
|
|
import { ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
|
|
|
import PanelGroup from './dashboard/PanelGroup.vue'
|
|
|
import LineChart from './dashboard/LineChart.vue'
|
|
|
-import RaddarChart from './dashboard/RaddarChart.vue'
|
|
|
-import PieChart from './dashboard/PieChart.vue'
|
|
|
-import PieChartOne from "./dashboard/PieChart-one.vue";
|
|
|
-import BarChart from './dashboard/BarChart.vue'
|
|
|
-
|
|
|
-import {listIndexBanner} from "../api/logistics/banner.js";
|
|
|
+import PieChartOne from './dashboard/PieChart-one.vue'
|
|
|
+import { getTotalOrderStatist, getLast7DaysOrderStatistics } from '@/api/logistics/index.js'
|
|
|
+import { listIndexBanner } from '@/api/logistics/banner.js'
|
|
|
|
|
|
// 轮播图数据
|
|
|
-const bannerList = ref([
|
|
|
- {
|
|
|
- id: 1,
|
|
|
- image: 'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
|
|
|
- title: '全程货物跟踪',
|
|
|
- desc: '查询不限口岸,节点提醒、ETA/ETD延误,微信实时推送',
|
|
|
- link: '/tracking',
|
|
|
- queryType: 'all'
|
|
|
- },
|
|
|
- {
|
|
|
- id: 2,
|
|
|
- image: 'https://images.unsplash.com/photo-1562887189-e5d078343de4?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
|
|
|
- title: '海运货物跟踪',
|
|
|
- desc: '海运货物实时位置查询,ETA准确率高达99%',
|
|
|
- link: '/tracking?type=sea',
|
|
|
- queryType: 'sea'
|
|
|
- },
|
|
|
- {
|
|
|
- id: 3,
|
|
|
- image: 'https://images.unsplash.com/photo-1518548419970-58e3b4079ab2?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
|
|
|
- title: '空运货物跟踪',
|
|
|
- desc: '空运货物快速查询,航班动态实时更新',
|
|
|
- link: '/tracking?type=air',
|
|
|
- queryType: 'air'
|
|
|
- },
|
|
|
- {
|
|
|
- id: 4,
|
|
|
- image: 'https://images.unsplash.com/photo-1542744094-3a31f272c490?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
|
|
|
- title: '多式联运跟踪',
|
|
|
- desc: '支持海运、空运、铁路、公路多式联运全程跟踪',
|
|
|
- link: '/tracking?type=multimodal',
|
|
|
- queryType: 'multimodal'
|
|
|
- },
|
|
|
- {
|
|
|
- id: 5,
|
|
|
- image: 'https://images.unsplash.com/photo-1601584115197-04ecc0da31d7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
|
|
|
- title: '跨境电商物流',
|
|
|
- desc: '专为跨境电商打造的物流跟踪解决方案',
|
|
|
- link: '/tracking?type=ecommerce',
|
|
|
- queryType: 'ecommerce'
|
|
|
- }
|
|
|
-])
|
|
|
-
|
|
|
-// 当前轮播索引
|
|
|
+const bannerList = ref([])
|
|
|
const currentIndex = ref(0)
|
|
|
-// 轮播定时器
|
|
|
let autoPlayTimer = null
|
|
|
-// 轮播间隔(毫秒)
|
|
|
const interval = 5000
|
|
|
|
|
|
-// 图表数据
|
|
|
-const lineChartDataMap = {
|
|
|
- newVisitis: {
|
|
|
- expectedData: [100, 120, 161, 134, 105, 160, 165],
|
|
|
- actualData: [120, 82, 91, 154, 162, 140, 145]
|
|
|
- },
|
|
|
- messages: {
|
|
|
- expectedData: [200, 192, 120, 144, 160, 130, 140],
|
|
|
- actualData: [180, 160, 151, 106, 145, 150, 130]
|
|
|
- },
|
|
|
- purchases: {
|
|
|
- expectedData: [80, 100, 121, 104, 105, 90, 100],
|
|
|
- actualData: [120, 90, 100, 138, 142, 130, 130]
|
|
|
- },
|
|
|
- shoppings: {
|
|
|
- expectedData: [130, 140, 141, 142, 145, 150, 160],
|
|
|
- actualData: [120, 82, 91, 154, 162, 140, 130]
|
|
|
- }
|
|
|
-}
|
|
|
+// 统计数据
|
|
|
+const totalOrderStat = ref({
|
|
|
+ totalOrderCount: 0,
|
|
|
+ jdOrderCount: 0,
|
|
|
+ sfOrderCount: 0,
|
|
|
+ totalAmount: 0
|
|
|
+})
|
|
|
+const last7DaysOrders = ref([])
|
|
|
+
|
|
|
+// 计算属性:X轴标签(MM-DD)
|
|
|
+const xAxisLabels = computed(() => {
|
|
|
+ return last7DaysOrders.value.map(item => {
|
|
|
+ const date = new Date(item.statisticsDate)
|
|
|
+ const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
|
+ const day = date.getDate().toString().padStart(2, '0')
|
|
|
+ return `${month}-${day}`
|
|
|
+ })
|
|
|
+})
|
|
|
|
|
|
-const lineChartData = ref(lineChartDataMap.newVisitis)
|
|
|
+// 各系列数据
|
|
|
+const jdCounts = computed(() => last7DaysOrders.value.map(item => item.jdOrderCount))
|
|
|
+const sfCounts = computed(() => last7DaysOrders.value.map(item => item.sfOrderCount))
|
|
|
+const totalCounts = computed(() => last7DaysOrders.value.map(item => item.totalOrderCount))
|
|
|
|
|
|
+// 饼图数据
|
|
|
+const pieChartData = computed(() => [
|
|
|
+ { value: totalOrderStat.value.jdOrderCount, name: '京东订单' },
|
|
|
+ { value: totalOrderStat.value.sfOrderCount, name: '顺丰订单' }
|
|
|
+])
|
|
|
+
|
|
|
+// 控制折线图显示哪些系列(默认全部显示)
|
|
|
+const visibleSeries = ref(['jd', 'sf', 'total'])
|
|
|
+
|
|
|
+// 卡片点击切换系列显示
|
|
|
const handleSetLineChartData = (type) => {
|
|
|
- if (lineChartDataMap[type]) {
|
|
|
- lineChartData.value = lineChartDataMap[type]
|
|
|
+ switch (type) {
|
|
|
+ case 'newVisitis': // 总订单数卡片 -> 只显示总订单
|
|
|
+ visibleSeries.value = ['total']
|
|
|
+ break
|
|
|
+ case 'messages': // 京东订单卡片 -> 只显示京东
|
|
|
+ visibleSeries.value = ['jd']
|
|
|
+ break
|
|
|
+ case 'purchases': // 顺丰订单卡片 -> 只显示顺丰
|
|
|
+ visibleSeries.value = ['sf']
|
|
|
+ break
|
|
|
+ case 'shoppings': // 总费用卡片(暂无每日费用,显示总订单趋势)
|
|
|
+ visibleSeries.value = ['total']
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ visibleSeries.value = ['jd', 'sf', 'total']
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -204,59 +155,59 @@ const nextSlide = () => {
|
|
|
currentIndex.value = (currentIndex.value + 1) % bannerList.value.length
|
|
|
resetAutoPlay()
|
|
|
}
|
|
|
-
|
|
|
const prevSlide = () => {
|
|
|
currentIndex.value = (currentIndex.value - 1 + bannerList.value.length) % bannerList.value.length
|
|
|
resetAutoPlay()
|
|
|
}
|
|
|
-
|
|
|
const goToSlide = (index) => {
|
|
|
currentIndex.value = index
|
|
|
resetAutoPlay()
|
|
|
}
|
|
|
-
|
|
|
const startAutoPlay = () => {
|
|
|
stopAutoPlay()
|
|
|
autoPlayTimer = setInterval(nextSlide, interval)
|
|
|
}
|
|
|
-
|
|
|
const stopAutoPlay = () => {
|
|
|
if (autoPlayTimer) {
|
|
|
clearInterval(autoPlayTimer)
|
|
|
autoPlayTimer = null
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
const resetAutoPlay = () => {
|
|
|
stopAutoPlay()
|
|
|
startAutoPlay()
|
|
|
}
|
|
|
|
|
|
-// 点击事件
|
|
|
const handleBannerClick = (item) => {
|
|
|
- console.log('Banner clicked:', item)
|
|
|
- if(item.linkUrl && item.linkUrl.startsWith('http')){
|
|
|
+ if (item.linkUrl && item.linkUrl.startsWith('http')) {
|
|
|
window.open(item.linkUrl, '_blank')
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const handleQueryClick = (item) => {
|
|
|
- console.log('Query button clicked:', item)
|
|
|
- // 这里可以触发查询事件
|
|
|
- // 例如:emit('query', item.queryType)
|
|
|
-}
|
|
|
-
|
|
|
-const getBannerList = () =>{
|
|
|
- // const params = {sysType:0,delFlag:0 } //系统类型(0PC管理、1小程) 删除标志(0代表存在 2代表删除
|
|
|
+// API 调用
|
|
|
+const getBannerList = () => {
|
|
|
listIndexBanner().then(response => {
|
|
|
bannerList.value = response.data
|
|
|
startAutoPlay()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 生命周期
|
|
|
+const queryStatist = () => {
|
|
|
+ getTotalOrderStatist().then(response => {
|
|
|
+ totalOrderStat.value = response
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const queryLast7DayStatist = () => {
|
|
|
+ getLast7DaysOrderStatistics().then(response => {
|
|
|
+ last7DaysOrders.value = response
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
getBannerList()
|
|
|
+ queryStatist()
|
|
|
+ queryLast7DayStatist()
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|