2026-06-12 11:02:01 +08:00

153 lines
6.8 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="hsd-page">
<swiper class="hsd-swiper" autoplay circular v-if="carousel.length">
<swiper-item v-for="(p, i) in carousel" :key="i">
<image :src="p" mode="aspectFill" class="hsd-swiper-img" />
</swiper-item>
</swiper>
<image v-else :src="picUrl + (info.cover_pic || '')" class="hsd-swiper-img" mode="aspectFill" />
<view class="hsd-main">
<view class="hsd-name">{{ info.service_name }}</view>
<view class="hsd-pricedesc">{{ info.price_desc }}</view>
</view>
<!-- SKU 选择 -->
<view class="hsd-block" v-if="skuList.length">
<view class="hsd-block-tit">选择规格</view>
<view class="hsd-sku-list">
<view class="hsd-sku" :class="{ active: currentSku && currentSku.id === sku.id }"
v-for="sku in skuList" :key="sku.id" @tap="selectSku(sku)">
<view class="hsd-sku-name">{{ sku.sku_name }}</view>
<view class="hsd-sku-price" v-if="isHousekeeping">月薪 ¥{{ sku.month_salary }}</view>
<view class="hsd-sku-price" v-else>定金 ¥{{ sku.deposit }}</view>
</view>
</view>
</view>
<!-- 师傅选择 -->
<view class="hsd-block" v-if="workerList.length">
<view class="hsd-block-tit">选择师傅</view>
<view class="hsd-worker-list">
<view class="hsd-worker" :class="{ active: currentWorker && currentWorker.employee_id === w.employee_id }"
v-for="w in workerList" :key="w.employee_id" @tap="selectWorker(w)">
<image class="hsd-worker-img" :src="w.employee_image || defaultAvatar" mode="aspectFill" />
<view class="hsd-worker-name">{{ w.employee_name }}</view>
<view class="hsd-worker-exp">{{ w.expertise }}</view>
</view>
</view>
</view>
<!-- 详情图 -->
<view class="hsd-block" v-if="detailPics.length">
<view class="hsd-block-tit">服务详情</view>
<image v-for="(p, i) in detailPics" :key="i" :src="p" mode="widthFix" class="hsd-detail-img" />
</view>
<view class="hsd-bottom">
<template v-if="isHousekeeping">
<view class="hsd-bottom-price">月薪 <text>¥{{ currentSku ? currentSku.month_salary : '--' }}</text></view>
<view class="hsd-bottom-btn" @tap="goConsult">咨询预约</view>
</template>
<template v-else>
<view class="hsd-bottom-price">定金 <text>¥{{ currentSku ? currentSku.deposit : '--' }}</text></view>
<view class="hsd-bottom-btn" @tap="goOrder">立即预约</view>
</template>
</view>
</view>
</template>
<script>
import { request, picUrl, NavgateTo } from '@/utils'
import { apiArr } from '@/api/homeService'
export default {
data() {
return {
picUrl,
defaultAvatar: 'https://static.hshuishang.com/defaultTx.png',
id: 0,
info: {},
carousel: [],
detailPics: [],
skuList: [],
workerList: [],
currentSku: null,
currentWorker: null
}
},
onLoad(options) {
this.id = Number(options.id)
this.loadInfo()
},
computed: {
// 家政服务(原长期服务 service_type=2):走咨询签约,不付定金
isHousekeeping() {
return Number(this.info.service_type) === 2
}
},
methods: {
loadInfo() {
request(apiArr.serviceInfo, 'POST', { id: this.id }, {}, false).then(res => {
this.info = res || {}
this.carousel = (res.carousel ? res.carousel.split(',') : []).filter(Boolean).map(p => p.startsWith('http') ? p : this.picUrl + p)
this.detailPics = (res.detail_pic ? res.detail_pic.split(',') : []).filter(Boolean).map(p => p.startsWith('http') ? p : this.picUrl + p)
this.skuList = res.sku_list || []
this.workerList = res.worker_list || []
if (this.skuList.length) this.currentSku = this.skuList[0]
if (this.workerList.length) this.currentWorker = this.workerList[0]
})
},
selectSku(sku) { this.currentSku = sku },
selectWorker(w) { this.currentWorker = w },
goOrder() {
if (!this.currentSku) { uni.showToast({ title: '请选择规格', icon: 'none' }); return }
if (!this.currentWorker) { uni.showToast({ title: '请选择师傅', icon: 'none' }); return }
const params = {
service_info_id: this.id,
sku_id: this.currentSku.id,
employee_id: this.currentWorker.employee_id,
service_name: this.info.service_name,
deposit: this.currentSku.deposit
}
NavgateTo('/packages/homeService/order/index?params=' + encodeURIComponent(JSON.stringify(params)))
},
// 家政服务:先与商家客服沟通签约,不走定金下单
goConsult() {
const supplierId = this.info.supplier_id
if (!supplierId) { uni.showToast({ title: '商家信息缺失', icon: 'none' }); return }
// 客服列表依赖 merchantInfo.id写入当前服务所属商家
const mi = uni.getStorageSync('merchantInfo') || {}
mi.id = supplierId
uni.setStorageSync('merchantInfo', mi)
NavgateTo('/packages/customerService/changeService/index')
}
}
}
</script>
<style scoped>
.hsd-page { background: #f5f5f5; min-height: 100vh; padding-bottom: 130rpx; }
.hsd-swiper, .hsd-swiper-img { width: 100%; height: 520rpx; }
.hsd-main { background: #fff; padding: 24rpx; }
.hsd-name { font-size: 36rpx; font-weight: 600; color: #222; }
.hsd-pricedesc { font-size: 26rpx; color: #FF370B; margin-top: 14rpx; }
.hsd-block { background: #fff; margin-top: 16rpx; padding: 24rpx; }
.hsd-block-tit { font-size: 30rpx; font-weight: 600; color: #222; margin-bottom: 18rpx; }
.hsd-sku-list, .hsd-worker-list { display: flex; flex-wrap: wrap; gap: 18rpx; }
.hsd-sku { border: 1rpx solid #eee; border-radius: 10rpx; padding: 16rpx 24rpx; }
.hsd-sku.active { border-color: #FF370B; background: #FFF1ED; }
.hsd-sku-name { font-size: 28rpx; color: #222; }
.hsd-sku-price { font-size: 24rpx; color: #FF370B; margin-top: 8rpx; }
.hsd-worker { width: 160rpx; display: flex; flex-direction: column; align-items: center; border: 1rpx solid #eee; border-radius: 10rpx; padding: 16rpx 8rpx; }
.hsd-worker.active { border-color: #FF370B; background: #FFF1ED; }
.hsd-worker-img { width: 100rpx; height: 100rpx; border-radius: 50%; background: #f0f0f0; }
.hsd-worker-name { font-size: 26rpx; color: #222; margin-top: 10rpx; }
.hsd-worker-exp { font-size: 20rpx; color: #999; margin-top: 4rpx; }
.hsd-detail-img { width: 100%; display: block; }
.hsd-bottom { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; display: flex; align-items: center; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.04); }
.hsd-bottom-price { flex: 1; font-size: 26rpx; color: #333; }
.hsd-bottom-price text { color: #FF370B; font-size: 36rpx; font-weight: 600; }
.hsd-bottom-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 30rpx; padding: 20rpx 60rpx; border-radius: 44rpx; }
</style>