mrr.sj.front/pages/address/add.nvue

673 lines
17 KiB
Plaintext

<template>
<view class="address-page">
<!-- 自定义导航栏 -->
<custom-navbar title="选择地址" :showBack="true" backgroundColor="#FFFFFF" :show-headle="true"
headleSrc="/static/images/add_icon.png" @onHeadleClick="addAddress">
</custom-navbar>
<!-- 地图容器 -->
<view class="map-container" :style="'height:' + mapHeight + 'rpx'">
<map id="map" class="map" :latitude="addressInfo.latitude" :longitude="addressInfo.longitude"
:show-location="true" :style="'height:' + mapHeight + 'rpx'" @regionchange="onRegionChange"
@tap="onMapTap">
</map>
<!-- 中心点标记 -->
<view class="center-marker" :style="'top:' + (mapHeight/2) + 'rpx'">
<image src="/static/images/mapCenter.png" class="center-marker-img" mode="widthFix"></image>
</view>
</view>
<!-- 地址信息表单 -->
<view class="address-form">
<view class="address-form-cont">
<!-- 服务地址 -->
<view class="form-item">
<text class="label">服务地址</text>
<view class="input textarea">
<text class="textarea-text">{{addressInfo.server_address}}</text>
</view>
<!-- <image src="/static/images/copy_icon.png" class="copy-icon" @tap="copyAddress"></image> -->
</view>
<!-- 门牌号 -->
<view class="form-item">
<text class="label">门牌号</text>
<input type="text" class="input" v-model="addressInfo.house_number" placeholder="如3号楼4单元502"
placeholder-class="placeholder" />
</view>
<!-- 预约人 -->
<view class="form-item">
<text class="label">预约人</text>
<input type="text" class="input" v-model="addressInfo.name" placeholder="请输入预约人姓名"
placeholder-class="placeholder" />
</view>
<!-- 手机号 -->
<view class="form-item">
<text class="label">手机号</text>
<input type="number" class="input" v-model="addressInfo.call_phone" placeholder="请输入手机号"
placeholder-class="placeholder" maxlength="11" />
</view>
<!-- 设为默认地址 -->
<view class="form-item switch-item">
<text class="label">设为默认地址</text>
<switch :checked="addressInfo.is_default == 1" @change="onSwitchChange" color="#E8101E" />
</view>
<!-- 顶部图标 -->
<view class="biao"></view>
<!-- 保存按钮 -->
<view class="save-btn" @tap="saveAddress">
<text class="save-text">保存</text>
</view>
</view>
</view>
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer }">
<text class="per-tit">美融融plus 对精确定位权限申请说明</text>
<text class="per-cont">便于您使用该功能获取您附近的手艺人以及店铺下的服务内容。</text>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import locationService from '../../utils/locationService';
import permissionUtils from '../../utils/per'
import {
debounce
} from '@/utils/debounce.js'
let debounceTimer = null;
export default {
data() {
return {
// isDisabled: true,
isShowPer: false,
mapHeight: 0,
addressInfo: {
call_phone: null,
house_number: null,
is_default: 2,
latitude: "",
longitude: "",
name: null,
server_address: null
},
mapCtx: '',
isGetDefault: false,
isAdd: false,
markers: []
}
},
onLoad() {
this.$nextTick(() => {
// 获取当前位置
this.getCurrentLocation()
// 获取视图高度
let pageHeight = uni.getWindowInfo().safeArea.height;
this.mapHeight = parseInt(pageHeight) * 2 - 826 - 70;
this.mapCtx = uni.createMapContext('map', this);
// 绑定事件确定只绑定一次
this.mapCtx.on('end', this.onRegionChange)
})
},
methods: {
getPlaceAround() {
let that = this;
let data;
if (!that.searchKeyword) {
data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
location: `${that.addressInfo.longitude},${that.addressInfo.latitude}`,
page: 1,
offset: 10
}
} else {
data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
location: `${that.addressInfo.longitude},${that.addressInfo.latitude}`,
keywords: that.searchKeyword,
page: 1,
offset: 10
}
}
return new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/place/around',
method: "GET",
data: data,
success(res) {
that.searchResults = res.data.pois;
}
})
})
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
async getCurrentLocation() {
let permission = '';
const systemInfo = uni.getSystemInfoSync()
if (systemInfo.platform === 'ios') {
permission = 'location'
} else {
permission = 'android.permission.ACCESS_FINE_LOCATION'
}
const firstRequest = !plus.storage.getItem(`perm_${permission}`);
if (firstRequest && systemInfo.platform !== 'ios') {
this.isShowPer = true;
}
const {
granted
} = await permissionUtils.checkPermission('location', '需要位置权限用于推荐附近服务');
console.log('granted==============', granted)
if (granted) {
this.getLocation();
this.isGetDefault = true;
return;
} else {
this.getDefault();
this.isGetDefault = false;
}
this.isShowPer = false;
// 2. 显示权限说明弹窗
const confirm = await this.showPermissionDialog(
'位置权限申请',
'我们需要位置权限,用于为您推荐附近服务'
);
if (!confirm) return;
// 3. 请求权限
const result = await permissionUtils.requestPermission('location', '需要位置权限用于推荐附近服务');
if (result) {
if (this.isShowPer || plus.storage.getItem(`perm_${permission}_no`)) {
this.getLocation();
} else {
this.getDefault();
this.isGetDefault = false;
}
} else {
locationService.openAppSettings();
}
},
//坐标转换
convert(item) {
let data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
locations: `${item.longitude},${item.latitude}`,
coordsys: 'gps',
}
return new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/assistant/coordinate/convert',
method: "GET",
data: data,
success(res) {
resolve(res.data)
}
})
})
},
async getLocation() {
if (uni.getStorageSync('setVersion').DeviceBrand == 'ios') {
uni.getLocation({
type: 'wgs84',
isHighAccuracy: true,
success: async res => {
let convert = await this.convert(res)
let locations = convert.locations.split(',')
res.longitude = locations[0]
res.latitude = locations[1]
this.addressInfo.latitude = res.latitude
this.addressInfo.longitude = res.longitude
this.updateMarkers()
this.getAddressInfo(res.latitude, res.longitude)
this.isGetDefault = true;
this.isShowPer = false;
},
fail: () => {
// uni.showToast({
// title: '获取位置失败',
// icon: 'none'
// })
this.getDefault();
this.isGetDefault = false;
this.isShowPer = true;
}
})
} else {
uni.getLocation({
type: 'gcj02',
success: res => {
this.addressInfo.latitude = res.latitude
this.addressInfo.longitude = res.longitude
this.updateMarkers()
this.getAddressInfo(res.latitude, res.longitude)
this.isGetDefault = true;
this.isShowPer = false;
},
fail: () => {
// uni.showToast({
// title: '获取位置失败',
// icon: 'none'
// })
this.getDefault();
this.isGetDefault = false;
this.isShowPer = true;
}
})
}
},
updateMarkers() {
// this.markers = [{
// id: 1,
// latitude: this.addressInfo.latitude,
// longitude: this.addressInfo.longitude,
// width: 32,
// height: 32
// }]
},
// 未授权定位 以默认定位为准
getDefault() {
this.addressInfo.latitude = getApp().globalData.addressRes.latitude
this.addressInfo.longitude = getApp().globalData.addressRes.longitude
this.updateMarkers()
this.getAddressInfo(getApp().globalData.addressRes.latitude, getApp().globalData.addressRes.longitude)
},
onRegionChange(e) {
console.log('onRegionChange', e)
// 地图视野变化事件
// if (e.type === 'end' && e.causedBy === 'drag') {
// // 拖动结束时更新地址信息
// const mapCtx = uni.createMapContext('map')
// mapCtx.getCenterLocation({
// success: res => {
// this.getAddressInfo(res.latitude, res.longitude)
// }
// })
// }
const systemInfo = uni.getSystemInfoSync()
if (systemInfo.platform === 'ios') {
if (e.detail.type === 'end' && e.detail.causedBy === 'drag') {
// clearTimeout(debounceTimer);
// debounceTimer = setTimeout(() => {
// console.log('防抖处理后的地图更新', e);
// // 真正的业务逻辑
// }, 300); // 300ms 内只执行最后一次
this.mapCtx.getCenterLocation({
success: async res => {
console.log('结果', res)
// 当前中心经纬度位置
await this.getAddressInfo(res.latitude, res.longitude, 'onRegionChange')
this.addressInfo.latitude = res.latitude;
this.addressInfo.longitude = res.longitude;
this.updateMarkers();
}
})
}
} else {
if (e.type === 'end' && e.causedBy === 'drag') {
// clearTimeout(debounceTimer);
// debounceTimer = setTimeout(() => {
// console.log('防抖处理后的地图更新', e);
// // 真正的业务逻辑
// }, 300); // 300ms 内只执行最后一次
this.mapCtx.getCenterLocation({
success: async res => {
console.log('结果', res)
// 当前中心经纬度位置
await this.getAddressInfo(res.latitude, res.longitude, 'onRegionChange')
this.addressInfo.latitude = res.latitude;
this.addressInfo.longitude = res.longitude;
this.updateMarkers();
}
})
}
}
},
onMapTap(e) {
console.log('onMapTap', e)
if (e.type == 'type') {
// 点击地图事件
let that = this;
that.addressInfo.latitude = e.detail.latitude;
that.addressInfo.longitude = e.detail.longitude;
that.updateMarkers()
that.getAddressInfo(e.detail.latitude, e.detail.longitude, 'onMapTap')
}
},
getAddressInfo(latitude, longitude, type) {
let that = this;
// 根据经纬度获取地址信息
// 这里需要接入地图SDK的逆地理编码服务
// 示例使用固定地址
return new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/geocode/regeo',
method: "GET",
data: {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
location: `${longitude},${latitude}`
},
success(res) {
console.log('======================', type, res.data)
that.addressInfo.dependency_province = res.data.regeocode.addressComponent
.adcode.slice(0, -4) + "0000";
that.addressInfo.dependency_city = res.data.regeocode.addressComponent.adcode
.slice(0, -2) + "00";
that.addressInfo.dependency_code = res.data.regeocode.addressComponent.adcode;
that.addressInfo.server_address = res.data.regeocode.formatted_address;
//地址逆编码特殊情况city=[],特殊处理
if (res.data.regeocode.addressComponent.city.length > 0) {
that.addressInfo.dependency = res.data.regeocode.addressComponent
.province +
'-' + res.data.regeocode.addressComponent.city + '-' + res.data
.regeocode
.addressComponent.district;
} else {
that.addressInfo.dependency = res.data.regeocode.addressComponent
.province +
'-' + res.data.regeocode.addressComponent.province + '-' + res.data
.regeocode
.addressComponent.district;
}
resolve(res.data)
}
})
})
},
copyAddress() {
uni.setClipboardData({
data: this.addressInfo.server_address,
success: () => {
uni.showToast({
title: '地址已复制',
icon: 'none'
})
}
})
},
onSwitchChange(e) {
this.addressInfo.is_default = !e.detail.value ? 2 : 1;
},
getPage() {
// 修改上一页页面信息
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
prevPage.$vm.getAddressList();
},
addAddress() {
if (!this.isGetDefault) {
uni.showToast({
title: '您未授权位置信息,暂无法添加地址!',
icon: 'none'
})
return;
}
uni.navigateTo({
url: '/pages/address/search?isSelectCity=true'
})
},
editAddress(item) {
console.log('item111111', item)
let location = item.location.split(',');
// this.$set(this.addressInfo, 'server_address', item.pname + item.cityname + item.adname + item.address +
// item.name);
// this.addressInfo.dependency = item.pname + '-' + item.cityname + '-' + item.adname;
this.$set(this.addressInfo, 'latitude', location[1]);
this.$set(this.addressInfo, 'longitude', location[0]);
this.getAddressInfo(location[1], location[0])
// this.updateMarkers();
},
saveAddress: debounce(function() {
if (this.isAdd) return;
// 表单验证
if (!this.addressInfo.server_address) {
uni.showToast({
title: '请选择地址',
icon: 'none'
})
return
}
if (!this.addressInfo.house_number) {
uni.showToast({
title: '请输入门牌号',
icon: 'none'
})
return
}
if (!this.addressInfo.name) {
uni.showToast({
title: '请输入预约人姓名',
icon: 'none'
})
return
}
if (!/^1\d{10}$/.test(this.addressInfo.call_phone)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
})
return
}
// TODO: 调用保存地址API
console.log('this.addressInfo', this.addressInfo)
request.post('/user/addaddress', this.addressInfo).then(res => {
console.log('添加结果', res)
if (res.state == 1) {
this.isAdd = true;
uni.showToast({
title: '添加成功',
duration: 2000,
success: () => {
setTimeout(() => {
this.getPage();
uni.navigateBack();
}, 2000)
}
})
} else {
this.isAdd = false;
}
}).catch(err => {
console.log(err)
this.isAdd = false;
})
}, 500)
}
}
</script>
<style lang="less">
.map-container {
width: 750rpx;
height: 500rpx;
position: relative;
}
.map {
width: 750rpx;
height: 500rpx;
}
.center-marker {
position: absolute;
left: 375rpx;
transform: translate(-50%);
width: 42rpx;
height: 69rpx;
.center-marker-img {
width: 42rpx;
}
}
.distance {
color: #FFFFFF;
font-size: 24rpx;
}
.address-form {
background-color: #FFFFFF;
padding: 80rpx 24rpx 48rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
}
.address-form-cont {
position: relative;
}
.biao {
position: absolute;
width: 80rpx;
height: 8rpx;
border-radius: 4rpx;
background-color: #EEF4FA;
top: -48rpx;
left: 50%;
transform: translateX(-50%);
}
.form-item {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.form-item:last-child {
border-bottom: 0;
}
.label {
font-size: 28rpx;
color: #3D3D3D;
font-weight: 500;
padding: 24rpx 0;
}
.value {
flex: 1;
font-size: 28rpx;
color: #333333;
}
.copy-icon {
width: 32rpx;
height: 32rpx;
margin-left: 16rpx;
}
.input {
height: 100rpx;
width: 568rpx;
font-size: 24rpx;
color: #3D3D3D;
font-weight: 500;
border-bottom: 1rpx solid #EEEEEE;
}
.textarea {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: flex-start;
}
.textarea-text {
font-size: 24rpx;
color: #3D3D3D;
}
.placeholder {
color: #666666;
font-weight: 500;
}
.switch-item {
justify-content: space-between;
margin-top: 12rpx;
}
.save-btn {
width: 630rpx;
height: 96rpx;
background-color: #E8101E;
border-radius: 44rpx;
display: flex;
justify-content: center;
align-items: center;
margin: 100rpx 36rpx 0;
}
.save-btn .save-text {
color: #FFFFFF;
font-size: 40rpx;
font-weight: 400;
}
.save-btn.disabled {
background-color: #EEF4FA;
}
/* 平台特定样式 */
/* #ifdef H5 */
.address-page {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* #endif */
/* #ifdef MP-WEIXIN */
.map-container {
/* 微信小程序地图容器样式调整 */
overflow: hidden;
}
/* #endif */
/* #ifdef APP-PLUS */
.form-item {
/* App端表单项样式调整 */
padding: 0;
}
.permission.transform {
top: 220rpx;
opacity: 1;
visibility: visible;
}
/* #endif */
</style>