work-order/work-order-uniapp/pages/dashboard/index.vue
2025-07-27 20:34:15 +08:00

197 lines
4.8 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="app-container">
<HeaderBar title="统计数据" text-align="center" enable-back />
<!-- 时间选择器 -->
<view class="time-selector">
<view class="preset-times">
<view
v-for="(item, index) in presetTimes"
:key="index"
:class="['preset-item', { active: currentTimeType === item.type }]"
@tap="handlePresetTimeSelect(item.type)"
>
{{ item.label }}
</view>
</view>
<view class="custom-time">
<uni-datetime-picker
v-model="dateRange"
type="daterange"
@change="handleDateRangeChange"
/>
</view>
</view>
<!-- 数据统计卡片 -->
<view class="stat-cards">
<view class="stat-card" v-for="(item, index) in statData" :key="index">
<view class="stat-title">{{ item.title }}</view>
<view class="stat-value">{{ item.value }}</view>
</view>
</view>
</view>
</template>
<script>
import HeaderBar from '@/components/HeaderBar.vue'
import { mchGetTaskStatistics } from '@/api/mch/dashboard'
export default {
components: {
HeaderBar
},
data() {
return {
currentTimeType: 'today',
dateRange: [],
presetTimes: [
{ type: 'today', label: '今日' },
{ type: 'yesterday', label: '昨日' },
{ type: 'last7days', label: '近7天' },
{ type: 'last30days', label: '近30天' }
],
statData: [
{ title: '接单数量', value: 0 },
{ title: '完成数量', value: 0 },
{ title: '取消数量', value: 0 },
{ title: '售后数量', value: 0 }
]
}
},
created() {
this.initDateRange()
this.fetchStatData()
},
methods: {
initDateRange() {
const today = new Date()
this.dateRange = [today, today]
},
handlePresetTimeSelect(type) {
this.currentTimeType = type
const today = new Date()
let startDate = new Date()
switch(type) {
case 'today':
startDate = today
break
case 'yesterday':
startDate = new Date(today.setDate(today.getDate() - 1))
break
case 'last7days':
startDate = new Date(today.setDate(today.getDate() - 6))
break
case 'last30days':
startDate = new Date(today.setDate(today.getDate() - 29))
break
}
this.dateRange = [startDate, new Date()]
this.fetchStatData()
},
handleDateRangeChange(e) {
this.currentTimeType = 'custom'
if (Array.isArray(e)) {
this.dateRange = e
this.fetchStatData()
}
},
fetchStatData() {
const formatDate = (dateStr) => {
// 如果已经是YYYY-MM-DD格式直接返回
if (typeof dateStr === 'string' && dateStr.match(/^\d{4}-\d{2}-\d{2}$/)) {
return dateStr
}
// 如果是时间戳或日期字符串转换为Date对象
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
const formattedDateRange = this.dateRange.map(date => formatDate(date))
this.$modal.loading("加载中");
mchGetTaskStatistics({
mchId: this.$store.state.user.mchId,
dateRange: formattedDateRange
}).then(res => {
let data = res.data;
this.statData = [
{ title: '接单数量', value: data.receiveCount },
{ title: '完成数量', value: data.completeCount },
{ title: '取消数量', value: data.cancelCount },
{ title: '售后数量', value: data.afterSaleCount }
]
this.$modal.closeLoading();
})
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 0 20rpx 20rpx;
}
.time-selector {
margin: 20rpx 0;
.preset-times {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
gap: 10rpx;
.preset-item {
padding: 10rpx 20rpx;
background-color: #ffffff;
border-radius: 8rpx;
font-size: 28rpx;
flex: 1;
text-align: center;
&.active {
background-color: #007AFF;
color: #fff;
}
}
}
.custom-time {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
}
}
.stat-cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
margin-top: 30rpx;
.stat-card {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.stat-title {
font-size: 28rpx;
color: #666;
margin-bottom: 10rpx;
}
.stat-value {
font-size: 40rpx;
color: #333;
font-weight: bold;
}
}
}
</style>