|
|
@@ -0,0 +1,377 @@
|
|
|
+<template>
|
|
|
+ <view class="ts-page">
|
|
|
+ <!-- 提示 -->
|
|
|
+ <view class="ts-tip">
|
|
|
+ <text class="ts-tip-icon">👩🏫</text>
|
|
|
+ <text class="ts-tip-text">选择规划师服务,专业团队为您审核和定制健康方案</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 服务类型切换 -->
|
|
|
+ <view class="ts-type-bar">
|
|
|
+ <view class="ts-type-item" :class="{ active: serviceType === 'online' }" @click="serviceType = 'online'">
|
|
|
+ <text class="ts-type-icon">💻</text>
|
|
|
+ <text class="ts-type-label">纯线上服务</text>
|
|
|
+ </view>
|
|
|
+ <view class="ts-type-item" :class="{ active: serviceType === 'contact' }" @click="serviceType = 'contact'">
|
|
|
+ <text class="ts-type-icon">📱</text>
|
|
|
+ <text class="ts-type-label">可联系服务</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 服务说明 -->
|
|
|
+ <view class="ts-info-card" v-if="serviceType === 'online'">
|
|
|
+ <text class="ts-info-title">纯线上服务</text>
|
|
|
+ <text class="ts-info-desc">• 规划师通过小程序内消息与您沟通</text>
|
|
|
+ <text class="ts-info-desc">• 双方不见面,不单独微信/电话联系</text>
|
|
|
+ <text class="ts-info-desc">• 所有沟通记录可追溯</text>
|
|
|
+ <text class="ts-info-price">费用包含:方案审核、定制调整、30天在线咨询</text>
|
|
|
+ <text class="ts-info-refund">退费说明:规划师审核前可全额退款;方案确认后不支持退款</text>
|
|
|
+ </view>
|
|
|
+ <view class="ts-info-card" v-else>
|
|
|
+ <text class="ts-info-title">可联系服务</text>
|
|
|
+ <text class="ts-info-desc">• 规划师可通过微信、电话与您联系</text>
|
|
|
+ <text class="ts-info-desc">• 购买后可查看规划师联系方式</text>
|
|
|
+ <text class="ts-info-desc">• 支持一对一深度沟通</text>
|
|
|
+ <text class="ts-info-price">费用包含:方案审核、定制调整、90天专属顾问、微信/电话沟通</text>
|
|
|
+ <text class="ts-info-refund">退费说明:规划师联系前可全额退款;首次沟通后不支持退款</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 规划师列表 -->
|
|
|
+ <view class="ts-list" v-if="guides.length > 0">
|
|
|
+ <view v-for="(g, idx) in guides" :key="getGuideKey(g, idx)"
|
|
|
+ class="ts-card" :class="{ active: selectedGuideId === g.id }"
|
|
|
+ @click="selectGuide(g)">
|
|
|
+ <view class="ts-card-top">
|
|
|
+ <view class="ts-avatar">{{ (g.name || '规划师').charAt(0) }}</view>
|
|
|
+ <view class="ts-card-info">
|
|
|
+ <text class="ts-card-name">{{ g.name || '规划师' }}</text>
|
|
|
+ <text class="ts-card-spec" v-if="g.specialty">{{ g.specialty }}</text>
|
|
|
+ <text class="ts-card-tag" v-if="g.isBound">已绑定家庭</text>
|
|
|
+ </view>
|
|
|
+ <view class="ts-card-check">{{ selectedGuideId === g.id ? '✓' : '' }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="ts-card-desc" v-if="g.description">
|
|
|
+ <text>{{ g.description }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="ts-card-price" v-if="g.price">
|
|
|
+ <text class="ts-price-val">¥{{ g.price }}</text>
|
|
|
+ <text class="ts-price-unit">/ {{ serviceType === 'online' ? '30天' : '90天' }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 空状态 -->
|
|
|
+ <view class="ts-empty" v-if="!loading && guides.length === 0">
|
|
|
+ <text class="ts-empty-icon">🔍</text>
|
|
|
+ <text class="ts-empty-text">暂无可用规划师</text>
|
|
|
+ <text class="ts-empty-hint">请联系管理员为您分配规划师</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 加载中 -->
|
|
|
+ <view class="ts-loading" v-if="loading">
|
|
|
+ <text class="ts-loading-text">加载中...</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 底部按钮 -->
|
|
|
+ <view class="ts-bottom-bar">
|
|
|
+ <button class="ts-btn-submit" :disabled="!selectedGuideId || submitting"
|
|
|
+ @click="confirmSelection">
|
|
|
+ {{ submitting ? '提交中...' : (selectedGuideId ? '确认选择并支付' : '请选择规划师') }}
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getAvailableGuides, getGuidePackage } from '../../utils/api'
|
|
|
+
|
|
|
+export default {
|
|
|
+ data: function() {
|
|
|
+ return {
|
|
|
+ guides: [],
|
|
|
+ selectedGuideId: null,
|
|
|
+ serviceType: 'online',
|
|
|
+ familyId: null,
|
|
|
+ planId: null,
|
|
|
+ memberIds: '',
|
|
|
+ goal: '',
|
|
|
+ loading: false,
|
|
|
+ submitting: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad: function(options) {
|
|
|
+ this.familyId = options.familyId ? parseInt(options.familyId) : null
|
|
|
+ this.planId = options.planId ? parseInt(options.planId) : null
|
|
|
+ this.memberIds = options.memberIds || ''
|
|
|
+ this.goal = options.goal || ''
|
|
|
+ if (!this.familyId) {
|
|
|
+ this.familyId = uni.getStorageSync('familyId') ? parseInt(uni.getStorageSync('familyId')) : null
|
|
|
+ }
|
|
|
+ if (!this.familyId) {
|
|
|
+ uni.showToast({ title: '缺少家庭信息', icon: 'none' })
|
|
|
+ setTimeout(function() { uni.navigateBack() }, 1000)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.loadGuides()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getGuideKey: function(g, idx) {
|
|
|
+ return g.id || ('g' + idx)
|
|
|
+ },
|
|
|
+ loadGuides: function() {
|
|
|
+ var self = this
|
|
|
+ self.loading = true
|
|
|
+ getAvailableGuides({}).then(function(res) {
|
|
|
+ self.loading = false
|
|
|
+ if (res && res.code === 200 && res.data) {
|
|
|
+ var list = res.data instanceof Array ? res.data : []
|
|
|
+ self.guides = list
|
|
|
+ } else {
|
|
|
+ self.guides = []
|
|
|
+ }
|
|
|
+ }).catch(function() {
|
|
|
+ self.loading = false
|
|
|
+ self.guides = []
|
|
|
+ })
|
|
|
+ },
|
|
|
+ selectGuide: function(g) {
|
|
|
+ this.selectedGuideId = g.id
|
|
|
+ },
|
|
|
+ confirmSelection: function() {
|
|
|
+ var self = this
|
|
|
+ if (!self.selectedGuideId || self.submitting) return
|
|
|
+ self.submitting = true
|
|
|
+ // 将选择保存到本地,返回上一页时 health-plan-summary 会读取
|
|
|
+ uni.setStorageSync('healthPlan_teacherId', self.selectedGuideId)
|
|
|
+ uni.setStorageSync('healthPlan_serviceType', self.serviceType)
|
|
|
+ uni.showToast({ title: '已选择规划师', icon: 'success' })
|
|
|
+ setTimeout(function() {
|
|
|
+ self.submitting = false
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 800)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.ts-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #F5F7FA;
|
|
|
+ padding-bottom: 160rpx;
|
|
|
+}
|
|
|
+.ts-tip {
|
|
|
+ margin: 24rpx 30rpx;
|
|
|
+ padding: 20rpx 24rpx;
|
|
|
+ background: #FFF7E6;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+.ts-tip-icon { font-size: 36rpx; }
|
|
|
+.ts-tip-text { font-size: 26rpx; color: #8A6D3B; line-height: 1.6; flex: 1; }
|
|
|
+
|
|
|
+/* 服务类型切换 */
|
|
|
+.ts-type-bar {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+ margin: 24rpx 30rpx;
|
|
|
+}
|
|
|
+.ts-type-item {
|
|
|
+ flex: 1;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx 16rpx;
|
|
|
+ text-align: center;
|
|
|
+ border: 3rpx solid #E5E7EB;
|
|
|
+}
|
|
|
+.ts-type-item.active {
|
|
|
+ border-color: #F97316;
|
|
|
+ background: #FFFBF0;
|
|
|
+}
|
|
|
+.ts-type-icon { font-size: 48rpx; display: block; margin-bottom: 8rpx; }
|
|
|
+.ts-type-label { font-size: 26rpx; font-weight: 600; color: #333; }
|
|
|
+.ts-type-item.active .ts-type-label { color: #F97316; }
|
|
|
+
|
|
|
+/* 服务说明 */
|
|
|
+.ts-info-card {
|
|
|
+ margin: 0 30rpx 24rpx;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ border-left: 6rpx solid #F97316;
|
|
|
+}
|
|
|
+.ts-info-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+}
|
|
|
+.ts-info-desc {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ line-height: 1.8;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+.ts-info-price {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #F97316;
|
|
|
+ font-weight: 600;
|
|
|
+ display: block;
|
|
|
+ margin-top: 12rpx;
|
|
|
+ padding-top: 12rpx;
|
|
|
+ border-top: 1rpx solid #F0F0F0;
|
|
|
+}
|
|
|
+.ts-info-refund {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #999;
|
|
|
+ display: block;
|
|
|
+ margin-top: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 规划师列表 */
|
|
|
+.ts-list {
|
|
|
+ margin: 0 30rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16rpx;
|
|
|
+}
|
|
|
+.ts-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ border: 3rpx solid #E5E7EB;
|
|
|
+ transition: all 0.2s;
|
|
|
+}
|
|
|
+.ts-card.active {
|
|
|
+ border-color: #F97316;
|
|
|
+ background: #FFFBF0;
|
|
|
+}
|
|
|
+.ts-card-top {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 16rpx;
|
|
|
+}
|
|
|
+.ts-avatar {
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ border-radius: 36rpx;
|
|
|
+ background: #ececec;
|
|
|
+ border: 2rpx solid #ddd;
|
|
|
+ color: #888;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+.ts-card.active .ts-avatar {
|
|
|
+ background: #F97316;
|
|
|
+ border-color: #F97316;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+.ts-card-info { flex: 1; }
|
|
|
+.ts-card-name {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+.ts-card.active .ts-card-name { color: #F97316; }
|
|
|
+.ts-card-spec {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #888;
|
|
|
+ display: block;
|
|
|
+ margin-top: 4rpx;
|
|
|
+}
|
|
|
+.ts-card-tag {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #4CAF50;
|
|
|
+ display: block;
|
|
|
+ margin-top: 4rpx;
|
|
|
+}
|
|
|
+.ts-card-check {
|
|
|
+ width: 48rpx;
|
|
|
+ height: 48rpx;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ border: 3rpx solid #d5d5d5;
|
|
|
+ background: #fff;
|
|
|
+ color: transparent;
|
|
|
+ font-size: 26rpx;
|
|
|
+ line-height: 42rpx;
|
|
|
+ text-align: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+.ts-card.active .ts-card-check {
|
|
|
+ background: #F97316;
|
|
|
+ border-color: #F97316;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+.ts-card-desc {
|
|
|
+ margin-top: 12rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #888;
|
|
|
+ line-height: 1.6;
|
|
|
+}
|
|
|
+.ts-card-price {
|
|
|
+ margin-top: 12rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
+ gap: 4rpx;
|
|
|
+}
|
|
|
+.ts-price-val {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #F97316;
|
|
|
+}
|
|
|
+.ts-price-unit {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+/* 空状态 */
|
|
|
+.ts-empty {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ padding: 80rpx 0;
|
|
|
+}
|
|
|
+.ts-empty-icon { font-size: 80rpx; margin-bottom: 16rpx; }
|
|
|
+.ts-empty-text { font-size: 28rpx; color: #bbb; }
|
|
|
+.ts-empty-hint { font-size: 24rpx; color: #ddd; margin-top: 8rpx; }
|
|
|
+
|
|
|
+/* 加载中 */
|
|
|
+.ts-loading {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 60rpx 0;
|
|
|
+}
|
|
|
+.ts-loading-text { font-size: 26rpx; color: #999; }
|
|
|
+
|
|
|
+/* 底部按钮 */
|
|
|
+.ts-bottom-bar {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ background: #fff;
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+ padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
|
+ box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.06);
|
|
|
+}
|
|
|
+.ts-btn-submit {
|
|
|
+ width: 100%;
|
|
|
+ height: 88rpx;
|
|
|
+ line-height: 88rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
+ border: none;
|
|
|
+ font-size: 30rpx;
|
|
|
+ text-align: center;
|
|
|
+ background: linear-gradient(135deg, #F97316, #FB923C);
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+.ts-btn-submit[disabled] { opacity: 0.4; }
|
|
|
+</style>
|