feat: 新增个人身体画像评估与馆主经营助手

把 3 分钟身体状态评估做成独立获客链路,匿名测评后登录认领完整报告,并接入体验预约与今日待办。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
richarjiang
2026-09-11 22:09:19 +08:00
parent b8c0dd6781
commit ab6602e41d
56 changed files with 4640 additions and 25 deletions

View File

@@ -0,0 +1,46 @@
<template>
<view class="page" :style="{ paddingTop: navBarHeight }">
<CustomNavBar title="12 周改善计划" show-back />
<text class="lead">生成后学员可在小程序看到三阶段计划而不是 12 节课</text>
<view class="cta" @tap="create">生成计划</view>
<view v-if="plan" class="card">
<text class="name">{{ plan.title }}</text>
<text v-for="phase in plan.phases" :key="phase.id" class="detail">{{ phase.name }} · {{ phase.lessonStart }}-{{ phase.lessonEnd }} </text>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import CustomNavBar from '../../components/CustomNavBar.vue'
import { getSystemLayout } from '../../utils/system'
import { useAdminStore } from './stores/admin'
import { getErrorMessage } from '../../utils/auth'
import type { TrainingPlanRecord } from '@mp-pilates/shared'
const navBarHeight = ref(`${getSystemLayout().navBarHeight}px`)
const admin = useAdminStore()
const userId = ref('')
const plan = ref<TrainingPlanRecord | null>(null)
onLoad((query) => { userId.value = String(query?.userId || '') })
async function create() {
try {
plan.value = await admin.createTrainingPlan(userId.value, { title: '你的 12 周身体改善计划', weeks: 12 })
uni.showToast({ title: '已生成', icon: 'success' })
} catch (err) {
uni.showToast({ title: getErrorMessage(err, '生成失败'), icon: 'none' })
}
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #fbf9f6; padding: 0 32rpx 60rpx; }
.lead { display: block; padding: 24rpx 8rpx; color: #7a6a5a; font-size: 26rpx; line-height: 1.6; }
.cta { height: 88rpx; border-radius: 999rpx; background: #6b8276; color: #fff; display: flex; align-items: center; justify-content: center; }
.card { margin-top: 24rpx; background: #fff; border-radius: 20rpx; padding: 28rpx; }
.name { display: block; font-size: 30rpx; color: #4a4035; }
.detail { display: block; margin-top: 10rpx; color: #7a6a5a; font-size: 24rpx; }
</style>