mrr.sj.front/pages/shop/servicesyr-home.nvue

537 lines
12 KiB
Plaintext
Raw Permalink Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view class="store-page">
<!-- 顶部导航栏 -->
<custom-navbar
title="手艺人主页"
:show-back="true"
backgroundColor="#fff"
></custom-navbar>
<!-- 手艺人信息卡片 -->
<view class="store-card" v-if="syrdetail.video">
<!-- 手艺人视频/图片 -->
<view class="store-media">
<video
class="store-bg"
id="syrVideo"
:auto-play="true"
:muted="false"
object-fit="cover"
:src="syrdetail.video"></video>
<image class="play-icon" src="/static/images/play.png" mode="aspectFit"></image>
</view>
</view>
<!-- 手艺人基本信息 -->
<view class="store-info"
:class="!syrdetail.video ? 'no-video' : ''">
<view class="store-title">{{syrdetail.name}}</view>
<!-- <view class="store-rating">
<view class="rating-stars">
<image
v-for="n in 5"
:key="n"
:src="n <= 4 ? '/static/images/star-full.png' : '/static/images/star-half.png'"
mode="aspectFit"
class="star-icon"
></image>
<text class="rating-score">5.0分</text>
</view>
<view class="store-row">
<view class="store-rank">
<text class="rank-label">人气榜</text>
<text class="rank-num">第2名</text>
</view>
<view class="store-cert">
<image src="/static/images/sign-grew.png" mode="aspectFit" class="cert-icon"></image>
<text class="cert-text">证书认证</text>
</view>
</view>
</view> -->
<image
:src="syrdetail.head_photo"
v-if="syrdetail.head_photo"
class="store-img"
mode="aspectFill"></image>
</view>
<!-- 店铺详细信息 -->
<view class="store-detail">
<!-- 标签切换 -->
<view class="tab-header">
<view
class="tab-item"
:class="{'active': activeTab === 'info'}"
@click="switchTab('info')"
>
<text class="tab-lable">手艺人信息</text>
<view class="tab-line"></view>
</view>
<view
class="tab-item tab-left"
:class="{'active': activeTab === 'all'}"
@click="switchTab('all')"
>
<text class="tab-lable">全部</text>
<view class="tab-line"></view>
</view>
</view>
<!-- 门店信息内容 -->
<view class="info-content" v-if="activeTab === 'info'">
<!-- 地址信息 -->
<view class="info-item">
<text class="info-label">所在地</text>
<text class="info-text">{{syrdetail.dependency}}</text>
</view>
<view class="info-item">
<text class="info-label">所属门店</text>
<text class="info-text">{{syrdetail.for_shop}}</text>
</view>
<view class="info-item">
<text class="info-label">简介</text>
<text class="info-text">{{syrdetail.detail}}</text>
</view>
<!-- 健康证 -->
<view class="info-item">
<!-- 健康证 -->
<text class="info-label health">健康证</text>
<text class="check-text" @click="lookHealth(syrdetail.health_card)">点击查看</text>
</view>
<!-- 资质证书 -->
<view class="info-item" v-if="syrdetail.qualifications && syrdetail.qualifications.length != 0">
<!-- 资质证书 -->
<text class="info-label health">资质证书</text>
<text class="check-text" @click="previewImage(syrdetail.qualifications)">点击查看</text>
</view>
<!-- 营业执照 -->
<view class="info-item" v-if="syrdetail.uscc_photo">
<!-- 营业执照 -->
<text class="info-label health">营业执照</text>
<text class="check-text" @click="lookHealth(syrdetail.uscc_photo)">点击查看</text>
</view>
<!-- 门头照片 -->
<view class="info-item" v-if="syrdetail.shop_photo">
<!-- 门头照片 -->
<text class="info-label health">门头照片</text>
<text class="check-text" @click="lookHealth(syrdetail.shop_photo)">点击查看</text>
</view>
<!-- 照片墙 -->
<!-- <view class="photo-wall">
<text class="wall-title">照片墙</text>
<scroll-view class="photo-scroll" scroll-x>
<view class="photo-list">
<image
v-for="(photo, index) in photoList"
:key="index"
:src="photo"
mode="heightFix"
class="photo-item"
@click="previewImage(index)"
></image>
</view>
</scroll-view>
</view> -->
</view>
<view class="all-cont" v-if="activeTab === 'all'">
<service-grid
:services="services"
@serviceclick="goToDetail"
page-type="nvue"
width="320rpx"
/>
</view>
</view>
<view v-if="isLoading && activeTab === 'all'" class="loading">
<text class="loading-text">加载中...</text></view>
<view v-if="!isLoading && activeTab === 'all'" class="loading">
<text class="loading-text">没有更多了</text></view>
</view>
</template>
<script>
import ServiceGrid from '@/components/service-grid/service-grid.vue'
import request from '../../utils/request'
import _public from '../../utils/public'
export default {
components: {
ServiceGrid
},
data() {
return {
activeTab: 'info',
syrdetail: {},
services: [],
isLoading: true,
videoContext: null,
queryData: {
publish_user_id: null,
page: 1,
limit: 20
}
}
},
async onLoad(options) {
console.log(options)
// const beforeShopInfo = await request.post('/user/getuser',{type: 3});
// const nowShopInfo = await request.post('/sj/sjdetail',{id: beforeShopInfo.data.id});
// this.queryData.sjid = nowShopInfo.data.id;
this.queryData.publish_user_id = options.id;
this.getShopDetail(options.id);
},
mounted() {
this.videoContext = uni.createVideoContext('syrVideo', this); // 绑定 video 实例
},
onHide() {
this.videoContext.pause();
},
onPullDownRefresh() {
console.log('触发下拉刷新');
if(this.activeTab == 'info') {
this.getShopDetail(this.queryData.publish_user_id)
}else if(this.activeTab == 'all') {
this.queryData.page = 1;
this.getServerList();
setTimeout(() => {
console.log('刷新完毕')
uni.stopPullDownRefresh();
}, 1000);
}
},
onReachBottom() {
if(!this.isLoading) return;
this.queryData.page = this.queryData.page+1;
this.getServerList();
},
methods: {
// 获取手艺人详情
getShopDetail(id) {
request.post('/sj/syrdetail',{id}).then(res=>{
this.syrdetail = res.data;
}).catch(err=>{
console.log(err)
})
},
// 获取手艺人下的服务列表
getServerList() {
request.post('/sj/syrserver',this.queryData).then(res=>{
let data = res.data;
data.forEach(async (service,i)=>{
const sjdiscount = await request.post('/sj/getsjdiscount',{id: service.first_class_id});
service.server_price = _public.roundUpToTwoDecimals(Number(service.server_price),sjdiscount.data.ratio)
})
this.services = [...this.services,...data];
if(res.count == this.services.length) {
this.isLoading = false;
}
})
},
// 查看详情
goToDetail(item) {
uni.navigateTo({
url: `/pages/shop/service-detail?id=${item.id}`
// url: `/pages/detail-ceshi/detail-ceshi?id=${item.id}`
})
},
switchTab(tab) {
this.activeTab = tab;
if(this.activeTab == 'all') {
this.queryData.page = 1;
this.getServerList();
}
},
handleCall(account) {
uni.makePhoneCall({
phoneNumber: account
})
},
lookHealth(url) {
let urls = []
urls[0] = url
// TODO: 查看营业执照
uni.previewImage({
urls: urls
})
},
previewImage(urls) {
uni.previewImage({
urls: urls
})
},
// previewImage(index) {
// uni.previewImage({
// urls: this.photoList,
// current: index
// })
// }
}
}
</script>
<style>
.store-card {
height: 602rpx;
background: #999;
margin-bottom: 24rpx;
}
.store-media,.store-bg {
height: 602rpx;
width: 750rpx;
position: relative;
}
.play-icon {
width: 96rpx;
height: 96rpx;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.5);
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
}
.store-info {
background-color: #FFFFFF;
border-radius: 16rpx;
margin: -48rpx 24rpx 24rpx;
padding: 24rpx 24rpx 56rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.50);
z-index: 9;
}
.store-info.no-video {
margin-top: 60rpx;
}
.store-title {
font-size: 32rpx;
color: rgba(0, 0, 0, 0.90);
font-weight: 400;
margin-bottom: 12rpx;
padding-right: 174rpx;
}
.store-rating {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
position: relative;
}
.rating-stars {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
.store-row {
display: flex;
align-items: center;
}
.star-icon {
width: 20rpx;
height: 20rpx;
margin-right: 8rpx;
background-color: #333333;
}
.rating-score {
font-size: 24rpx;
color: #FFA500;
margin-left: 22rpx;
}
.store-rank {
display: flex;
align-items: center;
}
.rank-label,.rank-num {
font-size: 20rpx;
font-weight: 400;
color: #FF0000;
}
.rank-num {
margin-left: 8rpx;
}
.store-cert {
margin-left: 24rpx;
display: flex;
align-items: center;
padding: 2rpx 8rpx;
border-radius: 4rpx;
background-color: rgba(0, 0, 0, 0.10);
}
.cert-icon {
width: 24rpx;
height: 24rpx;
margin-right: 4rpx;
}
.cert-text {
font-size: 16rpx;
color: #999999;
}
.store-img {
position: absolute;
top: -26rpx;
right: 24rpx;
width: 154rpx;
height: 154rpx;
border-radius: 16rpx;
}
.store-detail {
background: #FFFFFF;
margin: 0 24rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.50);
}
.tab-header {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
}
.tab-item {
position: relative;
padding: 24rpx 0 10rpx;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.tab-left {
margin-left: 252rpx;
}
.tab-lable {
font-size: 28rpx;
font-weight: 500;
color: #666666;
}
.tab-item.active .tab-lable {
2026-06-02 11:39:23 +08:00
color: #FF4767;
2026-03-24 11:45:13 +08:00
}
.tab-line {
width: 32rpx;
height: 6rpx;
border-radius: 3rpx;
margin-top: 10rpx;
}
.tab-item.active .tab-line {
2026-06-02 11:39:23 +08:00
background: #FF4767;
2026-03-24 11:45:13 +08:00
}
.info-content {
padding: 0 24rpx;
}
.info-item {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
padding: 24rpx 0;
border-bottom: 1rpx solid #F0F0F0;
}
.check-text {
font-size: 28rpx;
2026-06-02 11:39:23 +08:00
color: #FF4767;
2026-03-24 11:45:13 +08:00
margin-left: 12rpx;
}
.photo-wall {
margin-top: 24rpx;
}
.info-label {
width: 124rpx;
font-size: 28rpx;
color: #333333;
font-weight: 500;
/* #ifdef MP-WEIXIN || H5 */
flex-shrink: 0;
/* #endif */
}
.health {
margin-right: 0rpx;
}
.info-text {
width: 532rpx;
font-size: 28rpx;
color: #333333;
font-weight: 400;
}
/* #ifdef APP-IOS */
/* .info-text {
white-space: normal;
} */
/* #endif */
/* #ifdef APP-ANDROID */
/* .info-text {
lines: 0;
} */
/* #endif */
.wall-title {
font-size: 28rpx;
color: #333333;
font-weight: 500;
margin-bottom: 24rpx;
}
.photo-list {
padding: 32rpx 0;
display: flex;
flex-flow: row nowrap;
}
.photo-item {
height: 112rpx;
margin-right: 24rpx;
border-radius: 12rpx;
/* #ifdef MP-WEIXIN || H5 */
flex-shrink: 0;
/* #endif */
}
.photo-item:last-child {
margin-right: 0;
}
.all-cont {
padding: 24rpx 16rpx 0;
}
.loading {
text-align: center;
padding: 10px;
}
.loading-text {
font-size: 14px;
color: #999;
}
/* 小程序适配 */
/* #ifdef MP-WEIXIN */
.store-card {
margin-top: calc(-88rpx - var(--status-bar-height) - constant(safe-area-inset-top) );
margin-top: calc(-88rpx - var(--status-bar-height) - env(safe-area-inset-top));
}
/* #endif */
</style>