refactor(app): 移除管理中心顶部统计卡,数据已在统计分析页提供
This commit is contained in:
@@ -2,31 +2,6 @@
|
|||||||
<view class="page" :style="{ paddingTop: navBarHeight }">
|
<view class="page" :style="{ paddingTop: navBarHeight }">
|
||||||
<CustomNavBar title="管理中心" show-back />
|
<CustomNavBar title="管理中心" show-back />
|
||||||
|
|
||||||
<!-- Stats summary card -->
|
|
||||||
<view class="stats-card-wrap">
|
|
||||||
<view class="stats-card">
|
|
||||||
<view v-if="statsLoading" class="stats-loading">
|
|
||||||
<view v-for="i in 3" :key="i" class="stat-skeleton" />
|
|
||||||
</view>
|
|
||||||
<template v-else>
|
|
||||||
<view class="stat-block">
|
|
||||||
<text class="stat-num">{{ stats.todayBookings }}</text>
|
|
||||||
<text class="stat-sub">今日预约</text>
|
|
||||||
</view>
|
|
||||||
<view class="stat-sep" />
|
|
||||||
<view class="stat-block">
|
|
||||||
<text class="stat-num">{{ stats.totalOrders }}</text>
|
|
||||||
<text class="stat-sub">总订单</text>
|
|
||||||
</view>
|
|
||||||
<view class="stat-sep" />
|
|
||||||
<view class="stat-block">
|
|
||||||
<text class="stat-num">{{ stats.totalBookings }}</text>
|
|
||||||
<text class="stat-sub">总预约</text>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- Section: 课务运营 -->
|
<!-- Section: 课务运营 -->
|
||||||
<view class="section-header">
|
<view class="section-header">
|
||||||
<text class="section-title">课务运营</text>
|
<text class="section-title">课务运营</text>
|
||||||
@@ -101,37 +76,21 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import CustomNavBar from '../../components/CustomNavBar.vue'
|
import CustomNavBar from '../../components/CustomNavBar.vue'
|
||||||
import { getSystemLayout } from '../../utils/system'
|
import { getSystemLayout } from '../../utils/system'
|
||||||
import { useAdminStore } from './stores/admin'
|
|
||||||
import { useUserStore } from '../../stores/user'
|
import { useUserStore } from '../../stores/user'
|
||||||
import type { AdminStats } from './stores/admin'
|
|
||||||
import { requestAdminBookingSubscriptionCount } from '../../utils/wechat-subscription'
|
import { requestAdminBookingSubscriptionCount } from '../../utils/wechat-subscription'
|
||||||
import { getErrorMessage } from '../../utils/auth'
|
import { getErrorMessage } from '../../utils/auth'
|
||||||
|
|
||||||
const navBarHeight = ref('64px')
|
const navBarHeight = ref('64px')
|
||||||
|
|
||||||
const adminStore = useAdminStore()
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const { user } = storeToRefs(userStore)
|
const { user } = storeToRefs(userStore)
|
||||||
|
|
||||||
const statsLoading = ref(false)
|
|
||||||
const stats = ref<AdminStats>({ todayBookings: 0, totalOrders: 0, totalBookings: 0 })
|
|
||||||
const adminSubscribeLoading = ref(false)
|
const adminSubscribeLoading = ref(false)
|
||||||
|
|
||||||
function navigate(path: string) {
|
function navigate(path: string) {
|
||||||
uni.navigateTo({ url: path })
|
uni.navigateTo({ url: path })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadStats() {
|
|
||||||
statsLoading.value = true
|
|
||||||
try {
|
|
||||||
stats.value = await adminStore.fetchDashboardStats()
|
|
||||||
} catch {
|
|
||||||
// fail silently — stats are non-critical
|
|
||||||
} finally {
|
|
||||||
statsLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleIncreaseSubscriptionCount() {
|
async function handleIncreaseSubscriptionCount() {
|
||||||
if (adminSubscribeLoading.value) {
|
if (adminSubscribeLoading.value) {
|
||||||
return
|
return
|
||||||
@@ -156,72 +115,12 @@ async function handleIncreaseSubscriptionCount() {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
navBarHeight.value = `${getSystemLayout().navBarHeight}px`
|
navBarHeight.value = `${getSystemLayout().navBarHeight}px`
|
||||||
loadStats()
|
|
||||||
userStore.fetchProfile()
|
userStore.fetchProfile()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/* ── Page ───────────────────────── */
|
/* ── Page ───────────────────────── */
|
||||||
/* ── Stats card ──────────────────── */
|
|
||||||
.stats-card-wrap {
|
|
||||||
padding: 24rpx 24rpx 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-card {
|
|
||||||
background: #FFFFFF;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
padding: 32rpx 24rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
box-shadow: 0 4rpx 20rpx rgba(180, 160, 130, 0.10);
|
|
||||||
border: 1rpx solid rgba(180, 160, 130, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-loading {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-skeleton {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 64rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
background: linear-gradient(90deg, $primary-border 25%, $primary-light 50%, $primary-border 75%);
|
|
||||||
background-size: 400% 100%;
|
|
||||||
animation: shimmer 1.6s ease infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-block {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-num {
|
|
||||||
font-size: 44rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #4A4035;
|
|
||||||
line-height: 1;
|
|
||||||
font-family: 'DIN Alternate', 'Helvetica Neue', Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-sub {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #A09080;
|
|
||||||
letter-spacing: 0.5rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-sep {
|
|
||||||
width: 1rpx;
|
|
||||||
height: 56rpx;
|
|
||||||
background: rgba(180, 160, 130, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 40rpx;
|
padding-bottom: 40rpx;
|
||||||
|
|||||||
Reference in New Issue
Block a user