468 lines
9.0 KiB
Vue
468 lines
9.0 KiB
Vue
<template>
|
|
<view class="service-detail-page page-container">
|
|
<!-- 服务封面 -->
|
|
<view class="service-cover">
|
|
<image :src="service.coverImage" mode="aspectFill" class="cover-image" />
|
|
<view class="cover-overlay"></view>
|
|
|
|
<!-- 返回按钮 -->
|
|
<view class="back-btn" @click="goBack">
|
|
<text class="back-icon">←</text>
|
|
</view>
|
|
|
|
<!-- 分享按钮 -->
|
|
<view class="share-btn" @click="handleShare">
|
|
<text class="share-icon">📤</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 服务信息 -->
|
|
<view class="service-info cyber-card">
|
|
<view class="service-header">
|
|
<view class="service-title">{{ service.name }}</view>
|
|
<view class="price-container">
|
|
<text class="price-symbol">¥</text>
|
|
<text class="price-value">{{ service.price }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="service-stats">
|
|
<view class="stat-item">
|
|
<text class="stat-label">评分</text>
|
|
<text class="stat-value neon-text">{{ service.rating }} ⭐</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-label">销量</text>
|
|
<text class="stat-value">{{ service.salesCount }}</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-label">时长</text>
|
|
<text class="stat-value">{{ service.serviceTime }}分钟</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="tags-container">
|
|
<view v-for="tag in service.tags" :key="tag" class="tag-item">
|
|
{{ tag }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 商家信息 -->
|
|
<view class="merchant-card cyber-card">
|
|
<view class="merchant-header">
|
|
<image :src="service.merchantAvatar" class="merchant-avatar" />
|
|
<view class="merchant-info">
|
|
<text class="merchant-name">{{ service.merchantName }}</text>
|
|
<text class="merchant-desc">{{ service.playerCount }}位专业选手</text>
|
|
</view>
|
|
<button class="contact-btn" @click="contactMerchant">联系商家</button>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 服务详情 -->
|
|
<view class="service-detail cyber-card">
|
|
<view class="section-title">服务详情</view>
|
|
<view class="detail-content">
|
|
<text class="detail-text">{{ service.description }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 用户评价 -->
|
|
<view class="evaluations-card cyber-card">
|
|
<view class="section-title">
|
|
用户评价 ({{ service.reviewCount }})
|
|
</view>
|
|
<view class="evaluation-item" v-for="i in 3" :key="i">
|
|
<view class="eval-header">
|
|
<image src="https://picsum.photos/100/100?random=401" class="user-avatar" />
|
|
<view class="user-info">
|
|
<text class="user-name">用户{{ i }}</text>
|
|
<view class="rating">⭐⭐⭐⭐⭐</view>
|
|
</view>
|
|
<text class="eval-time">2天前</text>
|
|
</view>
|
|
<text class="eval-content">服务很棒,选手很专业,下次还会再来!</text>
|
|
</view>
|
|
|
|
<view class="view-all" @click="viewAllEvaluations">
|
|
查看全部评价 >
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 底部操作栏 -->
|
|
<view class="bottom-bar">
|
|
<view class="action-btns">
|
|
<view class="icon-btn" @click="toggleFavorite">
|
|
<text class="icon">{{ isFavorite ? '❤️' : '🤍' }}</text>
|
|
<text class="label">收藏</text>
|
|
</view>
|
|
<view class="icon-btn" @click="contactService">
|
|
<text class="icon">💬</text>
|
|
<text class="label">客服</text>
|
|
</view>
|
|
</view>
|
|
|
|
<button class="order-btn cyber-button" @click="goOrder">
|
|
立即下单
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onLoad } from '@dcloudio/uni-app'
|
|
import { getServiceById } from '../../mock'
|
|
|
|
const service = ref({
|
|
id: 0,
|
|
name: '',
|
|
coverImage: '',
|
|
price: 0,
|
|
originalPrice: 0,
|
|
description: '',
|
|
serviceTime: 0,
|
|
salesCount: 0,
|
|
rating: 5.0,
|
|
reviewCount: 0,
|
|
tags: [],
|
|
merchantName: '',
|
|
merchantAvatar: '',
|
|
playerCount: 0
|
|
})
|
|
|
|
const isFavorite = ref(false)
|
|
|
|
onLoad((options) => {
|
|
if (options.id) {
|
|
const serviceData = getServiceById(parseInt(options.id))
|
|
if (serviceData) {
|
|
service.value = serviceData
|
|
}
|
|
}
|
|
})
|
|
|
|
const goBack = () => {
|
|
uni.navigateBack()
|
|
}
|
|
|
|
const handleShare = () => {
|
|
uni.showShareMenu({
|
|
title: service.value.name,
|
|
path: `/pages/service/detail?id=${service.value.id}`
|
|
})
|
|
}
|
|
|
|
const toggleFavorite = () => {
|
|
isFavorite.value = !isFavorite.value
|
|
uni.showToast({
|
|
title: isFavorite.value ? '已收藏' : '取消收藏',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
|
|
const contactMerchant = () => {
|
|
uni.showToast({ title: '联系商家', icon: 'none' })
|
|
}
|
|
|
|
const contactService = () => {
|
|
uni.showToast({ title: '联系客服', icon: 'none' })
|
|
}
|
|
|
|
const viewAllEvaluations = () => {
|
|
uni.showToast({ title: '查看全部评价', icon: 'none' })
|
|
}
|
|
|
|
const goOrder = () => {
|
|
uni.navigateTo({
|
|
url: `/pages/order/create?serviceId=${service.value.id}`
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.service-detail-page {
|
|
padding-bottom: 160rpx;
|
|
}
|
|
|
|
.service-cover {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 600rpx;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
.cover-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.cover-overlay {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 200rpx;
|
|
background: linear-gradient(180deg, transparent 0%, rgba(10, 14, 39, 0.9) 100%);
|
|
}
|
|
|
|
.back-btn,
|
|
.share-btn {
|
|
position: absolute;
|
|
top: 40rpx;
|
|
width: 72rpx;
|
|
height: 72rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(10, 14, 39, 0.8);
|
|
border: 1px solid rgba(0, 255, 255, 0.3);
|
|
border-radius: 50%;
|
|
backdrop-filter: blur(10rpx);
|
|
}
|
|
|
|
.back-btn {
|
|
left: 24rpx;
|
|
}
|
|
|
|
.share-btn {
|
|
right: 24rpx;
|
|
}
|
|
|
|
.back-icon,
|
|
.share-icon {
|
|
font-size: 36rpx;
|
|
color: #00ffff;
|
|
}
|
|
|
|
.service-info,
|
|
.merchant-card,
|
|
.service-detail,
|
|
.evaluations-card {
|
|
margin: 0 24rpx 24rpx;
|
|
padding: 32rpx;
|
|
}
|
|
|
|
.service-header {
|
|
margin-bottom: 28rpx;
|
|
}
|
|
|
|
.service-title {
|
|
font-size: 36rpx;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.price-container {
|
|
display: flex;
|
|
align-items: baseline;
|
|
}
|
|
|
|
.price-symbol {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #00ffff;
|
|
}
|
|
|
|
.price-value {
|
|
font-size: 56rpx;
|
|
font-weight: bold;
|
|
color: #00ffff;
|
|
text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
|
|
}
|
|
|
|
.service-stats {
|
|
display: flex;
|
|
gap: 48rpx;
|
|
margin-bottom: 28rpx;
|
|
}
|
|
|
|
.stat-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8rpx;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 24rpx;
|
|
color: #7a7e9d;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.tags-container {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 16rpx;
|
|
}
|
|
|
|
.tag-item {
|
|
padding: 8rpx 20rpx;
|
|
background: rgba(0, 255, 255, 0.1);
|
|
border: 1px solid rgba(0, 255, 255, 0.3);
|
|
border-radius: 8rpx;
|
|
font-size: 24rpx;
|
|
color: #00ffff;
|
|
}
|
|
|
|
.merchant-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
}
|
|
|
|
.merchant-avatar {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
border-radius: 50%;
|
|
border: 1px solid rgba(0, 255, 255, 0.3);
|
|
}
|
|
|
|
.merchant-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8rpx;
|
|
}
|
|
|
|
.merchant-name {
|
|
font-size: 30rpx;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.merchant-desc {
|
|
font-size: 24rpx;
|
|
color: #7a7e9d;
|
|
}
|
|
|
|
.contact-btn {
|
|
padding: 16rpx 32rpx;
|
|
background: transparent;
|
|
border: 1px solid #00ffff;
|
|
border-radius: 8rpx;
|
|
font-size: 26rpx;
|
|
color: #00ffff;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 24rpx;
|
|
background: rgba(10, 14, 39, 0.5);
|
|
border-radius: 12rpx;
|
|
}
|
|
|
|
.detail-text {
|
|
font-size: 28rpx;
|
|
line-height: 1.8;
|
|
color: #a0a4c4;
|
|
}
|
|
|
|
.evaluation-item {
|
|
padding: 24rpx 0;
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.1);
|
|
}
|
|
|
|
.eval-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16rpx;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.user-avatar {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.user-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8rpx;
|
|
}
|
|
|
|
.user-name {
|
|
font-size: 26rpx;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.rating {
|
|
font-size: 20rpx;
|
|
}
|
|
|
|
.eval-time {
|
|
font-size: 22rpx;
|
|
color: #7a7e9d;
|
|
}
|
|
|
|
.eval-content {
|
|
font-size: 26rpx;
|
|
line-height: 1.6;
|
|
color: #a0a4c4;
|
|
}
|
|
|
|
.view-all {
|
|
text-align: center;
|
|
padding: 24rpx 0;
|
|
font-size: 26rpx;
|
|
color: #00ffff;
|
|
}
|
|
|
|
.bottom-bar {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 24rpx;
|
|
padding: 24rpx;
|
|
background: linear-gradient(180deg, transparent 0%, rgba(10, 14, 39, 0.95) 20%, rgba(10, 14, 39, 1) 100%);
|
|
border-top: 1px solid rgba(0, 255, 255, 0.2);
|
|
backdrop-filter: blur(20rpx);
|
|
}
|
|
|
|
.action-btns {
|
|
display: flex;
|
|
gap: 32rpx;
|
|
}
|
|
|
|
.icon-btn {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 8rpx;
|
|
}
|
|
|
|
.icon {
|
|
font-size: 40rpx;
|
|
}
|
|
|
|
.label {
|
|
font-size: 22rpx;
|
|
color: #7a7e9d;
|
|
}
|
|
|
|
.order-btn {
|
|
flex: 1;
|
|
height: 88rpx;
|
|
line-height: 88rpx;
|
|
text-align: center;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|