diff --git a/packages/app/src/pages/admin/members.vue b/packages/app/src/pages/admin/members.vue index b5eb70e..aaad165 100644 --- a/packages/app/src/pages/admin/members.vue +++ b/packages/app/src/pages/admin/members.vue @@ -87,40 +87,187 @@ - - + + - - - - - {{ (detailMember.nickname || '?').slice(0, 1) }} + + + + × + + + + + + + 详情 + + + 编辑 + + + + + + 加载中... + + + + + + + + + + {{ (detailMember.nickname || '?').slice(0, 1) }} + + + {{ detailMember.nickname || '未知用户' }} + + {{ detailMember.openid }} + + {{ detailMember.phone || '未绑定手机' }} + + + + + + {{ detailMember.totalBookings }} + 总预约 + + + {{ detailMember.completedBookings }} + 已完成 + + + {{ detailMember.cancelledBookings }} + 已取消 - {{ detailMember.nickname || '未知用户' }} - - {{ detailMember.openid }} - - {{ detailMember.phone || '未绑定手机' }} - - - - {{ detailMember.totalBookings }} - 总预约 + + + + {{ detailMembership.cardTypeName }} + + {{ statusLabel(detailMembership.status) }} + + + + + 剩余次数 + {{ detailMembership.remainingTimes ?? '不限' }} + + + 开始日期 + {{ formatDate(detailMembership.startDate) }} + + + 到期日期 + {{ formatDate(detailMembership.expireDate) }} + + - - {{ detailMember.completedBookings }} - 已完成 + + + + 暂无会员卡 + + 去开卡 + - - {{ detailMember.cancelledBookings }} - 已取消 + + + + + 解除会员卡 + - - 关闭 + + + + + + 卡类型 + + + {{ editCardTypes[editForm.cardTypeIndex]?.name || '请选择' }} + + + + + + + + 剩余次数 + + + + + + 开始日期 + + + {{ editForm.startDate || '请选择' }} + + + + + + + + 到期日期 + + + {{ editForm.expireDate || '请选择' }} + + + + + + + + + + {{ editSubmitting ? '保存中...' : '保存' }} + + @@ -128,7 +275,7 @@ @@ -546,4 +881,270 @@ onMounted(() => loadMembers(true)) } .modal-close-text { font-size: 28rpx; color: $text-secondary; } + +/* ── Modal header ─────────────────────────── */ +.modal-header { + display: flex; + justify-content: flex-end; + margin-bottom: 24rpx; +} + +.modal-close-btn { + width: 48rpx; + height: 48rpx; + display: flex; + align-items: center; + justify-content: center; + background: $bg-page; + border-radius: 50%; +} + +.modal-close-icon { + font-size: 36rpx; + color: $text-secondary; + line-height: 1; +} + +/* ── Tab bar ──────────────────────────────── */ +.tab-bar { + display: flex; + gap: 16rpx; + margin-bottom: 32rpx; +} + +.tab-item { + flex: 1; + height: 80rpx; + display: flex; + align-items: center; + justify-content: center; + background: $bg-page; + border-radius: $radius-md; +} + +.tab-item--active { + background: $brand-color; +} + +.tab-text { + font-size: 28rpx; + color: $text-secondary; + font-weight: 500; +} + +.tab-text--active { + color: $accent-color; + font-weight: 700; +} + +/* ── Tab content ──────────────────────────── */ +.tab-content { + min-height: 400rpx; +} + +.edit-loading { + display: flex; + align-items: center; + justify-content: center; + min-height: 400rpx; +} + +.edit-loading-text { + font-size: 28rpx; + color: $text-hint; +} + +/* ── Membership card ──────────────────────── */ +.membership-card { + background: $bg-page; + border-radius: $radius-md; + padding: 28rpx; + margin-bottom: 24rpx; +} + +.membership-card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20rpx; +} + +.membership-card-name { + font-size: 32rpx; + font-weight: 700; + color: $brand-color; +} + +.membership-card-badge { + font-size: 22rpx; + font-weight: 600; + padding: 4rpx 16rpx; + border-radius: 20rpx; +} + +.badge--active { + color: #52c41a; + background: rgba(#52c41a, 0.1); +} + +.badge--expired { + color: #999; + background: rgba(#999, 0.1); +} + +.badge--used_up { + color: #e64329; + background: rgba(#e64329, 0.1); +} + +.membership-card-info { + display: flex; + flex-direction: column; + gap: 12rpx; +} + +.membership-info-item { + display: flex; + justify-content: space-between; + align-items: center; +} + +.membership-info-label { + font-size: 26rpx; + color: $text-hint; +} + +.membership-info-value { + font-size: 26rpx; + color: $text-primary; + font-weight: 600; +} + +/* ── No membership ────────────────────────── */ +.no-membership { + display: flex; + flex-direction: column; + align-items: center; + gap: 24rpx; + padding: 48rpx 0; +} + +.no-membership-text { + font-size: 28rpx; + color: $text-hint; +} + +.no-membership-btn { + background: $brand-color; + border-radius: $radius-md; + padding: 20rpx 48rpx; +} + +.no-membership-btn-text { + font-size: 28rpx; + font-weight: 600; + color: $accent-color; +} + +/* ── Danger zone ─────────────────────────── */ +.danger-zone { + margin-top: 32rpx; + padding-top: 32rpx; + border-top: 1rpx solid $border-color; +} + +.danger-btn { + width: 100%; + height: 88rpx; + display: flex; + align-items: center; + justify-content: center; + background: rgba(#e64329, 0.08); + border-radius: $radius-md; +} + +.danger-btn-text { + font-size: 28rpx; + color: #e64329; + font-weight: 600; +} + +/* ── Edit form ───────────────────────────── */ +.edit-form { + display: flex; + flex-direction: column; + gap: 24rpx; +} + +.form-item { + display: flex; + flex-direction: column; + gap: 8rpx; +} + +.form-label { + font-size: 26rpx; + color: $text-secondary; + font-weight: 500; +} + +.form-input { + height: 80rpx; + background: $bg-page; + border-radius: $radius-md; + padding: 0 24rpx; + font-size: 28rpx; + color: $text-primary; +} + +.form-picker { + height: 80rpx; + background: $bg-page; + border-radius: $radius-md; + display: flex; + align-items: center; +} + +.form-picker-inner { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 24rpx; +} + +.form-picker-text { + font-size: 28rpx; + color: $text-primary; +} + +.form-picker-arrow { + font-size: 20rpx; + color: $text-hint; +} + +/* ── Edit submit ──────────────────────────── */ +.edit-submit { + margin-top: 32rpx; +} + +.submit-btn { + width: 100%; + height: 88rpx; + background: $brand-color; + border-radius: 44rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.submit-btn--disabled { + opacity: 0.5; +} + +.submit-btn-text { + font-size: 28rpx; + font-weight: 600; + color: $accent-color; +}