Files
2025-04-30 14:04:34 +08:00

883 lines
25 KiB
Vue
Raw Permalink 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="page add-address">
<fu-custom class="bg-white" style="position: relative; z-index: 100;" :isBack="true" :isBottom="true">
<block slot="content" style="font-weight: bold;">{{edit_id?'编辑地址':'添加地址'}}</block>
<!-- #ifndef MP-WEIXIN -->
<block slot="right"><text v-if="edit_id" @click="delAddr" class="text-lg text-333">删除</text></block>
<!-- #endif -->
</fu-custom>
<!-- 表单信息 start -->
<view class="addAddr">
<view class="cell" v-if="serveList.length > 0">
<text class="title">标签</text>
<view class="flex align-center">
<view v-for='(item,index) in serveList' :key='index' class='cu-tag radius' :class='item.name == default_serve.name? index < 3? "bg-orange2":"bg-green radius-left" :"line-black"'
@click='changeServe(item)' v-show="item.name">
{{item.name}}
</view>
<view v-if="serveList.length== 4" class='cu-tag radius bg-green left-0 radius-right' @click='addServe(serveList[3].name)'>
编辑
</view>
<view class='cu-tag line-black radius' @click='addServe()' v-if="serveList.length<= 3">+</view>
</view>
</view>
<view class="cell">
<text class="title">收货人</text>
<input type="text" maxlength="8" v-model="name" placeholder="收货人" />
<view class="flex">
<view class="text-999 flex align-center" @click="chooseSex('1')">
<text :class="[sex == 1 ? 'cuIcon-roundcheckfill active' : 'cuIcon-round']" class="text-xl"></text>
<text :class="{'text-666': sex == 1}" class="margin-left-xs">先生</text>
</view>
<view class="text-999 margin-left flex align-center" @click="chooseSex('2')">
<text :class="[sex == 2 ? 'cuIcon-roundcheckfill active' : 'cuIcon-round']" class="text-xl"></text>
<text :class="{'text-666': sex == 2}" class="margin-left-xs">女士</text>
</view>
</view>
</view>
<view class="cell">
<text class="title"> 联系电话</text>
<input type="number" maxlength="11" v-model="phone" placeholder="联系电话" />
<!-- <text v-if="phone.length > 0" class=" cuIcon-close" @click="clear"
style="font-size: 36rpx;color:#999;"></text> -->
</view>
<view class="cell" v-if="isPublish">
<text class="title"> 所在地区</text>
<view class="flex flex-sub">
<input class="flex-sub" type="text" disabled v-model="address" placeholder="请选择省市区县、乡镇" />
<text class="cuIcon-locationfill" style="font-size: 40rpx; color: rgba(255, 147, 0, 1);" @click="chooseLocation"></text>
<!-- <text class=" cuIcon-right text-gray" style="font-size: 36rpx; "
@click="showMulLinkageThreePicker"></text> -->
</view>
</view>
<view class="cell" v-if="!isPublish">
<text class="title"> 所在地区</text>
<view class="flex flex-sub">
<input class="flex-sub" type="text" disabled v-model="address" placeholder="请选择省市区县、乡镇" />
<text class="cuIcon-locationfill" style="font-size: 40rpx; color: rgba(255, 147, 0, 1);" @click="_chooseLocation"></text>
<!-- <text class=" cuIcon-right text-gray" style="font-size: 36rpx; "
@click="showMulLinkageThreePicker"></text> -->
</view>
</view>
<view class="cell">
<textarea class="text-area" type="text" v-model="addressDesc" maxlength="50" placeholder-class="placeholder"
placeholder="请输入详细地址:如道路、门牌号、小区、楼栋号等" />
</view>
<!-- <view class="cell justify-between" style="border: none; padding-bottom: 12rpx;">
<text class="title"> {{i18n["智能填写"]}}</text>
<view class="flex">
<text class="cuIcon-right text-333" style="font-size: 32rpx;"> </text>
</view>
</view>
<textarea class="text-ai" type="text" v-model="baiduAddress" maxlength="200" placeholder-class="placeholder"
:placeholder="i18n['请输入详细地址:如道路、门牌号、小区、楼栋号等']" />
<view class="flex justify-between">
<text></text>
<view class="btn" @tap="handleAddressRecognition">{{i18n["填写"]}}</view>
</view> -->
</view>
<view class="flex justify-between bg-white" style="padding: 32rpx 32rpx; border-top: 1px solid #f5f6f7;">
<view class="flex align-center">设置默认地址</view>
<switch class="switch" :class="is_default ? 'checked-green' : ''" @change="handleSwitch"
:checked="is_default ? true : false"></switch>
<!-- <switch class='theme' @change="handleSwitch" :class="is_default?'checked':''" :checked="is_default?true:false"></switch> -->
</view>
<!-- 表单信息 end -->
<!-- 服务标签弹框 start -->
<fu-popup v-model="serve_show" mode="bottom" :safe-area-inset-bottom="true">
<view class="serve-pop flex align-center justify-center" :style="{bottom:keyboardheight+'px'}">
<input type="text" placeholder="请填写标签名称最多5个字" v-model='serveKeyword' maxlength="5" focus
:adjust-position='false' placeholder-class="placeholderServe">
<button @click='addServeInfo()'>添加</button>
</view>
</fu-popup>
<!-- 服务标签弹框 end -->
<!-- 底部占位 start -->
<!-- <view class="bottom-status"></view> -->
<!-- 底部占位 end -->
<!-- 提交按钮 start -->
<view class="bottom-action">
<view class="btn2" @click="beforeConfirm">保存</view>
</view>
<!-- 提交按钮 end -->
<!-- 地址选择插件 start -->
<w-picker
mode="region"
:value="defVal"
default-type="label"
themeColor="#FF6464"
@confirm="onConfirm($event)"
ref="region"
>选择所在地区</w-picker>
<!-- 地址选择插件 end -->
<!-- 断网监测 start -->
<fu-notwork></fu-notwork>
<!-- 断网监测 end -->
</view>
</template>
<script>
import wPicker from '@/pages/my/components/w-picker/w-picker.vue'
// 高德地图sdk
import amapFile from '@/common/amap-wx.js';
export default {
computed: {
// 合并省市区信息字段
address() {
return this.province + this.city + this.district;
},
},
components:{
wPicker
},
data() {
return {
keyboardheight: 0, // 键盘高度
serveKeyword: '', // 服务标签关键字
serve_show: false, // 服务标签弹框
serveList: [], // 服务标签
default_serve: '', // 默认服务标签
phone: '', // 联系电话
name: '', // 收货人姓名
sex: 1, // 性别 1:男 2:女
is_default: true, // 是否设为默认地址
edit_id: null, // 是否是修改收货地址
myAmapFun: null, // 高德地图实例
province: '', // 省
city: '', //市
district: '', //区
provinceCode: '', // 省 code码
cityCode: '', //市 code码
districtCode: '', //区 code码
addressDesc: '', // 详细地址
baiduAddress: '',
lng: '',
lat: '',
customStyle: {
'backgroundColor': '#cccccc',
'color': '#ffffff',
},// 自定义按钮样式
defVal: [],
};
},
/**
* @description 页面入参
* @param {object} options = [id]
* @param {string} id = 修改的地址ID
*/
onLoad(options) {
this.setNavigationBarTitle('添加地址')
// 监听键盘高度
uni.onKeyboardHeightChange((res) => {
console.log("键盘监听", res);
this.keyboardheight = res.height;
});
// 初始化高德地图SDK,记得换成自己的key
this.myAmapFun = new amapFile.AMapWX({ key: '886bfe2d6c32bd8eac97c2e6d821ed0b' });
//如果是修改地址
if (options.id) {
this.edit_id = options.id;
// 换标题文字
uni.setNavigationBarTitle({
title: '编辑地址'
});
// 获取要修改的地址信息
this.get_editAddress();
} else {
// 自动定位当前地址
// this.autoGetLocation();
// 获取默认标签
this.getLabelData()
}
},
onShow() {
this.getPublishStatus()
},
methods: {
handleAddressRecognition() {
let baiduAddress = this.baiduAddress
if (!baiduAddress) {
this.$message.info('请先粘贴地址~');
return;
}
this.$api.post(global.apiUrls.postAddressRecognition, {address: baiduAddress}).then(res => {
let data = res.data;
console.log(data);
if (data.code == 1) {
this.name = data.data.name ? data.data.name.trim() : ''
this.phone = data.data.mobile || ''
this.addressDesc = data.data.address || ''
this.province = data.data.province;
this.city = data.data.city;
this.district = data.data.area;
} else {
this.$message.info(data.msg);
}
});
},
/**
* @description 删除地址
* */
delAddr() {
this.$util.showModal({
title: '提示',
content: '确定删除该地址?',
confirmColor: this.$store.state.themeColor,
success: (res) => {
if (res.confirm) {
this.$api.post(global.apiUrls.post5cadd0d3a0c93, { address_id: this.edit_id })
.then(res => {
console.log(res);
this.$message.info(res.data.msg);
if (res.data.code == 1) {
setTimeout(() => {
uni.navigateBack({
delta: 1
})
}, 800)
}
});
}
}
})
},
/**
* @func 获取服务标签列表
*/
getLabelData(val) {
this.$api.post(global.apiUrls.getAddressLabelList, {}).then(res => {
if (res.data.code == 1) {
console.log('服务标签列表', res.data.data)
this.serveList = res.data.data
let serve = uni.getStorageSync('DEFAULT_SERVE');
// 判断是否为编辑
if (this.edit_id) {
this.default_serve = {
id: 0,
name: val
}
var flag = this.serveList.filter((item) => {
return item.name == val
})
if (flag.length == 0) {
if(this.default_serve.name) this.serveList.push(this.default_serve);
}
} else {
if (serve && this.serveList !=0) {
this.default_serve = this.serveList[0]
this.serveList.push(JSON.parse(serve))
}
}
} else {
this.$message.info(res.data.msg);
}
}).catch(err => {
this.$message.info(err.msg);
})
},
/**
* @description 自定义服务标签弹窗显示
* @param {String} name 回显自定义标签关键词
*/
addServe(name) {
if (name) {
this.serveKeyword = name
}
this.serve_show = true //弹窗显示
},
/**
* @func 新增服务标签
*/
addServeInfo() {
let val = this.serveKeyword.trim()
if (val) {
console.log(this.serveList)
var flag = this.serveList.filter((item) => {
return item.name == val
})
console.log(flag)
if (flag.length == 0) {
this.serve_show = false // 弹窗隐藏
let serve = { id: 0, name: val }
// 存在自定义标签
if (this.serveList.length > 3) {
this.serveList[3] = serve
} else {
this.serveList.push(serve)
}
this.default_serve = serve
if (!this.edit_id) {
uni.setStorageSync('DEFAULT_SERVE', JSON.stringify(serve));
}
} else {
this.$message.info('标签已存在');
}
} else {
this.$message.info('请输入内容');
}
},
/**
* @description 切换服务标签
* @param {String} item = 服务标签关键字
*/
changeServe(item) {
this.default_serve = item;
},
/**
* @description 选择性别
* @param {String} type = 性别
*/
chooseSex(type) {
this.sex = type;
},
/**
* @func 获取修改地址信息
*/
get_editAddress() {
this.$api.post(global.apiUrls.post636fd7826b3ee, {
address_id: this.edit_id
}).then(res => {
console.log(res, '修改的信息');
if (res.data.code == 1) {
let data = res.data.data;
this.name = data.real_name; // 收货人姓名
this.phone = data.mobile; // 收货人电话
this.province = data.province; // 省
this.city = data.city; // 市
this.district = data.district; // 区
this.addressDesc = data.detail; // 详细地址
this.sex = data.sex; // 性别
this.is_default = data.is_default == '1' ? true : false; // 是否默认
this.defVal = [data.province,data.city,data.district];
// 服务标签
this.getLabelData(data.label_name)
} else {
this.$message.info(res.data.msg);
}
}).catch(err => {
this.$message.info(err.msg);
})
},
/**
* @func 显示地址选择弹窗
*/
showMulLinkageThreePicker() {
uni.hideKeyboard();
this.$refs.region.show();
},
/**
* @description 地址选择回调
* @param {Object} val = 地址信息对象
*/
onConfirm(val) {
this.province = val.obj.province.label;
this.city = val.obj.city.label;
this.district = val.obj.area.label;
this.provinceCode = val.value[0];
this.cityCode = val.value[1];
this.districtCode = val.value[2];
},
/**
* @func 切换是否为默认地址
*/
handleSwitch(e) {
this.is_default = e.detail.value;
},
/**
* @func 定位地址
*/
location() {
let _this = this;
//#ifdef MP-WEIXIN
uni.getSetting({
success(res) {
// 获取设置成功
console.log(res.authSetting);
if (!res.authSetting['scope.userLocation']) {
// 如果没开启权限提示打开
uni.openSetting({
success(res) {
// 打开成功,提示获取权限
console.log(res.authSetting);
uni.authorize({
scope: 'scope.userLocation',
success(res) {
_this.chooseLocation();
},
fail(res) {
console.log(res);
this.$message.info('打开权限失败');
}
});
}
});
} else {
_this.chooseLocation();
}
}
});
//#endif
this.chooseLocation();
},
/**
* @func 地图选点
*/
chooseLocation() {
uni.getLocation({
type: 'gcj02',
success: adr => {
uni.chooseLocation({
latitude: adr.latitude,
longitude: adr.longitude,
success: (res) => {
console.log(res, '地图');
this.myAmapFun.getRegeo({
location: res.longitude + ',' + res.latitude,
success: (data) => {
//成功回调
console.log('sdk回调', data);
let regeoData = data[0].regeocodeData.addressComponent;
this.lng = res.longitude;
this.lat = res.latitude;
this.province = regeoData.province;
this.city = Array.isArray(regeoData.city) && (regeoData.city.length == 0) ? regeoData.province: regeoData.city;
this.district = regeoData.district;
this.addressDesc = (res.address || '') + (res.name || '');
this.provinceCode = regeoData.adcode.substr(0,2)+'0000';
this.cityCode = regeoData.adcode.substr(0,4)+'00';
this.districtCode = regeoData.adcode+'';
},
fail: (info) => {
//失败回调
console.log(info)
}
})
}
})
}
})
},
/**
* @func 地图选点
*/
_chooseLocation() {
uni.getLocation({
type: 'gcj02',
success: adr => {
this.myAmapFun.getRegeo({
location: adr.longitude + ',' + adr.latitude,
success: (data) => {
//成功回调
console.log('sdk回调', data);
let regeoData = data[0].regeocodeData.addressComponent;
this.lng = adr.longitude;
this.lat = adr.latitude;
this.province = regeoData.province;
this.city = Array.isArray(regeoData.city) && (regeoData.city.length == 0) ? regeoData.province: regeoData.city;
this.district = regeoData.district || this.city;
this.addressDesc = ( data[0].name || '') + ( data[0].desc || '');
this.provinceCode = regeoData.adcode.substr(0,2)+'0000';
this.cityCode = regeoData.adcode.substr(0,4)+'00';
this.districtCode = regeoData.adcode+'';
},
fail: (info) => {
//失败回调
console.log(info)
}
})
}
})
},
/**
* @func 自动定位
*/
autoGetLocation() {
console.log("自动定位");
let that = this
uni.getLocation({
geocode: true,
success: (adr) => {
that.myAmapFun.getRegeo({
location: adr.longitude + ',' + adr.latitude,
success: (data) => {
//成功回调
console.log('自动定位 SDK回调', data);
let regeoData = data[0].regeocodeData.addressComponent;
this.lng = adr.longitude;
this.lat = adr.latitude;
that.province = regeoData.province;
that.city = Array.isArray(regeoData.city) && (regeoData.city.length == 0) ? regeoData.province: regeoData.city;
that.district = regeoData.district;
that.addressDesc = that.province + that.city + that.district + data[0].desc;
that.provinceCode = regeoData.adcode.substr(0,2)+'0000';
that.cityCode = regeoData.adcode.substr(0,4)+'00';
that.districtCode = regeoData.adcode+'';
},
fail: (info) => {
//失败回调
console.log(info)
}
})
}
})
},
//
beforeConfirm(){
this.$util.debounce(this.sub_sure,1500,true);
},
/**
* @func 提交表单
*/
sub_sure() {
// 表单验证
if (this.name.trim() == '') {
this.$message.info('请输入收货人姓名');
this.name = '';
return false;
};
if (!/^1(3|4|5|6|7|8|9)\d{9}$/.test(this.phone)) {
let text = !this.phone ? '请输入手机号' : '手机号格式不正确';
this.$message.info(text);
return false;
}
if (this.address.trim() == '') {
this.$message.info('地区不能为空');
return false;
}
//判断是否含有特殊字符
let iconRule1 = /[`~!@#$%^&*_\+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&* ——\+={}|《》?:“”【】;‘’,。]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
if (this.addressDesc.trim() == '') {
this.$message.info('详细地址不能为空');
this.addressDesc = '';
return false;
}
// if (iconRule1.test(this.addressDesc)) {
// this.$message.info('详细地址不能含有特殊字符');
// // this.addressDesc = '';
// return false;
// }
// if (iconRule2.test(this.addressDesc)) {
// this.$message.info('详细地址不能含有表情');
// // this.addressDesc = '';
// return false;
// }
let data = {
real_name: this.name, // 收货人姓名
mobile: this.phone, // 收货人手机
is_default: this.is_default ? '1' : '0', // 是否默认地址
detail: this.addressDesc, // 详细地址
province: this.province, // 省
city: this.city, // 市
district: this.district, // 区
provinceCode: this.provinceCode, // 省 code码
cityCode: this.cityCode, //市 code码
districtCode: this.districtCode, //区 code码
sex:this.sex,
lng:this.lng,
lat:this.lat,
label_name: this.default_serve ? this.default_serve.name : '' // 标签name
}
if (!data.label_name) {
this.$message.info('请选择地址标签');
this.name = '';
return false;
};
console.log(data)
// 判断提交的接口
let url = global.apiUrls.post637defdbd53ef;
if (this.edit_id) {
data.address_id = this.edit_id
url = global.apiUrls.post637df1ea39d16;
}
console.log('提交的地址参数',data);
console.log('提交的地址',url);
// 提交请求
this.$api.post(url, data)
.then(res => {
console.log(res, '添加/编辑成功');
if (res.data.code == 1) {
// this.$message.info(res.data.msg);
// 通知商品详情页更新地址数据
uni.$emit('refreshAddress',res.data.data.address_id);
setTimeout(() => {
uni.navigateBack()
}, 800);
} else {
this.$message.info(res.data.msg)
}
})
.catch(err => {
console.log("err: ", err);
})
},
/**
* @func 清除手机号
*/
clear() {
this.phone = '';
}
}
}
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #F6F7F9;
overflow: hidden;
}
.tag{
padding: 0 16rpx;
margin-right: 10rpx;
line-height: 52rpx;
border: 1rpx solid #333;
}
.bottom-status {
height: 156rpx;
height: calc(156rpx + constant(safe-area-inset-bottom));
height: calc(156rpx + env(safe-area-inset-bottom));
}
.cuIcon-right {
transform:rotate(-90deg);
-ms-transform:rotate(-90deg); /* IE 9 */
-moz-transform:rotate(-90deg); /* Firefox */
-webkit-transform:rotate(-90deg); /* Safari 和 Chrome */
-o-transform:rotate(-90deg); /* Opera */
}
.text-area {
height: 140rpx !important;
background-color: #F6F6F6;
padding: 20rpx;
border-radius: 8rpx;
}
.text-ai {
width: 100%;
height: 180rpx !important;
background-color: #fff;
padding: 24rpx 0;
border-radius: 8rpx;
}
.btn {
margin-bottom: 32rpx;
display: flex;
align-items: center;
justify-content: center;
width: 124rpx;
height: 56rpx;
border: 1px solid #006AB9;
opacity: 1;
color: #006AB9;
font-size: 24rpx;
border-radius: 28rpx;
}
/deep/ .uni-textarea-textarea{
line-height: 1.5;
}
.addAddr {
padding: 0 32upx;
background: #fff;
.uni-list-cell {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin: 20upx 0;
box-sizing: border-box;
height: 100upx;
font-size: 30upx;
background: #fff;
}
.addr {
font-size: 32upx;
padding: 30upx 0;
border-bottom: 1px solid #f5f5f7;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
.addr_title {
display: inline-block;
width: 180rpx;
}
.chose_addr {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 70%;
}
}
.cell {
font-size: 32upx;
display: flex;
flex-direction: row;
align-items: center;
padding: 32rpx 0;
border-bottom: 1px solid #f5f5f7;
.title {
display: inline-block;
width: 180rpx;
}
input {
flex: 1;
color: #333;
}
.text-area {
flex: 1;
}
}
.address {
display: flex;
flex-direction: column;
font-size: 32upx;
.title {
line-height: 110upx;
}
}
.tips {
padding: 20upx 0;
font-size: 26upx;
}
}
.placeholderClass {
font-size: 32rpx;
color: #BFBFBF;
}
.active {
color: #0CBC56;
}
switch::before,
switch::after {
content: "";
}
.bottom-action {
position: fixed;
bottom: 56rpx;
left: 32rpx;
width: 686rpx;
display: flex;
view {
height: 88rpx;
flex: 1;
line-height: 88rpx;
text-align: center;
border-radius: 88rpx;
color: #FFFFFF;
}
.btn2 {
background: rgba(255, 147, 0, 1);
}
}
/deep/ uni-switch.checked-green .uni-switch-input {
background-color: #39b54a !important;
border-color: #39b54a !important;
color: #ffffff !important;
}
/deep/ .switch {
transform: scale(0.7);
}
.serve-pop {
height: 100rpx;
position: fixed;
bottom: 0;
width: 100%;
background-color: #FFFFFF;
input {
margin-left: 32rpx;
width: 528rpx;
height: 66rpx;
background: #F6F7F9;
opacity: 1;
border-radius: 35rpx;
font-size: 28rpx;
font-weight: 400;
color: #99999A;
text-indent: 1em;
}
button {
width: 140rpx;
height: 66rpx;
background: #FF9300;
border-radius: 33rpx;
font-size: 28rpx;
font-weight: 400;
color: #FFFFFF;
}
}
.left-0 {
margin-left: 2rpx;
}
.radius-left {
border-top-left-radius: 20rpx;
border-bottom-left-radius: 20rpx;
}
.radius-right {
border-top-right-radius: 20rpx;
border-bottom-right-radius: 20rpx;
}
.bg-orange2{
// border: 1px solid #FF9300;
background: #59A6F4;
color: #fff;
}
.bg-green{
border: 1px solid #FF9300;
background: #FF9300;
color: #fff;
}
.placeholder{
font-size: 28rpx;
font-weight: 400;
color: #BFBFBF;
}
.placeholderServe{
font-size: 28rpx;
font-weight: 400;
color: #99999A;
}
</style>