|
|
@@ -108,6 +108,40 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
+ <!-- 本月概览 -->
|
|
|
+ <view class="section-header">
|
|
|
+ <view class="section-dot"></view>
|
|
|
+ <text class="section-title">本月概览</text>
|
|
|
+ <text class="section-sub">{{ monthLabel }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="month-grid">
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value highlight">¥{{ formatAmount(monthIncome) }}</text>
|
|
|
+ <text class="month-label">当月收益</text>
|
|
|
+ </view>
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value">¥{{ formatAmount(monthConsumption) }}</text>
|
|
|
+ <text class="month-label">当月消费</text>
|
|
|
+ </view>
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value">{{ monthOrders }}</text>
|
|
|
+ <text class="month-label">当月订单</text>
|
|
|
+ </view>
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value">{{ monthWashUsers }}</text>
|
|
|
+ <text class="month-label">当月洗车人数</text>
|
|
|
+ </view>
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value">{{ monthMembers }}</text>
|
|
|
+ <text class="month-label">当月新增会员</text>
|
|
|
+ </view>
|
|
|
+ <view class="month-card">
|
|
|
+ <text class="month-value">¥{{ formatAmount(monthRefund) }}</text>
|
|
|
+ <text class="month-label">当月退款</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
<!-- 快捷入口标题 -->
|
|
|
<view class="section-header">
|
|
|
<view class="section-dot"></view>
|
|
|
@@ -201,6 +235,18 @@ const todayMembers = ref(0)
|
|
|
const totalDevices = ref(0)
|
|
|
const onlineDevices = ref(0)
|
|
|
|
|
|
+const monthIncome = ref(0)
|
|
|
+const monthConsumption = ref(0)
|
|
|
+const monthOrders = ref(0)
|
|
|
+const monthWashUsers = ref(0)
|
|
|
+const monthMembers = ref(0)
|
|
|
+const monthRefund = ref(0)
|
|
|
+
|
|
|
+const monthLabel = computed(() => {
|
|
|
+ const d = new Date()
|
|
|
+ return `${d.getFullYear()}年${d.getMonth() + 1}月`
|
|
|
+})
|
|
|
+
|
|
|
const todayDate = computed(() => {
|
|
|
const d = new Date()
|
|
|
return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日`
|
|
|
@@ -277,6 +323,12 @@ const loadData = async (stationId) => {
|
|
|
avgOrderPrice.value = data.avgOrderPrice || 0
|
|
|
avgDuration.value = Math.round((data.avgOrderDuration || 0) / 60 * 10) / 10
|
|
|
todayMembers.value = data.todayRegisteredMembers || 0
|
|
|
+ monthIncome.value = data.monthIncome || 0
|
|
|
+ monthConsumption.value = data.monthConsumptionAmount || 0
|
|
|
+ monthOrders.value = data.monthWashOrders || 0
|
|
|
+ monthWashUsers.value = data.monthWashUsers || 0
|
|
|
+ monthMembers.value = data.monthRegisteredMembers || 0
|
|
|
+ monthRefund.value = data.monthRefundAmount || 0
|
|
|
}
|
|
|
|
|
|
if (deviceRes && deviceRes.code === 200) {
|
|
|
@@ -496,6 +548,47 @@ onPullDownRefresh(async () => {
|
|
|
font-weight: 600;
|
|
|
color: #1A1A1A;
|
|
|
}
|
|
|
+.section-sub {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #999999;
|
|
|
+}
|
|
|
+
|
|
|
+/* ===== Month Overview ===== */
|
|
|
+.month-grid {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 16rpx;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+}
|
|
|
+.month-card {
|
|
|
+ flex: 0 0 calc(50% - 8rpx);
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 28rpx 24rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 10rpx;
|
|
|
+ transition: box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+}
|
|
|
+.month-card:active {
|
|
|
+ transform: translateY(-2rpx);
|
|
|
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
|
+}
|
|
|
+.month-value {
|
|
|
+ font-size: 34rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #1A1A1A;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+.month-value.highlight {
|
|
|
+ color: #C6171E;
|
|
|
+}
|
|
|
+.month-label {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+}
|
|
|
|
|
|
/* ===== Quick Actions ===== */
|
|
|
.actions-row {
|