初始化参股
This commit is contained in:
438
前端/pages/cases/detail.uvue
Normal file
438
前端/pages/cases/detail.uvue
Normal file
@@ -0,0 +1,438 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<scroll-view class="page-scroll" scroll-y>
|
||||
<!-- 图片画廊 -->
|
||||
<view class="gallery-section">
|
||||
<swiper
|
||||
class="gallery-swiper"
|
||||
circular
|
||||
indicator-dots
|
||||
indicator-color="rgba(255,255,255,0.5)"
|
||||
indicator-active-color="#ffffff"
|
||||
>
|
||||
<swiper-item v-for="(item, index) in caseDetail.afterImages" :key="index">
|
||||
<image
|
||||
class="gallery-image"
|
||||
:src="item"
|
||||
mode="aspectFill"
|
||||
@click="previewImages(index)"
|
||||
></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="gallery-tag">
|
||||
<text class="gallery-tag-text">{{ caseDetail.categoryName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<view class="info-section">
|
||||
<text class="case-title">{{ caseDetail.title }}</text>
|
||||
<view class="case-meta">
|
||||
<text class="case-price">{{ caseDetail.price }}</text>
|
||||
<view class="case-stats">
|
||||
<text class="stat-text">👁 {{ caseDetail.views }}</text>
|
||||
<text class="stat-text">❤ {{ caseDetail.likes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 翻新前后对比 -->
|
||||
<view class="compare-section">
|
||||
<before-after
|
||||
:beforeImage="caseDetail.beforeImages[0] || ''"
|
||||
:afterImage="caseDetail.afterImages[0] || ''"
|
||||
:showTitle="true"
|
||||
></before-after>
|
||||
</view>
|
||||
|
||||
<!-- 详细信息 -->
|
||||
<view class="detail-section">
|
||||
<view class="detail-header">
|
||||
<text class="detail-title">翻新详情</text>
|
||||
</view>
|
||||
|
||||
<view class="detail-list">
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">使用材质</text>
|
||||
<text class="detail-value">{{ caseDetail.material }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">翻新工期</text>
|
||||
<text class="detail-value">{{ caseDetail.duration }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">完成日期</text>
|
||||
<text class="detail-value">{{ caseDetail.createTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-desc">
|
||||
<text class="desc-title">案例描述</text>
|
||||
<text class="desc-content">{{ caseDetail.description }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部间距 -->
|
||||
<view class="bottom-space"></view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="bar-left">
|
||||
<view class="bar-btn" @click="handleFavorite">
|
||||
<text class="bar-icon">{{ isFavorite ? '❤️' : '🤍' }}</text>
|
||||
<text class="bar-label">收藏</text>
|
||||
</view>
|
||||
<view class="bar-btn" @click="handleShare">
|
||||
<text class="bar-icon">📤</text>
|
||||
<text class="bar-label">分享</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bar-right">
|
||||
<view class="contact-btn" @click="handleContact">
|
||||
<text class="contact-text">在线咨询</text>
|
||||
</view>
|
||||
<view class="booking-btn" @click="goToBooking">
|
||||
<text class="booking-text">立即预约</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { getCaseDetail } from '@/api/index.uts'
|
||||
|
||||
// 案例详情类型
|
||||
type CaseDetail = {
|
||||
id : string
|
||||
title : string
|
||||
category : string
|
||||
categoryName : string
|
||||
beforeImages : string[]
|
||||
afterImages : string[]
|
||||
description : string
|
||||
material : string
|
||||
duration : string
|
||||
price : string
|
||||
views : number
|
||||
likes : number
|
||||
createTime : string
|
||||
}
|
||||
|
||||
// 案例ID
|
||||
const caseId = ref('')
|
||||
|
||||
// 案例详情
|
||||
const caseDetail = ref<CaseDetail>({
|
||||
id: '',
|
||||
title: '',
|
||||
category: '',
|
||||
categoryName: '',
|
||||
beforeImages: [],
|
||||
afterImages: [],
|
||||
description: '',
|
||||
material: '',
|
||||
duration: '',
|
||||
price: '',
|
||||
views: 0,
|
||||
likes: 0,
|
||||
createTime: ''
|
||||
})
|
||||
|
||||
// 是否收藏
|
||||
const isFavorite = ref(false)
|
||||
|
||||
// 获取案例详情
|
||||
const fetchCaseDetail = async () => {
|
||||
try {
|
||||
const res = await getCaseDetail(caseId.value)
|
||||
const data = res.data as UTSJSONObject
|
||||
|
||||
caseDetail.value = {
|
||||
id: data['id'] as string,
|
||||
title: data['title'] as string,
|
||||
category: data['category'] as string,
|
||||
categoryName: data['categoryName'] as string,
|
||||
beforeImages: data['beforeImages'] as string[],
|
||||
afterImages: data['afterImages'] as string[],
|
||||
description: data['description'] as string,
|
||||
material: data['material'] as string,
|
||||
duration: data['duration'] as string,
|
||||
price: data['price'] as string,
|
||||
views: data['views'] as number,
|
||||
likes: data['likes'] as number,
|
||||
createTime: data['createTime'] as string
|
||||
} as CaseDetail
|
||||
|
||||
// 更新标题
|
||||
uni.setNavigationBarTitle({
|
||||
title: caseDetail.value.title
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('获取案例详情失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 预览图片
|
||||
const previewImages = (index : number) => {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: caseDetail.value.afterImages
|
||||
})
|
||||
}
|
||||
|
||||
// 收藏
|
||||
const handleFavorite = () => {
|
||||
isFavorite.value = !isFavorite.value
|
||||
uni.showToast({
|
||||
title: isFavorite.value ? '已收藏' : '已取消收藏',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
// 分享
|
||||
const handleShare = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序触发分享
|
||||
// #endif
|
||||
uni.showToast({
|
||||
title: '分享功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
// 在线咨询
|
||||
const handleContact = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: '400-888-8888',
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '拨打电话失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 预约
|
||||
const goToBooking = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/booking/index'
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options : OnLoadOptions) => {
|
||||
caseId.value = options['id'] ?? ''
|
||||
if (caseId.value != '') {
|
||||
fetchCaseDetail()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page {
|
||||
flex: 1;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.page-scroll {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 图片画廊 */
|
||||
.gallery-section {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gallery-swiper {
|
||||
height: 500rpx;
|
||||
}
|
||||
|
||||
.gallery-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gallery-tag {
|
||||
position: absolute;
|
||||
top: 24rpx;
|
||||
left: 24rpx;
|
||||
background-color: rgba(212, 165, 116, 0.9);
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.gallery-tag-text {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 基本信息 */
|
||||
.info-section {
|
||||
background-color: #ffffff;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.case-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.case-meta {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.case-price {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
.case-stats {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.stat-text {
|
||||
font-size: 26rpx;
|
||||
color: #909399;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
/* 对比区域 */
|
||||
.compare-section {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
/* 详细信息 */
|
||||
.detail-section {
|
||||
background-color: #ffffff;
|
||||
margin: 24rpx;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 16rpx 0;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #EBEEF5;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 28rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.detail-desc {
|
||||
padding-top: 16rpx;
|
||||
}
|
||||
|
||||
.desc-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.desc-content {
|
||||
font-size: 28rpx;
|
||||
color: #606266;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
|
||||
/* 底部间距 */
|
||||
.bottom-space {
|
||||
height: 160rpx;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: #ffffff;
|
||||
padding: 16rpx 24rpx;
|
||||
padding-bottom: 32rpx;
|
||||
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.bar-left {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.bar-btn {
|
||||
align-items: center;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.bar-icon {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
font-size: 22rpx;
|
||||
color: #606266;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.bar-right {
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.contact-btn {
|
||||
background-color: #f5f5f5;
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 999rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.contact-text {
|
||||
font-size: 28rpx;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.booking-btn {
|
||||
background-color: #D4A574;
|
||||
padding: 20rpx 48rpx;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.booking-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user