|
|
@@ -3,72 +3,53 @@
|
|
|
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
|
|
<view class="sidebar-margin card-template mt-[var(--top-m)] py-[20rpx]">
|
|
|
<view>
|
|
|
- <u-form-item :label="t('name')" prop="name" labelWidth="200rpx">
|
|
|
- <u-input fontSize="28rpx" v-model.trim="formData.name" border="none" clearable maxlength="25" placeholderStyle="color: #888" :placeholder="t('namePlaceholder')" />
|
|
|
+ <u-form-item label="收货人" prop="consignee" labelWidth="200rpx">
|
|
|
+ <u-input fontSize="28rpx" v-model.trim="formData.consignee" border="none" clearable
|
|
|
+ maxlength="25" placeholderStyle="color: #888" placeholder="请输入收货人姓名" />
|
|
|
</u-form-item>
|
|
|
</view>
|
|
|
<view class="mt-[16rpx]">
|
|
|
- <u-form-item :label="t('mobile')" prop="mobile" labelWidth="200rpx">
|
|
|
- <u-input fontSize="28rpx" v-model.trim="formData.mobile" maxlength="11" border="none" clearable :placeholder="t('mobilePlaceholder')" placeholderStyle="color: #888" />
|
|
|
+ <u-form-item label="手机号码" prop="phone" labelWidth="200rpx">
|
|
|
+ <u-input fontSize="28rpx" v-model.trim="formData.phone" maxlength="11" border="none" clearable
|
|
|
+ placeholder="请输入手机号码" placeholderStyle="color: #888" />
|
|
|
</u-form-item>
|
|
|
</view>
|
|
|
<view class="mt-[16rpx]">
|
|
|
- <u-form-item :label="t('selectArea')" prop="area" labelWidth="200rpx">
|
|
|
- <view class="flex w-full items-center h-[52rpx]" v-if="addressType == 'address' && isSelectMap != 1" @click="selectArea">
|
|
|
- <view v-if="!formData.area" class="text-[#888] text-[28rpx] flex-1">{{ t('selectAreaPlaceholder') }}</view>
|
|
|
- <view v-else class="text-[28rpx] flex-1 leading-[1.4]">{{ formData.area }}</view>
|
|
|
- <view @click.stop="chooseLocation" class="flex items-center">
|
|
|
- <text class="nc-iconfont nc-icon-dizhiguanliV6xx mr-[4rpx] text-[32rpx] text-[var(--primary-color)]"></text>
|
|
|
- <text class="text-[24rpx] whitespace-nowrap text-[var(--primary-color)]">定位</text>
|
|
|
+ <u-form-item label="选择地区" prop="provincialCityCountry" labelWidth="200rpx">
|
|
|
+ <view class="flex w-full items-center h-[52rpx]" @click="selectArea">
|
|
|
+ <view v-if="!formData.provincialCityCountry" class="text-[#888] text-[28rpx] flex-1">请选择地区
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <view v-else class="flex justify-between items-center flex-1 h-[52rpx]" @click="chooseLocation">
|
|
|
- <view class="text-[28rpx] text-[#303133] leading-[1.4]" v-if="formData.area || formData.address_name">{{ formData.area || formData.address_name }}</view>
|
|
|
- <view class="text-[#888] text-[28rpx]" v-else>{{ t('selectAddressPlaceholder') }}</view>
|
|
|
- <view class="flex items-center">
|
|
|
- <text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[32rpx] mr-[4rpx] text-[var(--primary-color)]"></text>
|
|
|
- <text class="text-[24rpx] whitespace-nowrap text-[var(--primary-color)]">定位</text>
|
|
|
+ <view v-else class="text-[28rpx] flex-1 leading-[1.4]">{{ formData.provincialCityCountry }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</u-form-item>
|
|
|
</view>
|
|
|
<view class="mt-[16rpx]">
|
|
|
- <u-form-item :label="t('address')" prop="address" labelWidth="200rpx">
|
|
|
- <u-input fontSize="28rpx" v-model="formData.address" border="none" clearable maxlength="120" :placeholder="t('addressPlaceholder')" placeholderStyle="color: #888" />
|
|
|
+ <u-form-item label="详细地址" prop="address" labelWidth="200rpx">
|
|
|
+ <u-input fontSize="28rpx" v-model="formData.address" border="none" clearable maxlength="120"
|
|
|
+ placeholder="请填写详细地址" placeholderStyle="color: #888" />
|
|
|
</u-form-item>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="sidebar-margin card-template mt-[var(--top-m)] py-[10rpx]">
|
|
|
- <u-form-item :label="t('defaultAddress')" prop="name" :border-bottom="false" labelWidth="200rpx">
|
|
|
- <u-switch v-model="formData.is_default" size="20" :activeValue="1" :inactiveValue="0" activeColor="var(--primary-color)" inactiveColor="var(--temp-bg)" />
|
|
|
+ <u-form-item label="设为默认地址" prop="name" :border-bottom="false" labelWidth="200rpx">
|
|
|
+ <u-switch v-model="formData.defaultAddress" size="20" :activeValue="0" :inactiveValue="1"
|
|
|
+ activeColor="var(--primary-color)" inactiveColor="var(--temp-bg)" />
|
|
|
</u-form-item>
|
|
|
</view>
|
|
|
</u-form>
|
|
|
-
|
|
|
<view class="w-full footer">
|
|
|
-
|
|
|
<view
|
|
|
class="py-[var(--top-m)] px-[var(--sidebar-m)] footer w-full fixed bottom-30 left-0 right-0 box-border">
|
|
|
<button hover-class="none"
|
|
|
- class="primary-btn-bg !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500"
|
|
|
- @click="save" :disabled="btnDisabled" :loading="operateLoading"
|
|
|
- :class="{'opacity-50': btnDisabled}">{{ t('save') }}
|
|
|
+ class="primary-btn-bg !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500"
|
|
|
+ @click="save" :disabled="btnDisabled" :loading="operateLoading"
|
|
|
+ :class="{ 'opacity-50': btnDisabled }">保存
|
|
|
</button>
|
|
|
- <!-- #ifdef MP-WEIXIN -->
|
|
|
- <button hover-class="none"
|
|
|
- class=" bg-[#fff] !text-[var(--primary-color)] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500 mt-[30rpx] borders"
|
|
|
- @click="choosegAddress" :disabled="btnDisabled" :loading="loadingchoosegAddress"
|
|
|
- > <text class="nc-iconfont nc-icon-weixinV6mm"></text> 获取微信地址
|
|
|
- </button>
|
|
|
- <!-- #endif -->
|
|
|
</view>
|
|
|
-
|
|
|
</view>
|
|
|
- <area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id || formData.city_id" />
|
|
|
- <!-- #ifdef MP-WEIXIN -->
|
|
|
- <!-- 小程序隐私协议 -->
|
|
|
- <wx-privacy-popup ref="wxPrivacyPopupRef"></wx-privacy-popup>
|
|
|
- <!-- #endif -->
|
|
|
+ <cityPicker :column="column" :default-value="defaultValue" :mask-close-able="maskCloseAble" @confirm="confirm"
|
|
|
+ @cancel="cancel" :visible="visible" />
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
@@ -77,129 +58,104 @@
|
|
|
import { ref, computed, nextTick } from 'vue'
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
import { redirect } from '@/utils/common'
|
|
|
-import { t } from '@/locale'
|
|
|
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
|
|
|
-import manifestJson from '@/manifest.json'
|
|
|
-import { getAddressByLatlng } from '@/app/api/system'
|
|
|
+import cityPicker from '@/uni_modules/piaoyi-cityPicker/components/piaoyi-cityPicker/piaoyi-cityPicker'
|
|
|
|
|
|
+const column = ref(3)
|
|
|
+const defaultValue = ref<any>(null)
|
|
|
+const maskCloseAble = ref<any>(true)
|
|
|
+const visible = ref<any>(false)
|
|
|
const formData: any = ref({
|
|
|
- id: 0,
|
|
|
- name: '',
|
|
|
- mobile: '',
|
|
|
- province_id: 0,
|
|
|
- city_id: 0,
|
|
|
- district_id: 0,
|
|
|
- lat: '',
|
|
|
- lng: '',
|
|
|
- address: '',
|
|
|
- address_name: '',
|
|
|
- full_address: '',
|
|
|
- is_default: 0,
|
|
|
- area: ''
|
|
|
+ consignee: '', phone: '', provincialNo: '', cityNo: '', countryNo: '', provincialCityCountry: '', address: '', defaultAddress: 0
|
|
|
})
|
|
|
-const areaRef = ref()
|
|
|
+
|
|
|
const formRef: any = ref(null)
|
|
|
const source = ref('')
|
|
|
const btnDisabled = ref(false)
|
|
|
-const isSelectAddress = ref(false)
|
|
|
-const addressType = ref('address');
|
|
|
-const isSelectMap = ref(2) // 值为1,该地址需要有经纬度,反之不需要
|
|
|
-
|
|
|
-const wxPrivacyPopupRef: any = ref(null)
|
|
|
|
|
|
onLoad((data: any) => {
|
|
|
- isSelectMap.value = data.isSelectMap || '';
|
|
|
- const selectAddress = uni.getStorageSync('selectAddressCallback')
|
|
|
if (data.id) {
|
|
|
getAddressInfo(data.id).then((res: any) => {
|
|
|
+ res.data.defaultAddress = Number(res.data.defaultAddress)
|
|
|
res.data && Object.assign(formData.value, res.data)
|
|
|
- // 兼容待支付页面编辑地址
|
|
|
- if (selectAddress) {
|
|
|
- addressType.value = selectAddress.delivery == 'express' ? 'address' : 'locationAddress';
|
|
|
- }
|
|
|
})
|
|
|
-
|
|
|
- } else if (data.name) {
|
|
|
- if (uni.getStorageSync('addressInfo')) {
|
|
|
- Object.assign(formData.value, uni.getStorageSync('addressInfo'))
|
|
|
+ } else {
|
|
|
+ formData.value = {
|
|
|
+ consignee: '', phone: '', provincialNo: '', cityNo: '', countryNo: '', provincialCityCountry: '', address: '', defaultAddress: 0
|
|
|
}
|
|
|
- formData.value.address = data.name;
|
|
|
- getAddress(data.latng);
|
|
|
- const tempArr = getQueryVariable('latng').split(',');
|
|
|
- formData.value.lat = tempArr[0];
|
|
|
- formData.value.lng = tempArr[1];
|
|
|
- }
|
|
|
- source.value = data.source || ''
|
|
|
- if (selectAddress) {
|
|
|
- addressType.value = selectAddress.delivery == 'express' ? 'address' : 'locationAddress';
|
|
|
}
|
|
|
- // #ifdef MP
|
|
|
- nextTick(() => {
|
|
|
- if (wxPrivacyPopupRef.value) wxPrivacyPopupRef.value.proactive();
|
|
|
- })
|
|
|
- // #endif
|
|
|
})
|
|
|
|
|
|
const rules = computed(() => {
|
|
|
return {
|
|
|
- 'name': {
|
|
|
+ 'consignee': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
- message: t('namePlaceholder'),
|
|
|
+ message: '请输入收货人姓名',
|
|
|
trigger: ['blur', 'change'],
|
|
|
},
|
|
|
- 'mobile': [
|
|
|
+ 'phone': [
|
|
|
{
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
- message: t('mobilePlaceholder'),
|
|
|
+ message: '请输入手机号码',
|
|
|
trigger: ['blur', 'change'],
|
|
|
},
|
|
|
{
|
|
|
validator(rule: any, value: any, callback: any) {
|
|
|
let mobile = /^1[3-9]\d{9}$/;
|
|
|
if (!mobile.test(value)) {
|
|
|
- callback(new Error(t('mobileError')))
|
|
|
+ callback(new Error('请输入正确的手机号'))
|
|
|
} else {
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
],
|
|
|
- 'area': {
|
|
|
+ 'provincialCityCountry': {
|
|
|
validator() {
|
|
|
let bool = true;
|
|
|
- if (uni.$u.test.isEmpty(formData.value.area) && uni.$u.test.isEmpty(formData.value.address_name)) {
|
|
|
+ if (uni.$u.test.isEmpty(formData.value.provincialCityCountry)) {
|
|
|
bool = false;
|
|
|
}
|
|
|
return bool
|
|
|
},
|
|
|
- message: t('selectAreaPlaceholder')
|
|
|
+ message: '请选择地区'
|
|
|
},
|
|
|
'address': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
- message: t('addressPlaceholder'),
|
|
|
+ message: '请填写详细地址',
|
|
|
trigger: ['blur', 'change']
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-const selectArea = () => {
|
|
|
- isSelectAddress.value = true
|
|
|
- areaRef.value.open()
|
|
|
+const cancel = () => {
|
|
|
+ visible.value = false
|
|
|
}
|
|
|
|
|
|
-const areaSelectComplete = (event: any) => {
|
|
|
- if (isSelectAddress.value && (formData.value.province_id == event.province?.id || formData.value.city_id != event.city?.id || formData.value.district_id != event.district?.id)) {
|
|
|
- formData.value.lat = '';
|
|
|
- formData.value.lng = '';
|
|
|
- }
|
|
|
- formData.value.province_id = event.province?.id || 0
|
|
|
- formData.value.city_id = event.city?.id || 0
|
|
|
- formData.value.district_id = event.district?.id || 0
|
|
|
- formData.value.area = `${ event.province?.name || '' }${ event.city?.name || '' }${ event.district?.name || '' }`
|
|
|
- isSelectAddress.value = false;
|
|
|
+const confirm = (res: any) => {
|
|
|
+ formData.value.provincialCityCountry = res.provinceName + '/' + res.cityName + '/' + res.areaName
|
|
|
+ formData.value.provincialNo = parseAreaCode(res.code).province;
|
|
|
+ formData.value.cityNo = parseAreaCode(res.code).city;
|
|
|
+ formData.value.countryNo = res.code;
|
|
|
+ visible.value = false
|
|
|
+}
|
|
|
+
|
|
|
+const parseAreaCode = (code: any) => {
|
|
|
+ const provinceCode = code.substring(0, 2) + '0000';
|
|
|
+ const cityCode = code.substring(0, 4) + '00';
|
|
|
+ const districtCode = code;
|
|
|
+ return {
|
|
|
+ province: provinceCode,
|
|
|
+ city: cityCode,
|
|
|
+ district: districtCode
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+const selectArea = () => {
|
|
|
+ visible.value = true
|
|
|
}
|
|
|
|
|
|
const operateLoading = ref(false)
|
|
|
@@ -211,18 +167,6 @@ const save = () => {
|
|
|
|
|
|
btnDisabled.value = true
|
|
|
|
|
|
- formData.value.full_address = formData.value.area + formData.value.address
|
|
|
-
|
|
|
- if (isSelectMap.value == 1 && !formData.value.lat && !formData.value.lng) {
|
|
|
- uni.showToast({
|
|
|
- title: '缺少经纬度,请在地图上重新选点',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- operateLoading.value = false;
|
|
|
- btnDisabled.value = false
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
save(formData.value).then((res: any) => {
|
|
|
operateLoading.value = false
|
|
|
setTimeout(() => {
|
|
|
@@ -254,102 +198,6 @@ const save = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 选择地址
|
|
|
-const chooseLocation = () => {
|
|
|
- // #ifdef MP
|
|
|
- uni.chooseLocation({
|
|
|
- success: (res) => {
|
|
|
- res.latitude && (formData.value.lat = res.latitude)
|
|
|
- res.longitude && (formData.value.lng = res.longitude)
|
|
|
- res.address && (formData.value.area = res.address)
|
|
|
- res.name && (formData.value.address_name = res.address)
|
|
|
- res.name && (formData.value.address = res.name)
|
|
|
- if (res.latitude && res.longitude) {
|
|
|
- let latng = res.latitude + ',' + res.longitude;
|
|
|
- getAddress(latng);
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (res) => {
|
|
|
- // 在隐私协议中没有声明chooseLocation:fail api作用域
|
|
|
- if (res.errMsg && res.errno) {
|
|
|
- if (res.errno == 104) {
|
|
|
- let msg = '用户未授权隐私权限,选择位置失败';
|
|
|
- uni.showToast({ title: msg, icon: 'none' })
|
|
|
- } else if (res.errno == 112) {
|
|
|
- let msg = '隐私协议中未声明,打开地图选择位置失败';
|
|
|
- uni.showToast({ title: msg, icon: 'none' })
|
|
|
- } else {
|
|
|
- uni.showToast({ title: res.errMsg, icon: 'none' })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- // #endif
|
|
|
-
|
|
|
- // #ifdef H5
|
|
|
- const urlencode = formData.value;
|
|
|
- uni.setStorageSync('addressInfo', urlencode);
|
|
|
- let backurl = location.origin + location.pathname + '?source=' + source.value;
|
|
|
- if (isSelectMap.value) {
|
|
|
- backurl = backurl + '&isSelectMap=' + isSelectMap.value
|
|
|
- }
|
|
|
- window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + encodeURIComponent(backurl) + '&key=' + manifestJson.h5.sdkConfigs.maps.qqmap.key + '&referer=myapp';
|
|
|
- // #endif
|
|
|
-}
|
|
|
-
|
|
|
-//获取详细地址
|
|
|
-const getAddress = (latlng: any) => {
|
|
|
- getAddressByLatlng({ latlng }).then((res: any) => {
|
|
|
- if (res.data) {
|
|
|
- formData.value.full_address = '';
|
|
|
- formData.value.full_address += res.data.province != undefined ? res.data.province : '';
|
|
|
- formData.value.full_address += res.data.city != undefined ? '' + res.data.city : '';
|
|
|
- formData.value.full_address += res.data.district != undefined ? '' + res.data.district : '';
|
|
|
-
|
|
|
- formData.value.address_name = formData.value.full_address.replace(/-/g, '');
|
|
|
- formData.value.area = (res.data.province + res.data.city + res.data.district) || res.data.full_address;
|
|
|
-
|
|
|
- formData.value.province_id = res.data.province_id != undefined ? res.data.province_id : 0;
|
|
|
- formData.value.city_id = res.data.city_id != undefined ? res.data.city_id : 0;
|
|
|
- formData.value.district_id = res.data.district_id != undefined ? res.data.district_id : 0;
|
|
|
- } else {
|
|
|
- uni.showToast({ title: res.msg, icon: 'none' })
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-const getQueryVariable = (variable: any) => {
|
|
|
- const query = window.location.search.substring(1);
|
|
|
- const vars = query.split('&');
|
|
|
- for (let i = 0; i < vars.length; i++) {
|
|
|
- const pair = vars[i].split('=');
|
|
|
- if (pair[0] == variable) {
|
|
|
- return pair[1];
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
-}
|
|
|
-const loadingchoosegAddress = ref(false)
|
|
|
-const choosegAddress = () =>{
|
|
|
- loadingchoosegAddress.value = true
|
|
|
- uni.chooseAddress({
|
|
|
- success(res) {
|
|
|
- console.log(7744)
|
|
|
- loadingchoosegAddress.value = false
|
|
|
- // 将地址信息格式化为“名字-手机号-地址(详细地址)”
|
|
|
- // const formattedAddress = `${res.userName}-${res.telNumber}-${res.provinceName}${res.cityName}${res.countyName}${res.detailInfoNew || res.detailInfo}`;
|
|
|
- console.log(res)
|
|
|
- formData.value.name = res.userName
|
|
|
- formData.value.mobile = res.telNumber
|
|
|
- formData.value.area = res.provinceName + res.cityName + res.countyName
|
|
|
- formData.value.address = res.detailInfo
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- loadingchoosegAddress.value = false
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@@ -365,7 +213,8 @@ const choosegAddress = () =>{
|
|
|
height: calc(100rpx + var(--top-m) + var(--top-m) + constant(safe-area-inset-bottom)) !important;
|
|
|
height: calc(100rpx + var(--top-m) + var(--top-m) + env(safe-area-inset-bottom)) !important;
|
|
|
}
|
|
|
-.borders{
|
|
|
+
|
|
|
+.borders {
|
|
|
border: 1px solid var(--primary-color);
|
|
|
}
|
|
|
</style>
|