增加品牌方案管理

This commit is contained in:
2026-07-23 18:56:35 +08:00
parent 4c07ec5455
commit b689656faf
67 changed files with 5572 additions and 231 deletions
+53 -10
View File
@@ -1,32 +1,41 @@
<template>
<view class="home-page">
<!-- 状态栏 + 胶囊按钮占位 -->
<view class="header-wrap" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-bar" :style="{ height: navBarHeight + 'px' }">
<view class="header-wrap" :style="headerStyle">
<view class="nav-bar" :style="navStyle">
<text class="nav-title">&#10031; 今日训练</text>
</view>
</view>
<scroll-view class="content" scroll-y :style="{ height: 'calc(100vh - ' + totalHeaderHeight + 'px)' }">
<view class="content-inner">
<!-- 品牌展示 -->
<view class="brand-section">
<image class="brand-logo" :src="brandConfig.logoUrl || '/static/logo.png'" mode="aspectFit" />
<view class="brand-text">
<text class="brand-name">{{ brandConfig.brandName }}</text>
<text class="brand-slogan">{{ brandConfig.slogan }}</text>
</view>
</view>
<!-- 个人信息卡片深色+ 轮播图 -->
<view class="greeting-card">
<view class="greeting-card" :style="greetingCardStyle">
<view class="greeting-header" @click="goToProfile">
<view class="member-info">
<text class="member-name">{{ memberInfo.nickname ? '你好,' + memberInfo.nickname : '欢迎您!点击前往更新您的信息。' }}</text>
</view>
<view class="checkin-badge" v-if="memberInfo.checkedInToday">
<view class="checkin-badge" v-if="memberInfo.checkedInToday" :style="checkinBadgeStyle">
<text class="checkin-icon">&#10003;</text>
<text>今日已签到</text>
</view>
</view>
<view class="stats">
<view class="stat-item">
<text class="stat-number">{{ memberInfo.totalSignDays }}</text>
<text class="stat-number" :style="{ color: brandConfig.primaryColor }">{{ memberInfo.totalSignDays }}</text>
<text class="stat-label">累计签到()</text>
</view>
<view class="stat-item">
<text class="stat-number">{{ memberInfo.pendingBookings }}</text>
<text class="stat-number" :style="{ color: brandConfig.primaryColor }">{{ memberInfo.pendingBookings }}</text>
<text class="stat-label">待上团课</text>
</view>
</view>
@@ -46,7 +55,7 @@
<view class="recommend-section">
<view class="section-header">
<text class="section-title">&#10031; 今日推荐</text>
<text class="section-more" @click="goToSearch">查看全部 &#8250;</text>
<text class="section-more" :style="{ color: brandConfig.primaryColor }" @click="goToSearch">查看全部 &#8250;</text>
</view>
<view class="recommend-list">
<view v-for="(course, idx) in recommendCourses" :key="idx" class="recommend-card"
@@ -56,7 +65,7 @@
<text class="card-name">{{ course.courseName }}</text>
<text class="card-reason">{{ course.recommendReason }}</text>
<view class="card-bottom">
<text class="card-price">{{ course.priceLabel }}</text>
<text class="card-price" :style="{ color: brandConfig.primaryColor }">{{ course.priceLabel }}</text>
<text class="card-count">{{ course.bookedCount }}人已预约</text>
</view>
</view>
@@ -75,6 +84,7 @@
const memberApi = require('../../api/member')
const courseApi = require('../../api/course')
const bannerApi = require('../../api/banner')
const brandStore = require('../../store/brand')
const { resolveCoverUrl } = require('../../utils/request')
export default {
@@ -91,7 +101,8 @@
pendingBookings: 0
},
banners: [],
recommendCourses: []
recommendCourses: [],
brandConfig: brandStore.config
}
},
onLoad() {
@@ -107,6 +118,29 @@
this.statusBarHeight = statusBarHeight
this.navBarHeight = navBarHeight
this.totalHeaderHeight = statusBarHeight + navBarHeight
uni.$on('brand:updated', (config) => { this.brandConfig = config })
},
onUnload() {
uni.$off('brand:updated')
},
computed: {
headerStyle() {
return 'padding-top:' + this.statusBarHeight + 'px;background-color:' + this.brandConfig.secondaryColor
},
navStyle() {
return 'height:' + this.navBarHeight + 'px;background-color:' + this.brandConfig.secondaryColor
},
greetingCardStyle() {
return {
backgroundColor: this.brandConfig.secondaryColor,
backgroundImage: this.brandConfig.backgroundImageUrl ? 'url(' + this.brandConfig.backgroundImageUrl + ')' : 'none',
backgroundSize: 'cover',
backgroundPosition: 'center'
}
},
checkinBadgeStyle() {
return { backgroundColor: 'rgba(' + this.brandConfig.primaryColorRgb + ',0.2)', color: this.brandConfig.primaryColor }
}
},
onShow() {
if (!store.isLoggedIn) {
@@ -114,9 +148,11 @@
return
}
this.loadData()
brandStore.fetchConfig()
},
onPullDownRefresh() {
this.loadData().finally(() => { uni.stopPullDownRefresh() })
Promise.all([this.loadData(), brandStore.fetchConfig()])
.finally(() => { uni.stopPullDownRefresh() })
},
methods: {
goToCourseDetail(id) { uni.navigateTo({ url: '/pages/course-detail/course-detail?id=' + id }) },
@@ -193,6 +229,13 @@
.nav-title { font-size: 18px; font-weight: 700; color: #FFFFFF; }
.content-inner { padding: 16px; }
/* 品牌展示 */
.brand-section { display: flex; align-items: center; background: #FFFFFF; border-radius: 16px; padding: 16px 18px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.04); }
.brand-logo { width: 48px; height: 48px; border-radius: 10px; margin-right: 14px; flex-shrink: 0; }
.brand-text { display: flex; flex-direction: column; }
.brand-name { font-size: 18px; font-weight: 700; color: #1E1E1E; }
.brand-slogan { font-size: 12px; color: #9E9E9E; margin-top: 4px; }
/* 个人信息卡片 */
.greeting-card { background: #1A1A1A; border-radius: 20px; padding: 18px 20px 0; color: #FFFFFF; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.06); overflow: hidden; }
.greeting-header { display: flex; justify-content: space-between; align-items: flex-start; }