dingdong-mall/pages/index/home.vue

706 lines
23 KiB
Vue

<template name="index">
<c-tabbar :current="0">
<view>
<!-- 顶部操作条 -->
<!-- <cu-custom class="text-left">
<block slot="left-content">
<image :src="item.url" v-if="item.type=='image'"></image>
<text class="padding-left text-xl" style="float: left;">叮咚到家家政服务</text>
</block>
</cu-custom> -->
<!-- 轮播图-->
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true"
:circular="true" :autoplay="true" interval="5000" duration="500">
<swiper-item v-for="(item,index) in swiperList" :key="item.id">
<image mode="aspectFill" :src="item.url" v-if="item.type=='image'"></image>
<video :src="item.url" autoplay loop muted :show-play-btn="false" :controls="false"
objectFit="cover" v-if="item.type=='video'"></video>
</swiper-item>
</swiper>
<!-- 搜索栏 -->
<view class="cu-bar search bg-white">
<view class="search-form round">
<text class="cuIcon-search"></text>
<input @confirm="chooseCategory(null)" v-model="searchInfo.inputGoodsName" :adjust-position="true"
type="text" placeholder="输入搜索内容" confirm-type="search"></input>
</view>
<!-- 区域筛选picker -->
<view class="action">
<picker class="text-black text-bold" :mode="'multiSelector'" @change="regionChange"
@columnchange="regionColChange" :value="areaMultiIndex" :range-key="'areaName'"
:range="areaList">
<text>{{searchInfo.area && searchInfo.area.length ? searchInfo.area[1].areaName : areaList[1][0].areaName}}</text>
<text class="text-xl"><text class="cuIcon-triangledownfill"></text></text>
</picker>
</view>
</view>
<view>
<view class="margin-lr-sm">
<!-- 大类 -->
<view class="flex justify-between text-black">
<view class="padding text-lg" @click="showProductCategories">
<text>分类</text>
<text class="cuIcon-apps text-main-color"></text>
<text class="cuIcon-triangledownfill"></text>
</view>
<view class="flex-twice">
<scroll-view scroll-x class="nav text-right" :scroll-with-animation="true"
:scroll-left="scrollLeft">
<view class="cu-item" :class="index==tabCur?'text-main-color cur':''" v-if="index < 2"
v-for="(item,index) in categories" :key="item.goodsCategoryId"
@tap="tabSelect($event, item)" :data-index="index">
{{item.goodsCategoryName}}
</view>
</scroll-view>
</view>
</view>
<!-- 热门细类 -->
<view class="cu-list grid no-border hot-sub-category" :class="['col-5']"
:style="'padding-top: 10rpx'">
<view class="cu-item align-center" v-for="(item,index) in hotServCategory" :key="index"
v-if="tabCur === 0 && index < 15" @click="chooseCategory(item)">
<!-- <view class="hot-sub-category-icon" :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
<view class="cu-tag badge" v-if="item.badge!=0">
<block v-if="item.badge!=1">{{item.badge}}</block>
</view>
</view> -->
<view class="cu-avatar round"
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'">
</view>
<text>{{item.name}}</text>
</view>
<view class="cu-item align-center" v-for="(item,index) in hotFittingsCategory" :key="index"
v-if="tabCur === 1 && index < 15" @click="chooseCategory(item)">
<view class="cu-avatar round"
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'">
</view>
<text>{{item.name}}</text>
</view>
</view>
<!-- 细类 -->
<!-- <view class="cu-list grid no-border" :class="['col-5']" v-if="subCategories.length > 5">
<view class="cu-item" v-for="(item,index) in subCategories" :key="index"
v-if="index < subCategories.length && index > 4" @click="chooseCategory(item)">
<view :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
</view>
<text>{{item.goodsCategoryName}}</text>
</view>
</view> -->
<!-- 超值服务 -->
<!-- <vertical-goods-card ref="discountGoodsCard" :goodsInfos="discountGoods.goodsInfos"
:title="discountGoods.title"></vertical-goods-card> -->
<!-- 热门服务 -->
<!-- <vertical-card :list="hotServCategory" :multiPicMode="true" title="大家都在买"></vertical-card> -->
</view>
<!-- 当前城市服务列表 -->
<view class="text-gray text-lg text-center margin flex align-center">
<view class="divider" />
<text class="margin-lr-sm" style="flex-basis: 60%; color: #9E9E9E;">当前城市</text>
<view class="divider" />
</view>
<view>
<view class="margin-top-sm margin-lr-sm waterfall-grid">
<view @click="showDetails(item)" :key="item.goodsId" v-for="(item, index) in productList"
class="waterfall-grid-item">
<flow-goods-card :product="item"></flow-goods-card>
</view>
</view>
<load-status-bar ref="loadStatusBar1" @loadMore="loadProductPage"></load-status-bar>
</view>
<!-- 其他城市服务列表 -->
<view class="text-gray text-lg text-center margin flex align-center" style="padding-top: 60rpx;">
<view class="divider" />
<text class="margin-lr-sm" style="flex-basis: 50%;">其他城市</text>
<view class="divider" />
</view>
<view>
<view class="margin-top-sm margin-lr-sm waterfall-grid">
<view @click="showDetails(item)" :key="item.goodsId"
v-for="(item, index) in otherCityProductList" class="waterfall-grid-item">
<flow-goods-card :product="item"></flow-goods-card>
</view>
</view>
<load-status-bar ref="loadStatusBar2" @loadMore="loadOtherCityProductPage"></load-status-bar>
</view>
</view>
<view class="occupancy-bottom-bar"></view>
<!-- 前往授权设置 -->
<view class="cu-modal" :class="isShowPrivSetting?'show':''">
<view class="cu-dialog">
<view class="padding-xl text-left">
<view>需先授权定位功能才可正常使用功能</view>
</view>
<view class="cu-bar bg-white">
<navigator class="modal-bottom-oper margin-0 flex-sub text-black" open-type="exit"
target="miniProgram">拒绝授权
</navigator>
<button class="cu-btn modal-bottom-oper margin-0 flex-sub text-main-color bg-white solid-left"
open-type="openSetting" @opensetting="authLocationCallback">前往授权</button>
</view>
</view>
</view>
</view>
<!-- <valid ref="validRef"></valid> -->
</c-tabbar>
</template>
<script>
import verticalCard from '@/components/common-card/vertical-card.vue';
import loadStatusBar from '@/components/custom-bar/load-status-bar.vue';
import flowGoodsCard from '@/components/goods-card/flow-goods-card.vue';
import CTabbar from '@/components/CTabbar.vue';
// import valid from './components/valid.vue';
export default {
name: 'index',
components: {
verticalCard,
loadStatusBar,
flowGoodsCard,
CTabbar,
// valid
},
data() {
return {
scrollLeft: 0,
dotStyle: true,
swiperList: [],
tabCur: 0,
categories: [],
subCategories: [],
hotServCategory: [],
hotFittingsCategory: [],
discountGoods: {},
InputBottom: 0,
searchInfo: {},
areaList: [],
areaMultiIndex: [0, 0],
productList: [],
otherCityProductList: [],
pageNum: 0,
pageSize: 0,
otherCityProductPageNum: 0,
otherCityProductPageSize: 0,
isShowPrivSetting: false,
initParam: null,
goInfo: false,
deptGoodsCategoryIds: []
}
},
onLoad(option) {
if(option) {
// 跳转逻辑
if (option.menuCode) {
if(option.menuCode == 'myPage') {
setTimeout(() => {
uni.switchTab({
url: '/pages/index/my-home'
})
}, 500)
}
return;
}
if (option.scene) {
let paraStr = decodeURIComponent(option.scene);
let kvStrArr = paraStr.split("&");
kvStrArr.forEach((kvStr) => {
let kvArr = kvStr.split("=");
option[kvArr[0]] = kvArr[1];
});
}
}
this.initParam = option
uni.hideTabBar();
},
mounted() {
this.bindEvent();
},
beforeDestroy() {
this.offBindEvent();
},
async onReady() {
// await this.$request.authAndGetLocation();
// 定位当前城市
await this.getCurAreaArr();
uni.$emit('initValid', this.initParam)
},
async onShow() {
if((this.productList.length || this.otherCityProductList.length) && !this.goInfo) {
this.reloadProductPage();
}
this.goInfo = false;
this.curUserInfo = this.$request.getCurUserInfo();
// if (this.initParam && this.initParam.distributor) {
// let res = await this.$request.updateUser({
// customerPlace: this.initParam.distributor,
// customerId: this.curUserInfo.customerId
// });
// if (res && res.code === 0) {
// this.initParam = null;
// }
// }
},
async onShareAppMessage(e) {
let shareInfo = null;
if (e && e.target && e.target.dataset) {
shareInfo = e.target.dataset.shareInfo;
}
if (!this.curUserInfo) {
this.curUserInfo = await this.$request.getCurUserNoCache();
if (!this.curUserInfo) {
uni.showToast({
title: '请前往“我的”完成登录',
icon: 'none'
})
return;
}
}
if (!shareInfo) {
shareInfo = {
title: '家政服务就找工圈子',
path: '/pages/index/home?distributor=' + this.curUserInfo.customerId,
imageUrl: 'http://gqz.opsoul.com/sys/group-selfie.png'
}
}
return shareInfo;
},
methods: {
async loadData() {
this.initBasicData();
// 加载区域信息
await this.loadRegionList();
// 加载服务商城热门类目
let hotServCategoryRes = await this.$request.getHotCategory({
type: 1
});
this.hotServCategory = hotServCategoryRes.data;
// 加载配件商城热门类目
let hotFittingsCategoryRes = await this.$request.getHotCategory({
type: 2
});
this.hotFittingsCategory = hotFittingsCategoryRes.data;
const deptGoodsCategoryIds = []
if(this.curUserInfo) {
const res = await this.$request.getChooseCategories({
selectionType: 1,
customerId: this.curUserInfo.customerId
})
deptGoodsCategoryIds.push(...res[1].data.data)
}
this.deptGoodsCategoryIds = deptGoodsCategoryIds
// 加载品类
this.loadCategoryList();
// 加载当前定位城市的服务列表
this.loadProductPage();
// 加载其他城市的服务列表
this.loadOtherCityProductPage();
this.swiperList = await this.$api.data('swiperList');
// this.categories = await this.$api.data('categories');
// this.subCategories = await this.$api.data('subCategories');
this.moduleBarInfos = await this.$api.data('moduleBarInfos');
// this.hotGoods = await this.$api.data('hotGoods');
// this.discountGoods = await this.$api.data('discountGoods');
},
// authCallback() {
// this.$refs.validRef.loadData(this.initParam)
// },
bindEvent() {
uni.$on('clickCard', this.clickHotCategory);
// uni.$on('authCallback', this.authCallback);
},
offBindEvent() {
uni.$off('clickCard');
// uni.$off('authCallback');
},
async authLocationCallback(res) {
if (res.detail.authSetting['scope.userLocation']) {
this.isShowPrivSetting = false;
await this.getCurAreaArr();
}
},
async wxGetLocation() {
let _this = this;
// 通过 wx.getSetting 先查询一下用户是否授权了authScope
let res1 = await wx.getSetting();
if (res1) {
if (!res1.authSetting['scope.userLocation']) {
let res2 = await wx.getLocation({
type: 'gcj02',
fail: async (result) => {
console.log(result)
if (result.errno === 103 || result.errMsg ===
'getLocation:fail auth deny') {
this.isShowPrivSetting = true;
} else {
// 用户授权
// uni.showToast({
// title: '请确认是否开启定位',
// icon: 'none',
// duration: 1500
// })
uni.showModal({
title: '提示',
content: '请确认是否开启定位',
cancelText: '取消',
confirmText: '重试',
success: res => {
if (res.confirm) {
this.getCurAreaArr();
}
}
})
}
},
success: async (result) => {
await _this.$request.storageLocation(result);
let areaArr = await _this.getCurAreaArr();
if (areaArr) {
_this.searchInfo.area = areaArr;
await _this.loadData();
}
}
})
} else {
wx.getLocation({
type: 'gcj02',
fail: async (result) => {
console.log(result)
if (result.errCode === 2 || result.errCode === 404) {
// uni.showToast({
// title: '定位获取失败,请确认是否开启定位',
// icon: 'none',
// duration: 2500
// })
uni.showModal({
title: '提示',
content: '定位获取失败,请确认是否开启定位',
cancelText: '取消',
confirmText: '重试',
success: res => {
if (res.confirm) {
this.getCurAreaArr();
}
}
})
} else {
// uni.showToast({
// title: '定位获取失败,请稍后重试',
// icon: 'none',
// duration: 2500
// })
uni.showModal({
title: '提示',
content: '定位获取失败,请稍后重试',
cancelText: '取消',
confirmText: '重试',
success: res => {
if (res.confirm) {
this.getCurAreaArr();
}
}
})
}
},
success: async (result) => {
await _this.$request.storageLocation(result);
let areaArr = await _this.getCurAreaArr();
if (areaArr) {
_this.searchInfo.area = areaArr;
await _this.loadData();
}
}
})
}
}
},
async getCurAreaArr() {
let curLocation = uni.getStorageSync('curLocation');
if (curLocation && curLocation.updateTimes) {
let curTimes = new Date().getTime();
let deltaSeconds = curTimes - curLocation.updateTimes;
if (deltaSeconds <= 15 * 60 * 1000) {
this.searchInfo.area = curLocation.area;
this.loadData();
return;
}
}
await this.wxGetLocation();
},
async loadCategoryList() {
let res = await this.$request.getProductCategories();
this.categories = res[1].data.data;
this.tabSelect(null, this.categories[0]);
},
async loadRegionList() {
let area = this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area : null
let regionList = await this.$request.areaListByStep({
areaId: area == null ? null : area[0].areaId
});
regionList = regionList.data;
let subRegionList = [];
let subSubRegionList = [];
if (regionList && regionList.length > 0) {
let params = {};
if (area != null) {
params = {
areaId: area[1].areaId,
parentCode: area[0].areaId
}
} else {
params = {
parentCode: regionList[0].areaCode
}
}
subRegionList = await this.$request.areaListByStep(params);
subRegionList = subRegionList.data;
}
if (subRegionList && subRegionList.length > 0) {
subSubRegionList = await this.$request.areaListByStep({
parentCode: subRegionList[0].areaCode
});
subSubRegionList = subSubRegionList.data;
let allAreaIdsOfSubSubRegionList = [];
subSubRegionList.forEach(region => {
allAreaIdsOfSubSubRegionList.push(region.areaId)
})
let subSubRegionListWithAll = [{
areaIds: allAreaIdsOfSubSubRegionList,
areaId: subRegionList[0].areaId,
isAll: true,
areaName: subRegionList[0].areaName
}].concat(subSubRegionList);
subSubRegionList = subSubRegionListWithAll;
}
this.areaList = [];
// this.areaList.push(regionList);
this.areaList.push(subRegionList);
this.areaList.push(subSubRegionList);
this.searchInfo.area = [this.areaList[0][0], this.areaList[1][0]];
},
regionChange(e) {
this.areaMultiIndex = e.detail.value;
let chosenArea = [];
for (let i = 0; i < this.areaList.length; i++) {
chosenArea.push(this.areaList[i][this.areaMultiIndex[i]]);
}
this.searchInfo.area = chosenArea;
this.reloadProductPage();
},
async regionColChange(e) {
// let colObj = e.detail;
// if (colObj.column == 0) {
// // 通过一级查二级
// let subAreaList = await this.$request.areaListByStep({
// parentCode: this.areaList[0][colObj.value].areaCode
// });
// subAreaList = subAreaList.data;
// let subSubAreaList = [];
// if (subAreaList.length) {
// subSubAreaList = await this.$request.areaListByStep({
// parentCode: subAreaList[0].areaCode
// });
// subSubAreaList = subSubAreaList.data;
// }
// this.areaList.pop();
// this.areaList.pop();
// this.areaList.push(subAreaList);
// this.areaList.push(subSubAreaList);
// this.areaMultiIndex = [colObj.value, 0, 0];
// } else if (colObj.column == 1) {
// // 通过二级查三级
// let subAreaList = await this.$request.areaListByStep({
// parentCode: this.areaList[1][colObj.value].areaCode
// });
// subAreaList = subAreaList.data;
// this.areaList.pop();
// this.areaList.push(subAreaList);
// this.areaMultiIndex = [this.areaMultiIndex[0], colObj.value, 0];
// }
},
async tabSelect(e, item) {
this.tabCur = e == null ? 0 : e.currentTarget.dataset.index;
this.scrollLeft = (this.tabCur - 1) * 60;
let subSubTypeList = [];
for (let i = 0; i < item.child.length; i++) {
let stopFlag = false;
let secondList = item.child[i].child;
if (secondList && secondList.length) {
for (let k = 0; k < secondList.length; k++) {
let thirdList = secondList[k].child;
if (thirdList && thirdList.length) {
for (let j = 0; j < thirdList.length; j++) {
subSubTypeList = subSubTypeList.concat(thirdList[j]);
if (subSubTypeList.length >= 15) {
subSubTypeList = subSubTypeList.slice(0, 15);
stopFlag = true;
break;
}
}
}
if (stopFlag) break;
}
}
if (stopFlag) break;
}
let subCategoryOpt = await this.$api.data('subCategories');
for (let i = 0; i < subSubTypeList.length; i++) {
subSubTypeList[i]['cuIcon'] = subCategoryOpt[i].cuIcon;
subSubTypeList[i]['color'] = subCategoryOpt[i].color;
}
this.subCategories = subSubTypeList;
},
chooseCategory(item) {
this.searchInfo.category = item;
this.searchGoods();
},
searchGoods() {
let params = {
category: this.searchInfo.category,
area: this.searchInfo.area,
inputGoodsName: this.searchInfo.category ? '' : this.searchInfo.inputGoodsName,
showData: true
};
// if(!this.deptGoodsCategoryIds.includes(this.searchInfo.category)) {
// params.showData = false
// }
uni.navigateTo({
url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params))
})
},
clickHotCategory(item) {
let params = {
category: item,
showData: true
};
// if(!this.deptGoodsCategoryIds.includes(this.searchInfo.category)) {
// params.showData = false
// }
uni.navigateTo({
url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params))
})
},
showProductCategories() {
uni.navigateTo({
url: '/pages/product/product-category'
})
},
/* 底部当前城市服务列表 start */
initBasicData() {
this.pageNum = this.$globalData.initPageNum;
this.pageSize = this.$globalData.initPageSize;
this.otherCityProductPageNum = this.$globalData.initPageNum;
this.otherCityProductPageSize = this.$globalData.initPageSize;
this.productList = [];
this.otherCityProductList = [];
},
showDetails(productItem) {
let params = {
goodsId: productItem.goodsId
}
this.goInfo = true;
uni.navigateTo({
url: '/pages/product/product-detail?params=' + encodeURIComponent(JSON.stringify(params))
});
},
async reloadProductPage() {
this.initBasicData();
this.loadProductPage();
this.loadOtherCityProductPage();
},
async loadProductPage(params = {
areaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[this.searchInfo
.area.length - 1].areaId : null
}, loadStatusBarRefName = "loadStatusBar1", resContainer = "productList", pageNumName = "pageNum",
pageSizeName = "pageSize") {
if (!params.exceptParentAreaId && this.searchInfo.area &&
this.searchInfo.area.length && this.searchInfo.area[this.searchInfo.area.length - 1].isAll) {
params.areaIds = this.searchInfo.area[this.searchInfo.area.length - 1].areaIds;
params.areaId = null;
}
params.deptGoodsCategoryIds = this.deptGoodsCategoryIds;
params.pageNum = this[pageNumName];
params.pageSize = this[pageSizeName];
params.status = 0;
this.$refs[loadStatusBarRefName].showLoading();
try {
let res = await this.$request.qryProductPage(params);
let rowsLength = res[1].data.rows.length;
if (rowsLength > 0) {
this[resContainer] = this[resContainer].concat(res[1].data.rows);
console.log(this[resContainer])
this[pageNumName]++;
if (rowsLength === this[pageSizeName]) {
this.$refs[loadStatusBarRefName].showLoadMore();
return;
}
}
this.$refs[loadStatusBarRefName].showLoadOver();
} catch (e) {
console.error(e)
this.$refs[loadStatusBarRefName].showLoadErr();
}
},
/* 底部当前城市服务列表 end */
/* 其他城市服务列表 start */
loadOtherCityProductPage() {
this.loadProductPage({
exceptParentAreaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[
1].areaId : null
}, "loadStatusBar2", "otherCityProductList", "otherCityProductPageNum", "otherCityProductPageSize")
}
/* 其他城市服务列表 end */
}
}
</script>
<style scoped>
.screen-swiper {
height: 500rpx;
}
.cu-list+.cu-list {
margin-top: 0;
}
.cu-list.grid.no-border {
padding: 0 10rpx;
}
.hot-sub-category .cu-item .hot-sub-category-icon {
font-size: 80rpx;
}
.modal-bottom-oper {
height: 70rpx;
display: inline-flex;
align-items: center;
justify-content: center;
}
.waterfall-grid {
/* column-count: 2;
column-gap: 15rpx; */
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.waterfall-grid-item {
/* break-inside: avoid;
margin-bottom: 15rpx; */
width: 49%;
margin-bottom: 15rpx;
}
</style>