From 6cee28bf66412afceb771d160e5dbdad398e42bf Mon Sep 17 00:00:00 2001 From: richarjiang Date: Sun, 12 Apr 2026 22:18:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E6=B6=88=E6=81=AF=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/app/src/components/ProfileMenu.vue | 20 ++- packages/app/src/components/SlotCard.vue | 10 +- packages/app/src/components/StudioInfo.vue | 132 ++++++++++++----- packages/app/src/components/UserCard.vue | 104 +++++++++----- packages/app/src/pages/admin/index.vue | 46 ++++++ packages/app/src/pages/booking/detail.vue | 23 +++ packages/app/src/pages/booking/index.vue | 15 +- packages/app/src/pages/home/index.vue | 1 + packages/app/src/pages/profile/index.vue | 16 ++- packages/app/src/stores/user.ts | 9 ++ packages/app/src/utils/wechat-subscription.ts | 76 ++++++++-- packages/server/prisma/schema.prisma | 19 +-- packages/server/prisma/seed.ts | 1 + packages/server/src/auth/auth.service.ts | 1 + .../booking/__tests__/booking.service.spec.ts | 58 +++++++- .../server/src/booking/booking.service.ts | 63 ++++++++- .../__tests__/time-slot.service.spec.ts | 36 ++++- .../server/src/time-slot/time-slot.service.ts | 11 +- .../src/user/__tests__/user.service.spec.ts | 42 +++++- .../src/user/subscription-message.service.ts | 133 +++++++++++++++--- packages/server/src/user/user.controller.ts | 5 + packages/server/src/user/user.service.ts | 113 +++++++++++---- packages/shared/src/enums.ts | 1 + packages/shared/src/types/subscription.ts | 1 + packages/shared/src/types/time-slot.ts | 4 +- packages/shared/src/types/user.ts | 1 + 26 files changed, 780 insertions(+), 161 deletions(-) diff --git a/packages/app/src/components/ProfileMenu.vue b/packages/app/src/components/ProfileMenu.vue index 33234f6..aa6c537 100644 --- a/packages/app/src/components/ProfileMenu.vue +++ b/packages/app/src/components/ProfileMenu.vue @@ -47,6 +47,7 @@ interface MenuItem { const props = defineProps<{ isAdmin: boolean requireAuth?: boolean + activeMembershipCount?: number }>() const emit = defineEmits<{ @@ -56,12 +57,17 @@ const emit = defineEmits<{ }>() const menuItems = computed(() => { + const membershipBadge = props.activeMembershipCount && props.activeMembershipCount > 0 + ? `${props.activeMembershipCount}张` + : undefined + const items: MenuItem[] = [ { key: 'membership', type: 'item', title: '我的会员卡', path: '/pages/profile/membership', + badge: membershipBadge, requireAuth: true, }, { @@ -346,11 +352,17 @@ function handleTap(item: MenuItem) { &__badge { font-size: 22rpx; - color: #ffffff; - background: $error-color; - border-radius: 20rpx; - padding: 2rpx 12rpx; + line-height: 1; + font-weight: 600; + color: #496578; + background: linear-gradient(135deg, rgba(239, 247, 251, 0.98), rgba(218, 234, 243, 0.96)); + border-radius: 999rpx; + padding: 9rpx 18rpx; margin-right: $spacing-sm; + border: 1rpx solid rgba(123, 165, 190, 0.18); + box-shadow: + inset 0 1rpx 0 rgba(255, 255, 255, 0.92), + 0 6rpx 16rpx rgba(123, 165, 190, 0.16); } &__arrow { diff --git a/packages/app/src/components/SlotCard.vue b/packages/app/src/components/SlotCard.vue index cf2b27c..a48d195 100644 --- a/packages/app/src/components/SlotCard.vue +++ b/packages/app/src/components/SlotCard.vue @@ -68,7 +68,7 @@