java-mall-app/member/member/supermarketlList.vue

946 lines
25 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="supermarket-container">
<view class="hander">
<uni-nav-bar
class="hander-nav-bar"
title=""
:fixed="true"
:statusBar="true"
:border="false"
backgroundColor="transparent"
>
<view class="title-name">门店列表</view>
<block slot="left">
<uni-icons type="back" color="#fff" size="24" @click="handerSkip" />
</block>
</uni-nav-bar>
</view>
<view class="address-block">
<view class="address-name" @click="selectAddress">
<text class="iconfontAili icon-dingwei"></text>
<text class="address-box">{{
originalData.result.sematic_description
}}</text>
<text class="iconfontAili icon-right"></text>
</view>
<view class="refresh-address" @click="anewLoction">
<text class="iconfontAili icon-zhongxindingwei"></text>
<text style="padding-left: 8rpx">重新定位</text>
</view>
</view>
<view class="supermarketl-list">
<view class="input-block">
<view class="input-view">
<uni-icons
type="search"
size="22"
color="#666666"
style="line-height: 60rpx"
/>
<input
confirm-type="search"
class="input"
type="text"
v-model="storeName"
placeholder="输入超市名进行搜索"
@input="handerInputName"
/>
</view>
</view>
<scroll-view
class="m-scroll-list"
scroll-y="true"
@scrolltolower="scrollbottom"
:show-scrollbar="false"
:scroll-with-animation="false"
enhanced
>
<view class="">
<view
class="list-content"
v-for="(item, index) of shopList"
:key="index"
@click="handerSkipShop(item)"
>
<view :class="['list-item-hander']">
<view :class="['list-item-img', {'is-rest': item.store_biz_state ==2 }]">
<image
class="item-img"
lazy-load
:src="item.store_logo"
></image>
<view class="is-rest-bg" v-if="item.store_biz_state ==2"></view>
<view class="is-rest-tips" v-if="item.store_biz_state ==2">休息中</view>
</view>
<view class="list-item-info">
<view class="list-item-name">{{ item.store_name }}</view>
<view class="list-item-time"
>{{ item.store_opening_hours }}~{{
item.store_close_hours
}}</view
>
<view class="list-item-address">
<view class="address-name">{{ item.store_address }}</view>
<view class="list-item-distance">
<text class="distance-number">{{
(item.distance / 1000).toFixed(2)
}}</text>
<text class="distance-unit">km</text>
</view>
</view>
</view>
</view>
<view class="list-item-bottom">
<view class="list-item-lable-list">
<!-- <text class="list-item-lable">实体店</text> -->
<text class="list-item-lable" v-if="item.chain_count > 0"
>上门自提</text
>
<text class="list-item-lable" v-if="same_city_setting_count > 0"
>同城配送</text
>
</view>
<view class="list-item-skipu">
<text class="skipu-name">详细</text>
<text class="iconfontAili icon-right"></text>
</view>
</view>
</view>
<block v-if="ispage">
<view class="u-loadmore">
<label class="u-loading"></label>
<text class="u-loadmore-tips">{{ __("正在加载") }}</text>
</view>
</block>
<block v-else>
<view class="u-loadmore u-loadmore-line">
<text class="u-loadmore-tips">{{ __("没有更多数据啦!") }}</text>
</view>
</block>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import { mapState, mapMutations } from "vuex";
var bmap = require("../../libs/bmap-wx");
export default {
data() {
return {
ispage: false,
originalData: {
result: {
sematic_description: "定位中..",
},
},
addressInfo: {},
provinceData: [],
cityData: [],
areaData: [],
pageNum: 1,
pageSize: 10,
time: null,
shopList: [],
time2: null,
isNoData: false,
storeName: "",
};
},
computed: mapState([
"Config",
"StateCode",
"notice",
"plantformInfo",
"shopInfo",
"userInfo",
"hasLogin",
]),
onLoad(options) {
// if (options) {
// this.originalData.result.sematic_description = options.address;
// }
},
onPullDownRefresh() {
this.pageNum = 1;
this.storeName = "";
this.shopList = [];
this.getShopList(null);
},
onShow() {
let item = uni.getStorageSync("currentAddress");
this.getAppDistrict();
if (item) {
this.originalData.result.sematic_description = item.name;
this.addressInfo = item;
this.getShopList();
} else {
this.isPhoneLocationEnabled();
}
},
onHide() {
this.time = null;
clearTimeout(this.time);
this.time2 = null;
clearTimeout(this.time2);
this.shopList = [];
this.pageNum = 1;
},
methods: {
handerSkipShop(item) {
let km = (item.distance / 1000).toFixed(2);
uni.navigateTo({
url: `/pagesub/index/store?store_id=${item.store_id}&d=${km}km`,
});
},
handerSkip() {
this.$.gopage("/pages/index/index");
},
handerInputName(e) {
this.storeName = e.target.value;
if (this.time !== null) {
clearTimeout(this.time);
}
this.time = setTimeout(() => {
this.getShopList(e.target.value, null, true);
}, 600);
},
isPhoneLocationEnabled() {
let _this = this;
// 获取用户手机系统信息
uni.getSystemInfo({
success: (res) => {
const locationEnabled = res.locationEnabled;
if (locationEnabled) {
// 手机GPS定位已开启则判断微信APP是否已获取访问定位信息的权限
_this.isAppAuthorized();
} else {
// 手机GPS定位未开启则引导用户手动前往开启
uni.showModal({
title: "提示",
content:
'小程序需要基于您的手机定位信息为您提供服务,当前检测到您的手机并未打开定位开关,请关闭小程序后前往 "设置 - 定位服务/位置信息" 开启手机定位,然后重新进入小程序~',
showCancel: false,
confirmText: "我已知悉",
});
}
},
fail: (err) => {
console.log("用户手机系统信息获取失败", err);
},
});
},
isAuthorized(a = "scope.userLocation") {
// 检查当前是否已经授权访问scope属性
let _this = this;
uni.getSetting({
success: (res) => {
let userLocation = res.authSetting[a];
if (!userLocation) {
// 判断当前是否获得授权,如果没有就去申请授权
_this.getAuthorize();
} else {
_this.getLocation();
}
},
fail: (err) => {
_this.openSetting();
},
});
},
isAppAuthorized() {
let _this = this;
// 微信APP授权设置
const appAuthorizeSetting = uni.getAppAuthorizeSetting();
// 是否允许微信使用定位信息的开关
let locationAuthorized = appAuthorizeSetting.locationAuthorized;
switch (locationAuthorized) {
case "authorized":
_this.isAuthorized();
break;
case "denied":
uni.showModal({
title: "提示",
content:
"已拒绝微信获取定位权限,即将打开权限管理页面,请把定位权限设置为允许~",
confirmText: "前往设置",
success: (res) => {
if (res.confirm) {
_this.openAppAuthorizeSetting();
} else if (res.cancel) {
_this.rejectGetLocation();
}
},
});
break;
case "not determined":
uni.showModal({
title: "提示",
content: "请授权微信获取定位权限~",
confirmText: "同意授权",
success: (res) => {
if (res.confirm) {
_this.openAppAuthorizeSetting();
} else if (res.cancel) {
_this.rejectGetLocation();
}
},
});
break;
}
},
getAuthorize(a = "scope.userLocation") {
let _this = this;
// uniapp弹窗弹出获取授权地理个人微信信息等授权信息弹窗
uni.authorize({
scope: a,
success: () => {
_this.getLocation();
},
fail: () => {
_this.openSetting();
},
});
},
openSetting() {
let _this = this;
uni.showModal({
title: "提示",
content: "我们需要获取您的位置信息,为您提供服务~",
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (res) => {
if (res.authSetting["scope.userLocation"] === true) {
_this.getLocation();
} else {
_this.rejectGetLocation();
}
},
fail: (err) => {
console.log("小程序授权弹窗打开失败", err);
},
});
} else if (res.cancel) {
_this.rejectGetLocation();
}
},
});
},
rejectGetLocation() {
uni.showToast({
title: "您拒绝了位置授权,小程序无法继续提供出行服务~",
icon: "none",
duration: 3000,
});
},
openAppAuthorizeSetting() {
let _this = this;
uni.openAppAuthorizeSetting({
success: (res) => {
console.log("打开系统微信授权管理页成功", res);
_this.isAuthorized();
},
fail: (err) => {
console.log("打开系统微信授权管理页失败", err);
},
});
},
getLocation() {
uni.getLocation({
type: "wgs84",
isHighAccuracy: true,
success: function (res) {
location = res.latitude + "," + res.longitude;
let BMap = new bmap.BMapWX({
ak: "LkqqCMB1qZmjYEkzx0Y1PTfmAUrkWPog",
});
let fail = function (res) {
console.log("fail", res);
};
let success = function (res) {
console.log("结果地址", res);
that.originalData = res.originalData;
that.getShopList(null);
};
BMap.regeocoding({
location: location,
coordtype: "wgs84ll",
ret_coordtype: "gcj02ll",
fail: fail,
success: success,
});
},
fail: function (error) {
console.error("获取位置失败:", error);
},
});
},
selectAddress() {
uni.navigateTo({
url: "/address/selectShippingAddress?isShopList=true",
});
},
getAppDistrict() {
let that = this;
// 读取地区数据 【为了不同项目的小程序包体大小考虑,这里不能直接把数据放前端,可以使用服务端缓存和浏览器与小程序的本地存储来优化】
let district_data = uni.getStorageSync("district_data");
if (!district_data) {
that.$.request({
url: that.cf.URL.getAppDistrict,
data: {},
loading: false,
ajaxCache: {
timeout: this.cf.CACHE_EXPIRE,
},
success: function (data, status, msg, code) {
if (status == 200) {
uni.setStorageSync("district_data", data);
that.setDistrictData(data);
}
},
});
} else {
that.setDistrictData(district_data);
}
},
setDistrictData(district_data) {
this.provinceData = district_data.provinceData;
this.cityData = district_data.cityData;
this.areaData = district_data.areaData;
},
fuzzyMatch(shortStr, longStr) {
if (!shortStr || !longStr) {
console.log("找不到地址");
return;
}
const lowerShortStr = shortStr.toLowerCase();
const lowerLongStr = longStr.toLowerCase();
return lowerShortStr.includes(lowerLongStr);
},
getLocation() {
var that = this;
var location = "";
uni.getLocation({
type: "wgs84",
success: function (res) {
location = res.latitude + "," + res.longitude;
let BMap = new bmap.BMapWX({
ak: "LkqqCMB1qZmjYEkzx0Y1PTfmAUrkWPog",
});
let fail = function (res) {
console.log("fail", res);
};
let success = function (res) {
console.log("结果地址", res);
that.originalData = res.originalData;
that.getShopList(null, res.originalData.result.location);
};
BMap.regeocoding({
location: location,
coordtype: "wgs84ll",
ret_coordtype: "gcj02ll",
fail: fail,
success: success,
});
},
fail: function (error) {
console.error("获取位置失败:", error);
},
});
},
async getShopList(storeName, currlocation, isSearch) {
let that = this;
var province = {
label: "",
value: 0,
};
var city = {
label: "",
value: 0,
};
var county = {
label: "",
value: 0,
};
var location = {
lat: 0,
lng: 0,
};
if (!currlocation) {
var item = this.addressInfo;
if (item && item.ud_id) {
province.value = item.ud_province_id;
city.value = item.ud_city_id;
county.value = item.ud_county_id;
location = item.location;
}
if (item && !item.ud_id) {
let res = await this.getAddressUid(item.uid);
let items = res.data.result;
location = items.location;
this.provinceData.forEach((group) => {
let isFind = this.fuzzyMatch(items.province, group.label);
if (isFind) {
province = group;
}
});
this.cityData.forEach((group) => {
group.forEach((group1) => {
let isFind = this.fuzzyMatch(group1.label, items.city);
if (isFind) {
city = group1;
}
});
});
this.areaData.forEach((group) => {
group.forEach((group1) => {
group1.forEach((group2) => {
let isFind = this.fuzzyMatch(group2.label, items.area);
if (isFind) {
county = group2;
}
});
});
});
}
} else {
let data = this.originalData.result.addressComponent;
this.provinceData.forEach((group) => {
let isFind = this.fuzzyMatch(data.province, group.label);
if (isFind) {
province = group;
}
});
this.cityData.forEach((group) => {
group.forEach((group1) => {
let isFind = this.fuzzyMatch(group1.label, data.city);
if (isFind) {
city = group1;
}
});
});
this.areaData.forEach((group) => {
group.forEach((group1) => {
group1.forEach((group2) => {
let isFind = this.fuzzyMatch(group2.label, data.district);
if (isFind) {
county = group2;
}
});
});
});
location = currlocation;
console.log(province, city, county);
}
let params = {
provinceId: province.value,
cityId: city.value,
countyId: county.value,
userLng: location.lng,
userLat: location.lat,
storeCategoryId: 1003,
pageNum: this.pageNum,
pageSize: this.pageSize,
storeName: this.storeName || "",
};
that.ispage = true;
that.$.request({
url: that.Config.URL.store.nearList,
data: params,
success: (res, status) => {
if (status == 200) {
if (res.items.length > 0) {
if (isSearch) {
that.shopList = res.items;
} else {
that.shopList = [...that.shopList, ...res.items];
}
console.log(that.shopList);
} else {
that.isNoData = true;
that.pageNum = 1;
}
that.ispage = false;
}
},
fail: (res) => {},
});
},
getAddressUid(uid) {
let baiduParams = {
uid: uid,
scope: 1,
ak: "qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v",
output: "json",
};
return new Promise((resolve) => {
uni.request({
url: "https://api.map.baidu.com/place/v2/detail",
data: baiduParams,
success(res) {
console.log("66", res);
resolve(res);
},
fail(res) {
resolve(res);
},
});
}).catch((e) => {});
},
scrollbottom() {
if (this.isNoData) return;
if (this.time2 !== null) {
clearTimeout(this.time2);
}
this.time2 = setTimeout(() => {
this.pageNum = this.pageNum + 1;
this.getShopList();
}, 600);
},
anewLoction() {
uni.removeStorageSync("currentAddress");
this.time = null;
clearTimeout(this.time);
this.time2 = null;
clearTimeout(this.time2);
this.shopList = [];
this.pageNum = 1;
this.isPhoneLocationEnabled();
},
},
};
</script>
<style lang="scss">
.supermarket-container {
height: 100vh;
// background: linear-gradient(to top left, #e85169, #e93340);
// background: linear-gradient(to top left, #e93340, #e85169);
background: rgb(249, 55, 43);
overflow: hidden;
.hander {
.title-name {
width: 100vw;
font-size: 16px;
text-align: center;
color: #fff;
}
}
/* 隐藏滚动条 */
.m-scroll-list {
scrollbar-width: none; /* Firefox */
}
.m-scroll-list::-webkit-scrollbar {
display: none; /* Chrome, Safari */
}
.address-block {
display: flex;
justify-content: space-between;
color: #fff;
padding: 16px;
.address-name {
display: flex;
align-items: center;
}
.address-box {
display: block;
margin: 0 6px;
max-width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.icon-zhongxindingwei {
margin-right: 4px;
}
}
.m-scroll-list {
height: calc(100vh - 220px);
}
.supermarketl-list {
background: #f4f5f9;
padding: 4px;
border-top-left-radius: 18px;
border-top-right-radius: 18px;
overflow: hidden;
.input-view {
// width: 50%;
display: flex;
background-color: #ffffff;
height: 60rpx;
border-radius: 30rpx;
padding: 0 4%;
flex-wrap: nowrap;
margin: 20px 10px;
line-height: 60rpx;
color: #b9b9b9;
}
.input-view .uni-icon {
line-height: 60rpx !important;
font-size: 24rpx;
}
.input-view .uni-icons {
font-size: 32rpx !important;
}
.input-view .input {
height: 60rpx;
line-height: 60rpx;
width: 100%;
padding: 0 2%;
font-size: 24rpx;
}
.list-content {
margin: 10px;
background: #fff;
border-radius: 6px;
padding: 18px 12px;
.list-item-hander {
display: flex;
.list-item-img {
border-radius: 10px;
margin-right: 12px;
width: 102px;
height: 102px;
min-width: 102px;
min-height: 102px;
overflow: hidden;
.item-img {
width: 102px;
height: 102px;
}
}
.list-item-info {
flex: 1 1;
font-size: 13px;
color: #5e6066;
line-height: 18px;
.list-item-name {
font-size: 16px;
color: #2f3033;
line-height: 22px;
margin-bottom: 6px;
font-weight: 700;
max-width: 258px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list-item-time {
font-size: 13px;
color: #5e6066;
line-height: 18px;
margin-bottom: 6px;
}
.list-item-address {
display: flex;
justify-content: space-between;
.address-name {
max-width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list-item-distance {
.distance-number {
font-weight: 700;
font-size: 20px;
color: #000;
}
}
}
}
}
.is-rest{
position: relative;
.is-rest-bg{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40rpx;
background: #000;
opacity: 0.5;
z-index: 2;
}
.is-rest-tips{
position: absolute;
bottom: 0;
width: 100%;
line-height: 40rpx;
font-size: 24rpx;
color: #fff;
text-align: center;
z-index: 3;
}
}
.list-item-bottom {
display: flex;
justify-content: space-between;
.list-item-lable-list {
.list-item-lable {
margin-right: 9px;
border-radius: 4px;
height: 18px;
font-size: 11px;
padding: 0 4px;
align-items: center;
justify-content: center;
color: #6f7dad;
background: #f4f6fa;
}
}
.list-item-skipu {
font-size: 14px;
font-weight: 700;
color: #fe0137;
}
}
}
}
/* 小屏幕设备 iPhone 5/SE */
@media screen and (max-width: 320px) {
.address-block {
.address-box {
max-width: 140px;
}
}
.list-item-img {
width: 62px !important;
height: 62px !important;
min-width: 62px !important;
min-height: 62px !important;
.item-img {
width: 62px !important;
height: 62px !important;
}
}
.address-name {
max-width: 120px !important;
}
}
/* 中等屏幕设备 iPhone 6/7/8/X */
@media screen and (min-width: 321px) and (max-width: 414px) {
.m-product-info {
width: 60%;
}
.list-item-img {
width: 62px !important;
height: 62px !important;
min-width: 62px !important;
min-height: 62px !important;
.item-img {
width: 62px !important;
height: 62px !important;
}
}
}
/* 大屏幕设备 iPhone Plus 系列 */
@media screen and (min-width: 415px) {
/* 可以添加针对大屏幕的样式 */
.list-item-img {
width: 102px !important;
height: 102px !important;
min-width: 102px !important;
min-height: 102px !important;
.item-img {
width: 102px !important;
height: 102px !important;
}
}
}
/* 专门针对 iPhone X 的竖屏模式 */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 812px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: portrait) {
.list-item-img {
width: 62px !important;
height: 62px !important;
min-width: 62px !important;
min-height: 62px !important;
.item-img {
width: 62px !important;
height: 62px !important;
}
}
}
}
</style>