daoji_h5/pages/service.vue

794 lines
18 KiB
Vue
Raw 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="pages-home" v-if="isLoad">
<!-- #ifndef H5 -->
<uni-nav-bar :fixed="true" :shadow="false" :statusBar="true" title="首页" color="#ffffff"
:backgroundColor="primaryColor">
</uni-nav-bar>
<view :style="{height:`${configInfo.navBarHeight}px`}"></view>
<!-- #endif -->
<view :class="[{'rel':banner.length >0}]" :style="{height:banner.length > 0?`484rpx`:`84rpx`}">
<banner @change="goBanner" :list="banner" :margin="0" :autoplay="true" :indicatorActiveColor="primaryColor"
:dotWidth="20" :dotBottom="30" v-if="banner.length > 0">
</banner>
<view class="search-box flex-center fill-base"
:class="[{'mt-md':banner.length ==0},{'abs':banner.length>0}]" :style="{ color: primaryColor }">
<view style="width: 100%;">
<view class="servetip pl-lg pr-lg pt-sm pb-sm">
<view @tap.stop="toJump('servefc', index)" v-for="(item, index) in servefc"
:key="index" class="servefc">
<i class="iconfont" :class="item.icon"></i>
<span class="ml-sm">{{ item.text }}</span>
</view>
</view>
</view>
</view>
</view>
<!-- 分类 -->
<view class="fill-base pl-md pr-md" style="overflow: hidden;" v-if="service_cate.length>0">
<column @change="goCate" :list="service_cate" :indicatorActiveColor="primaryColor" :colNum="5" :rowNum="2">
</column>
</view>
<view class="fill-base pl-lg pr-lg pb-lg" v-if="recommend_list && recommend_list.length > 0">
<view @tap.stop="$util.goUrl({url: `/pages/technician`,openType: `reLaunch`})" class="flex-between pb-lg">
<view class="f-st-title text-bold flex-between">
<view class="mr-md" style="width: 15px;height: 17px;">
<image src="/static/img/icon_technician.png" class="van-img" style="object-fit: cover;"></image>
</view>
{{`推荐${$t('action.attendantName')}`}}
</view>
<view class="flex-y-center f-caption c-caption">查看更多<i class="iconfont icon-right"
style="font-size: 24rpx;"></i></view>
</view>
<scroll-view scroll-x class="recommend-technician">
<block v-for="(item,index) in recommend_list" :key="index">
<view @tap.stop="toTechnician(index)" class="recommend-item type-1" v-if="recommend_style == 1">
<!-- #ifdef H5 -->
<view class="cover radius-16">
<view class="h5-image cover radius-16"
:style="{ backgroundImage : `url('${item.work_img}')`}">
</view>
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<image mode="aspectFill" lazy-load class="cover radius-16" :src="item.work_img"></image>
<!-- #endif -->
<view class="flex-center f-desc c-title text-bold mt-md">
<view class="ellipsis">{{item.coach_name}}</view>
</view>
<view class="flex-center">
<view class="new-technician flex-center f-icontext radius"
:style="{height:`33rpx`,width:`80rpx`,color:primaryColor,border:`1rpx solid ${primaryColor}`}" v-if="item.is_new">新人
</view>
<view class="f-icontext c-caption" v-else>30天接单{{item.order_count||0}}
</view>
</view>
</view>
<view @tap.stop="toTechnician(index)" class="recommend-item type-2 pd-md"
v-if="recommend_style == 2">
<view class="flex-center pb-sm">
<!-- #ifdef H5 -->
<view class="cover radius">
<view class="h5-image cover radius"
:style="{ backgroundImage : `url('${item.work_img}')`}">
</view>
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<image mode="aspectFill" lazy-load class="cover radius" :src="item.work_img"></image>
<!-- #endif -->
<view class="flex-1 ml-sm">
<view class="f-desc ellipsis">{{item.coach_name}}</view>
<view class="flex-y-baseline" style="margin-top: 4rpx;">
<i class="iconfont iconyduixingxingshixin icon-font-color"></i>
<view class="star-text flex-y-center f-caption">{{item.star}}</view>
</view>
</view>
</view>
<view class="flex-center">
<view class="new-technician flex-center f-icontext radius"
:style="{height:`33rpx`,width:`80rpx`,color:primaryColor,border:`1rpx solid ${primaryColor}`}" v-if="item.is_new">新人
</view>
<view class="f-icontext c-caption" v-else>30天接单{{item.order_count||0}}
</view>
</view>
</view>
</block>
</scroll-view>
</view>
<view class="fill-base pl-lg pr-lg">
<view class="fill-base flex-between">
<view class="f-st-title text-bold flex-between">
<view class="mr-md" style="width: 15px;height: 17px;">
<image src="/static/img/icon_project.png" class="van-img" style="object-fit: cover;"></image>
</view>
推荐项目
</view>
</view>
</view>
<view class="fill-base pd-lg b-1px-b" v-for="(item,index) in list.data" :key="index">
<service-list-item :info="item"></service-list-item>
</view>
<load-more :noMore="list.current_page >= list.last_page && list.data.length > 0" :loading="loading"
v-if="loading">
</load-more>
<abnor v-if="!loading && list.data.length <= 0 && list.current_page == 1"></abnor>
<view class="space-footer"></view>
<uni-popup ref="coupon_item" type="center" :maskClick="false">
<view class="coupon-popup flex-center">
<!-- #ifdef H5 -->
<view class="h5-image bg-img"
:style="{ backgroundImage : `url('https://lbqnyv2.migugu.com/bianzu3.png')`}">
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<image mode="aspectFill" lazy-load class="bg-img" src="https://lbqnyv2.migugu.com/bianzu3.png"></image>
<!-- #endif -->
<i @tap.stop="$refs.coupon_item.close()" class="iconfont icon-close c-base"></i>
</image>
<view class="coupon-info flex-center flex-column">
<view class="tops flex-center flex-column">
<view class="">
成功领取
</view>
<view class="">
卡券将放入“我的-我的卡券”
</view>
</view>
<view class="lists flex-center">
<scroll-view scroll-y style="width: 420rpx;height:100%;">
<view class="list flex-between" v-for="(item, index) in couponList" :key="index">
<image src="https://lbqny.migugu.com/admin/anmo/coupon/coupon.png" mode="aspectFill">
</image>
<view class="flex-between">
<view class="flex-center flex-column">
<view class="price">
{{item.discount}}
</view>
<view class="price_text">
{{item.full*1>0?`满${item.full}可用`:`立减`}}
</view>
</view>
<view class="title flex-y-center">
<view class="ellipsis-3">
{{item.title}}
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="btns flex-center" @tap.stop="userGetCoupon">
<view class="flex-center">
领取到卡包
</view>
</view>
</view>
</uni-popup>
<view :style="{height: `${configInfo.tabbarHeight}px`}"></view>
<tabbar :cur="1"></tabbar>
<!-- #ifdef APP-PLUS -->
<login-info></login-info>
<!-- #endif -->
</view>
</template>
<script>
import {
mapState,
mapActions,
mapMutations
} from "vuex"
import siteInfo from '@/siteinfo.js';
import serviceListItem from "@/components/service-list-item.vue"
import tabbar from "@/components/tabbar.vue"
export default {
components: {
serviceListItem,
tabbar
},
data() {
return {
couponList: [], //优惠券
isLoad: false,
options: {},
loading: true,
lockTap: false,
servefc: [{
icon: 'icon-kzj',
text: '实名认证'
}, {
icon: 'icon-kpk',
text: '爽约包赔'
}, {
icon: 'icon-sybp',
text: '超时秒退'
}, {
icon: 'icon-kzz',
text: '资质证书'
}],
}
},
computed: mapState({
pageActive: state => state.service.pageActive,
activeIndex: state => state.service.activeIndex,
tabList: state => state.service.tabList,
param: state => state.service.param,
list: state => state.service.list,
banner: state => state.service.banner,
service_cate: state => state.service.service_cate,
recommend_list: state => state.service.recommend_list,
recommend_style: state => state.service.recommend_style,
primaryColor: state => state.config.configInfo.primaryColor,
subColor: state => state.config.configInfo.subColor,
configInfo: state => state.config.configInfo,
autograph: state => state.user.autograph,
userInfo: state => state.user.userInfo,
location: state => state.user.location,
isGzhLogin: state => state.user.isGzhLogin,
haveShieldOper: state => state.user.haveShieldOper,
}),
async onLoad(options) {
//this.$util.showLoading()
options = await this.updateCommonOptions(options)
this.options = options
uni.onNetworkStatusChange((res) => {
let {
isConnected
} = res
if (isConnected && !this.pageActive) {
this.initIndex()
return
}
})
await this.initIndex()
},
async onShow() {
// #ifdef H5
if (this.$jweixin.isWechat()) {
await this.$jweixin.initJssdk();
this.toAppShare()
}
// #endif
if (this.haveShieldOper == 2) {
this.initIndex()
this.updateUserItem({
key: 'haveShieldOper',
val: 0
})
}
if (this.pageActive && this.userInfo.id) {
this.getCouponList()
}
},
onPullDownRefresh() {
// #ifndef APP-PLUS
uni.showNavigationBarLoading()
// #endif
this.initRefresh();
uni.stopPullDownRefresh()
},
onReachBottom() {
if (this.list.current_page >= this.list.last_page || this.loading) return;
this.loading = true;
this.getList(this.param.page + 1);
},
onShareAppMessage(e) {
let {
id: pid = 0
} = this.userInfo
let path = `/pages/service?pid=${pid}`
this.$util.log(path)
return {
title: '',
imageUrl: '',
path,
}
},
methods: {
...mapActions(['getConfigInfo', 'getUserInfo', 'updateCommonOptions', 'getServiceIndex', 'getServiceList']),
...mapMutations(['updateServiceItem', 'updateTechnicianItem', 'updateUserItem']),
async initIndex(refresh = false) {
let {
pid = 0
} = this.options
if (!refresh && this.pageActive && !pid) {
this.isLoad = true
this.loading = false
this.$util.hideAll()
return
}
let {
isGzhLogin
} = this
let {
id: uid = 0
} = this.userInfo
if (pid && !uid) {
// #ifdef H5
if (isGzhLogin) {
setTimeout(() => {
this.getUserInfo()
}, 1000)
} else {
this.getUserInfo()
}
// #endif
// #ifndef H5
await this.getUserInfo()
// #endif
}
if (!this.configInfo.id || refresh) {
await this.getConfigInfo()
}
let {
location
} = this
let {
plugAuth = {}
} = this.configInfo
let {
recommend = false
} = plugAuth
if (recommend && !location.lat) {
// #ifdef H5
if (await this.$jweixin.isWechat()) {
this.$util.showLoading()
// await this.$jweixin.initJssdk();
await this.$jweixin.wxReady2();
let {
latitude: lat = 0,
longitude: lng = 0
} = await this.$jweixin.getWxLocation()
location = {
lng,
lat,
address: '定位失败',
province: '',
city: '',
district: ''
}
}
// #endif
// #ifndef H5
location = await this.$util.getBmapLocation()
// #endif
this.updateUserItem({
key: 'location',
val: location
})
}
let {
lng = 0,
lat = 0
} = location
await this.getServiceIndex({
lat,
lng
})
this.updateServiceItem({
key: 'pageActive',
val: true
})
this.isLoad = true
if (this.userInfo.id) {
await Promise.all([this.getList(1), this.getCouponList()])
} else {
await this.getList(1)
}
},
initRefresh() {
this.initIndex(true)
},
toAppShare() {
let {
id: pid = 0
} = this.userInfo
let title = '首页'
let {
siteroot
} = siteInfo
let url = siteroot.split('/index.php')[0]
let href = `${url}/h5/#/pages/service?pid=${pid}`
let imageUrl = ''
this.$jweixin.wxReady(() => {
this.$jweixin.showOptionMenu()
this.$jweixin.shareAppMessage(title, '', href, imageUrl)
this.$jweixin.shareTimelineMessage(title, href, imageUrl)
})
},
// 轮播图/广告图跳转
goBanner(e) {
// connect_type 1查看大图2文章
let {
connect_type,
type_id: id = 0,
img: current
} = e
switch (connect_type) {
case 1:
this.$util.previewImage({
current,
urls: [current]
})
break;
case 2:
this.$util.goUrl({
url: `/user/pages/article?id=${id}`
})
break;
}
},
goCate(e) {
let {
id,
title,
url: link = ''
} = e
let url = link || `/user/pages/service/list?id=${id}&title=${title}`
this.$util.goUrl({
url
})
},
async userGetCoupon() {
let ids = []
this.couponList.forEach(v => {
ids.push(v.id)
})
let res = await this.$api.service.userGetCoupon({
coupon_id: ids
})
this.$util.showToast({
title: `领取成功`
})
setTimeout(() => {
this.$util.goUrl({
url: '/user/pages/coupon/list'
})
}, 1000)
this.$refs.coupon_item.close()
this.loading = false
this.$util.hideAll()
},
async getCouponList() {
let list = await this.$api.service.couponList()
this.couponList = list
if (list.length > 0 && this.isLoad) {
this.$refs.coupon_item.open()
}
this.loading = false
this.$util.hideAll()
},
async getList(page = 0) {
if (page) {
let param = this.$util.deepCopy(this.param)
param.page = page
this.updateServiceItem({
key: 'param',
val: param
})
}
let {
list: oldList,
param,
tabList,
activeIndex
} = this
let {
sort,
sign
} = tabList[activeIndex]
let desc = activeIndex == 0 || sign == 1 ? '' : 'desc'
param.sort = `${sort} ${desc}`
await this.getServiceList(param)
this.loading = false
this.$util.hideAll()
},
handerTabChange(index) {
this.updateServiceItem({
key: 'activeIndex',
val: index
})
let tabList = this.$util.deepCopy(this.tabList)
let {
is_sign,
sign,
} = tabList[index];
if (is_sign) {
tabList[index].sign = sign == 0 ? 1 : 0;
}
this.updateServiceItem({
key: 'tabList',
val: tabList
})
this.$util.showLoading()
uni.pageScrollTo({
scrollTop: 0
})
this.getList(1)
},
toTechnician(index) {
let {
id,
city_id,
coach_name
} = this.recommend_list[index]
this.updateTechnicianItem({
key: 'pageActive',
val: false
})
this.$util.goUrl({
url: `/pages/technician?coach_id=${id}&coach_name=${coach_name}&city_id=${city_id}`,
openType: `reLaunch`
})
}
}
}
</script>
<style lang="scss">
.pages-home {
.search-box {
width: 100%;
bottom: 0;
z-index: 9;
overflow: hidden;
}
.recommend-technician {
white-space: nowrap;
width: 690rpx;
.recommend-item {
display: inline-block;
}
.recommend-item.type-1 {
width: 180rpx;
margin-left: 26rpx;
.cover {
width: 180rpx;
height: 180rpx;
}
.ellipsis {
max-width: 180rpx;
}
}
.recommend-item.type-2 {
width: 203rpx;
height: 151rpx;
background: #F4F6F7;
border-radius: 12rpx;
margin-left: 20rpx;
.cover {
width: 70rpx;
height: 70rpx;
}
.ellipsis {
max-width: 82rpx;
}
.iconyduixingxingshixin {
font-size: 26rpx;
background-image: -webkit-linear-gradient(270deg, #FAD961 0%, #F76B1C 100%);
}
.star-text {
height: 26rpx;
color: #FF9519;
margin-left: 6rpx;
}
.new-technician {
width: 67rpx;
height: 30rpx;
border-radius: 8rpx;
transform: rotateZ(360deg);
}
}
.recommend-item:nth-child(1) {
margin-left: 0;
}
}
.list-item {
.cover {
width: 180rpx;
height: 180rpx;
}
.time-long {
min-width: 72rpx;
height: 30rpx;
padding: 0 5rpx;
background: linear-gradient(270deg, #4C545A 0%, #282B34 100%);
border-radius: 4rpx;
font-size: 20rpx;
color: #FFEEB9;
margin-right: 16rpx;
}
.f-icontext {
font-size: 18rpx;
}
.text-delete {
font-size: 24rpx;
color: #B9B9B9;
}
.item-btn {
width: 150rpx;
height: 52rpx;
border-radius: 100rpx;
}
}
}
.radius-top {
border-radius: 30rpx 30rpx 0 0;
}
.coupon-popup {
width: 658rpx;
height: 865rpx;
position: relative;
.bg-img {
width: 100%;
height: 100%;
}
.icon-close {
font-size: 60rpx;
position: absolute;
top: 50rpx;
right: 60rpx;
z-index: 999;
}
.coupon-info {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
.tops {
width: 480rpx;
color: #FB4523;
position: absolute;
top: 260rpx;
>view:nth-child(1) {
font-weight: bold;
font-size: 30rpx;
}
}
.lists {
width: 500rpx;
height: 300rpx;
padding: 10rpx;
overflow-x: hidden;
position: absolute;
bottom: 222rpx;
.list {
width: 420rpx;
height: 130rpx;
margin-bottom: 10rpx;
margin-top: 5rpx;
position: relative;
>image {
width: 100%;
height: 100%;
}
>view {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 8rpx;
>view:nth-child(1) {
width: 38%;
}
>view:nth-child(2) {
display: flex;
justify-content: center;
flex: 1;
padding: 0 15rpx;
box-sizing: border-box;
}
.price {
font-size: 30rpx;
color: #FB4523;
}
.title {
font-size: 30rpx;
line-height: 36rpx;
font-weight: bold;
}
.price_text {
color: #ccc;
}
}
}
}
}
view.btns {
width: 100%;
position: absolute;
height: 82rpx;
bottom: 0rpx;
left: 0;
>view {
width: 422rpx;
height: 82rpx;
border-radius: 40rpx;
font-size: 34rpx;
color: #FFFFFF;
}
}
}
.servetip {
font-size: 28rpx;
font-weight: 400;
display: flex;
justify-content: space-between;
align-items: center;
margin: 22rpx 0;
}
.servefc{
display: flex;
align-items: center;
}
.van-image {
position: relative;
display: inline-block;
}
.van-img {
width: 100%;
height: 100%;
}
.margin-20 {
margin: 0.53333rem;
}
</style>