init: 初始化

This commit is contained in:
richarjiang
2026-04-04 10:03:06 +08:00
parent 7a06b5e336
commit 817d5a85c5
14 changed files with 478 additions and 394 deletions

View File

@@ -1,57 +1,34 @@
<template>
<view class="studio-info card">
<!-- Photo Swiper -->
<swiper
<view class="studio-info">
<!-- Horizontal photo strip -->
<scroll-view
v-if="studioInfo?.photos?.length"
class="photo-swiper"
:indicator-dots="studioInfo.photos.length > 1"
:autoplay="true"
:interval="4000"
:duration="500"
indicator-color="rgba(255,255,255,0.5)"
indicator-active-color="#c9a87c"
circular
scroll-x
class="photo-strip"
:show-scrollbar="false"
>
<swiper-item
v-for="(photo, idx) in studioInfo.photos"
:key="idx"
>
<view class="photo-strip-inner">
<image
class="photo"
v-for="(photo, idx) in studioInfo.photos"
:key="idx"
class="strip-photo"
:src="photo"
mode="aspectFill"
@tap="previewPhoto(idx)"
/>
</swiper-item>
</swiper>
</view>
</scroll-view>
<!-- Placeholder when no photos -->
<view v-else class="photo-placeholder">
<text class="placeholder-icon">🏃</text>
<text class="placeholder-text">专业普拉提工作室</text>
</view>
<!-- Info rows -->
<view class="info-rows">
<!-- Address -->
<view class="info-row" @tap="handleAddressTap">
<view class="icon-wrap">
<text class="iconfont">📍</text>
</view>
<text class="info-text address-text">
<!-- Address + Phone row -->
<view class="location-row">
<view class="location-left" @tap="handleAddressTap">
<text class="location-icon">📍</text>
<text class="location-text">
{{ studioInfo?.address || '地址加载中…' }}
</text>
<text class="info-action">
{{ studioInfo?.latitude ? '导航' : '复制' }}
</text>
</view>
<!-- Phone -->
<view class="info-row" @tap="handlePhoneTap">
<view class="icon-wrap">
<text class="iconfont">📞</text>
</view>
<text class="info-text">{{ studioInfo?.phone || '—' }}</text>
<text class="info-action">拨打</text>
<view class="phone-btn" @tap="handlePhoneTap">
<text class="phone-icon">📞</text>
</view>
</view>
</view>
@@ -64,6 +41,14 @@ const props = defineProps<{
studioInfo: StudioConfig | null
}>()
function previewPhoto(index: number) {
if (!props.studioInfo?.photos?.length) return
uni.previewImage({
current: index,
urls: props.studioInfo.photos,
})
}
function handleAddressTap() {
if (!props.studioInfo) return
@@ -73,8 +58,8 @@ function handleAddressTap() {
uni.openLocation({
latitude,
longitude,
name: name || '普拉提工作室',
address: address,
name: name || 'Focus Core',
address,
fail() {
copyAddress()
},
@@ -109,95 +94,73 @@ function handlePhoneTap() {
<style lang="scss" scoped>
.studio-info {
margin: 24rpx 24rpx 0;
overflow: hidden;
}
.card {
background: #ffffff;
border-radius: 16rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
.photo-swiper {
/* ── Photo strip ── */
.photo-strip {
width: 100%;
height: 360rpx;
border-radius: 16rpx 16rpx 0 0;
overflow: hidden;
padding: 24rpx 0;
}
.photo {
width: 100%;
height: 100%;
}
.photo-placeholder {
width: 100%;
height: 280rpx;
background: linear-gradient(135deg, #f0f0f0, #e8e8e8);
.photo-strip-inner {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex-direction: row;
gap: 16rpx;
border-radius: 16rpx 16rpx 0 0;
padding: 0 24rpx;
width: max-content;
}
.placeholder-icon {
font-size: 80rpx;
}
.placeholder-text {
font-size: 28rpx;
color: #999;
}
.info-rows {
padding: 16rpx 32rpx;
}
.info-row {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
gap: 16rpx;
&:last-child {
border-bottom: none;
}
}
.icon-wrap {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
.strip-photo {
width: 240rpx;
height: 160rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
.iconfont {
font-size: 36rpx;
/* ── Location row ── */
.location-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx 28rpx;
gap: 24rpx;
}
.info-text {
.location-left {
display: flex;
align-items: flex-start;
gap: 12rpx;
flex: 1;
min-width: 0;
}
.location-icon {
font-size: 28rpx;
color: #333;
line-height: 1.4;
}
.address-text {
font-size: 26rpx;
}
.info-action {
font-size: 24rpx;
color: #c9a87c;
padding: 6rpx 16rpx;
border: 1rpx solid #c9a87c;
border-radius: 24rpx;
flex-shrink: 0;
margin-top: 4rpx;
}
.location-text {
font-size: 26rpx;
color: #666;
line-height: 1.5;
word-break: break-all;
}
.phone-btn {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
background: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.phone-icon {
font-size: 36rpx;
color: #4CAF50;
}
</style>