work-order/work-order-uniapp/pages/dashboard/index.vue

197 lines
4.8 KiB
Vue
Raw Permalink Normal View History

2025-07-27 20:34:15 +08:00
<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>