feat: 添加教练详情页面及相关数据模型

This commit is contained in:
richarjiang
2026-04-13 17:08:17 +08:00
parent 1f45c3dc3f
commit f78cdcc9d1
4 changed files with 753 additions and 62 deletions

View File

@@ -1,96 +1,279 @@
<template>
<view class="about-section">
<!-- 老师介绍 -->
<view class="about-card">
<view class="card-header">
<view class="header-dot" />
<text class="header-title">老师介绍</text>
<view class="section-header">
<view>
<text class="section-eyebrow">Teacher Spotlight</text>
<text class="section-title">老师介绍</text>
</view>
<image class="teacher-img" :src="teacherImage" mode="widthFix" @tap="previewImages([teacherImage], 0)" />
<text class="section-more" @tap="goToDetail">查看详情</text>
</view>
<!-- 场馆介绍 -->
<view class="about-card">
<view class="card-header">
<view class="header-dot" />
<text class="header-title">场馆介绍</text>
<view class="teacher-card" @tap="goToDetail">
<view class="teacher-main">
<view class="cover-wrap">
<image class="teacher-cover" :src="teacher.avatar" mode="aspectFill" />
<view class="cover-badge">
<text class="cover-badge-text">{{ teacher.badges[0] }}</text>
</view>
</view>
<view class="teacher-content">
<view class="teacher-heading">
<view>
<view class="name-row">
<text class="teacher-name">{{ teacher.name }}</text>
<text class="teacher-tag">{{ teacher.badges[1] }}</text>
</view>
<text class="teacher-title">{{ teacher.title }}</text>
</view>
</view>
<view class="specialty-row">
<text v-for="item in teacher.specialties" :key="item" class="specialty-pill">{{ item }}</text>
</view>
<text class="teacher-intro">{{ teacher.intro }}</text>
</view>
</view>
<view class="studio-gallery">
<image v-for="(img, idx) in studioImages" :key="idx" class="gallery-img" :src="img" mode="widthFix"
@tap="previewImages(studioImages, idx)" />
<view class="credential-box">
<text class="credential-label">认证背景</text>
<text class="credential-text">{{ certificationSummary }}</text>
</view>
<view class="action-row">
<view class="secondary-btn" @tap.stop="goToDetail">
<text class="secondary-btn-text">查看详情</text>
</view>
<view class="primary-btn" @tap.stop="goToBooking">
<text class="primary-btn-text">立即预约</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
const teacherImage = 'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/mp/images/person_desc.jpeg'
import { computed } from 'vue'
import { irisProfile } from '../utils/teacher'
const studioImages = [
'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/mp/images/place_1.jpg',
'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/mp/images/place_2.jpg',
'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/mp/images/place_3.jpg',
'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/mp/images/place_4.jpg',
]
const teacher = irisProfile
function previewImages(urls: string[], current: number) {
uni.previewImage({
current,
urls,
})
const certificationSummary = computed(() => teacher.certifications.slice(0, 2).join(' · '))
function goToDetail() {
uni.navigateTo({ url: `/pages/teacher/detail?id=${teacher.id}` })
}
function goToBooking() {
uni.switchTab({ url: '/pages/booking/index' })
}
</script>
<style lang="scss" scoped>
.about-section {
padding: 16rpx 24rpx 0;
padding: 20rpx 24rpx 0;
}
.section-header {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 18rpx;
}
.section-eyebrow {
display: block;
font-size: 20rpx;
letter-spacing: 3rpx;
text-transform: uppercase;
color: #b99b8c;
margin-bottom: 8rpx;
}
.section-title {
font-size: 34rpx;
font-weight: 700;
color: #2f2723;
}
.section-more {
font-size: 24rpx;
color: #c36d52;
padding: 10rpx 0;
}
.teacher-card {
display: flex;
flex-direction: column;
gap: 16rpx;
gap: 18rpx;
background:
radial-gradient(circle at top right, rgba(226, 198, 179, 0.42), transparent 32%),
linear-gradient(135deg, #fffdfb 0%, #f8f2ee 46%, #f2e8e2 100%);
border-radius: 30rpx;
padding: 22rpx;
box-shadow: 0 18rpx 38rpx rgba(126, 98, 84, 0.09);
}
.about-card {
background: #ffffff;
border-radius: 20rpx;
.teacher-main {
display: flex;
gap: 22rpx;
align-items: stretch;
}
.cover-wrap {
position: relative;
width: 188rpx;
height: 248rpx;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
padding: 28rpx 24rpx 24rpx;
flex-shrink: 0;
background: #eadfd7;
}
.card-header {
.teacher-cover {
width: 100%;
height: 100%;
}
.cover-badge {
position: absolute;
left: 14rpx;
bottom: 14rpx;
border-radius: 999rpx;
padding: 8rpx 16rpx;
background: rgba(41, 34, 30, 0.74);
backdrop-filter: blur(12rpx);
}
.cover-badge-text {
font-size: 20rpx;
font-weight: 600;
color: #fff7f3;
}
.teacher-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.teacher-heading {
margin-bottom: 14rpx;
}
.name-row {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 20rpx;
gap: 10rpx;
margin-bottom: 8rpx;
}
.header-dot {
width: 10rpx;
height: 36rpx;
border-radius: 5rpx;
background: linear-gradient(180deg, #D4A59A, #C08B7E);
}
.header-title {
font-size: 32rpx;
.teacher-name {
font-size: 38rpx;
line-height: 1;
font-weight: 700;
color: #222;
color: #2e2521;
}
.teacher-tag {
font-size: 18rpx;
line-height: 1;
color: #a85d44;
background: rgba(221, 150, 118, 0.18);
border-radius: 999rpx;
padding: 8rpx 12rpx;
}
.teacher-title {
font-size: 24rpx;
color: #7f6659;
}
.specialty-row {
display: flex;
flex-wrap: wrap;
gap: 10rpx;
margin-bottom: 14rpx;
}
.specialty-pill {
padding: 8rpx 16rpx;
border-radius: 999rpx;
background: rgba(92, 126, 151, 0.12);
color: #5a7a8b;
font-size: 20rpx;
font-weight: 600;
}
.teacher-intro {
font-size: 22rpx;
line-height: 1.7;
color: #5e5048;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.credential-box {
padding: 16rpx 18rpx;
border-radius: 18rpx;
background: rgba(255, 255, 255, 0.72);
border: 1rpx solid rgba(190, 161, 145, 0.22);
}
.credential-label {
display: block;
font-size: 18rpx;
letter-spacing: 2rpx;
color: #b19486;
margin-bottom: 8rpx;
}
.credential-text {
font-size: 20rpx;
line-height: 1.6;
color: #6a5a51;
}
.action-row {
display: flex;
gap: 12rpx;
}
.secondary-btn,
.primary-btn {
height: 72rpx;
border-radius: 999rpx;
display: flex;
align-items: center;
justify-content: center;
}
.secondary-btn {
width: 148rpx;
border: 1rpx solid rgba(139, 113, 99, 0.24);
background: rgba(255, 255, 255, 0.8);
}
.primary-btn {
flex: 1;
background: linear-gradient(135deg, #ff7654 0%, #ff4d38 100%);
box-shadow: 0 14rpx 24rpx rgba(255, 92, 69, 0.24);
}
.secondary-btn-text {
font-size: 24rpx;
font-weight: 600;
color: #684d40;
}
.primary-btn-text {
font-size: 26rpx;
font-weight: 700;
color: #ffffff;
letter-spacing: 1rpx;
}
.teacher-img {
width: 100%;
border-radius: 12rpx;
}
.studio-gallery {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.gallery-img {
width: 100%;
border-radius: 12rpx;
}
</style>