addSite.vue 9.39 KB
<template>
	<view class="wrap">
		<view class="wrap-from-container">
			<city-select v-model="cityPikerShowFlag" @city-change="handleCityChange"></city-select>
			<u--form :labelStyle="{ color: '#303133' }" labelWidth="140" labelPosition="top" :model="addressInfo"
				ref="addressFrom">
				<u-form-item :required="true" label="所在地区" prop="addressArea" borderBottom>
					<view @click.stop="showRegionPicker" hover-class="click-box" style="width: 100%;">
						<u--input border="none" readonly style="pointer-events:none" type="text" v-model="addressInfo.addressArea"
							placeholder-class="line" placeholder="请选着所在地区"></u--input>
					</view>
				</u-form-item>
				<u-form-item :required="true" label="详细地址" prop="addressDetail" borderBottom>
					<view @click.stop="chooseAddressDetail" class="wrap-from-container-address-details"
						style="color:#606266;font-size: 28rpx;width: 100%;" hover-class="click-box">
						<view style="pointer-events: none; width: 100%;">
							<up-textarea :disabled="true" color="#606266" border="none" autoHeight style="pointer-events:none"
								v-model="addressInfo.addressDetail" placeholder="请选择详细地址"></up-textarea>
						</view>
					</view>
				</u-form-item>
				<u-form-item :required="true" label="联系人" prop="contactPerson" borderBottom>
					<u--input color="#606266" border="none" type="text" v-model="addressInfo.contactPerson"
						placeholder-class="line" placeholder="联系人"></u--input>
				</u-form-item>
				<u-form-item :required="true" label="联系电话" prop="contactIphoneNumber" borderBottom>
					<u--input color="#606266" border="none" type="text" v-model="addressInfo.contactIphoneNumber"
						placeholder-class="line" placeholder="联系电话"></u--input>
				</u-form-item>
			</u--form>
		</view>
		<view class="bottom">
			<view class="default">
				<view class="left">
					<view class="set">设置成默认地址</view>
				</view>
				<view class="right">
					<u-switch v-model="addressInfo.defaultFlag" size="40" activeColor="#19a97c"></u-switch>
				</view>
			</view>
		</view>
		<view class="submit-button">
			<view v-if="addFlag" @click="submit" class="add" hover-class="click-box">新增地址</view>
			<view v-else class="update-box">
				<view class="del" @click="handleDeleteClick" hover-class="click-box">删除地址</view>
				<view class="update" @click="handleUpdateClick" hover-class="click-box">保存地址</view>
			</view>
		</view>
	</view>
</template>

<script setup>
import { addAddress, deleteAddress, updateAddress } from '@/apis/address.js';
import { onLoad } from '@dcloudio/uni-app';
import { getCurrentInstance, onMounted, reactive, ref } from 'vue';
import citySelect from './citySelect/u-city-select.vue';
const { proxy } = getCurrentInstance();
const cityPikerShowFlag = ref(false)
const addFlag = ref(true)
const location = ref({});
const addressInfo = reactive({
	addressArea: "",
	addressDetail: "",
	contactPerson: "",
	contactIphoneNumber: "",
	defaultFlag: false
});

const rules = reactive({
	'addressArea': {
		type: 'string',
		required: true,
		message: '请选择区域',
		trigger: ['blur', 'change']
	},
	'addressDetail': {
		type: 'string',
		required: true,
		message: '请输入详细地址',
		trigger: ['blur', 'change']
	},
	'contactPerson': {
		type: 'string',
		required: true,
		message: '请输入联系人',
		trigger: ['blur', 'change']
	},
	'contactIphoneNumber': [{
		type: 'string',
		required: true,
		message: '手机号码不正确',
		trigger: ['blur', 'change']
	}, {
		validator: (rule, value, callback) => {
			return uni.$u.test.mobile(value);
		},
		message: '手机号码不正确',
		// 触发器可以同时用blur和change
		trigger: ['change', 'blur'],
	}]
})

const showRegionPicker = () => {
	cityPikerShowFlag.value = true;
}

const handleCityChange = (e) => {
	addressInfo.addressArea = e.province.label + '-' + e.city.label + '-' + e.area.label;
}

const handleDeleteClick = () => {
	uni.showModal({
		title: '',
		content: '是否确认删除这个地址',
		success: function (res) {
			if (res.confirm) {
				deleteAddress(addressInfo.garAddressId).then(res => {
					if (res.data.success) {
						uni.$u.toast(res.data.msg)
						jumpAddressList()
					}
				})
			} else if (res.cancel) {
			}
		}
	});

}

const handleUpdateClick = () => {
	updateAddress(addressInfo).then(res => {
		console.log(res);
		uni.$u.toast(res.data.msg)
		if (res.data.success) {
			setTimeout(() => {
				jumpAddressList();
			}, 200);
		}
	})
}

const jumpAddressList = () => {
	reset();
	uni.$u.route({
		type: 'navigateBack',
		url: `pages/home-info/address/index`,
	})
}

const submit = () => {
	proxy.$refs.addressFrom.validate().then(res => {
		addAddress(addressInfo).then(res => {
			uni.$u.toast(res.data.msg)
			if (res.data.success) {
				setTimeout(() => {
					jumpAddressList();
				}, 200);
			}
		})
	}).catch(errors => {
		uni.$u.toast('请填写正确信息!')
	})
}

/**
 * 打开地图选择地址(自动定位到当前位置,修复 startCompass:fail 问题)
 */
const chooseAddressDetail = () => {
  console.log('打开地图选择地址');

  // 先获取当前位置的经纬度
  uni.getLocation({
    type: 'gcj02', // 使用国测局坐标系,与地图选择器的坐标系一致
    altitude: false,
    success: (locationRes) => {
      console.log('获取当前位置成功', locationRes);

      // 使用获取到的经纬度作为初始位置打开地图选择器
      uni.chooseLocation({
        longitude: location.value.longitude, // 设置初始经度
        latitude: location.value.latitude, // 设置初始纬度
        success: (res) => {
          addressInfo.addressDetail = res.name;
          addressInfo.garLongitude = res.longitude;
          addressInfo.garLatitude = res.latitude;
        },
        fail: (err) => {
          console.error('地图选择失败:', err);
          uni.$u.toast('地图选择失败');
        }
      });
    },
    fail: (err) => {
      console.error('获取当前位置失败:', err);

      // 如果获取位置失败,仍然打开地图选择器,但不自动定位
      uni.chooseLocation({
        success: (res) => {
          addressInfo.addressDetail = res.name;
          addressInfo.garLongitude = res.longitude;
          addressInfo.garLatitude = res.latitude;
        },
        fail: (err) => {
          console.error('地图选择失败:', err);
          uni.$u.toast('地图选择失败');
        }
      });
    }
  });
};

onMounted(() => {
	proxy.$refs.addressFrom.setRules(rules)
  window.takeLocationCallBack = takeLocalCallBack
})

const takeLocalCallBack = (lngLat) => {
  const ll = lngLat.split(",");
  console.log(ll);
  location.value = {
    longitude: ll[0],
    latitude: ll[1]
  };
}

const takeLocation = () => {
  window.JsInterface.takeLocation();
}

onLoad((options) => {
	if (options.addressObj) {
		let addressObj = JSON.parse(options.addressObj);
		addressInfo.addressArea = addressObj.garUserAddress;
		addressInfo.contactPerson = addressObj.garUserContactName;
		addressInfo.contactIphoneNumber = addressObj.garUserContactTel;
		addressInfo.defaultFlag = addressObj.garUserDefault == 1 ? true : false;
		addressInfo.addressDetail = addressObj.garRemark;
		addressInfo.garAddressId = addressObj.garAddressId
		addressInfo.garLongitude = addressObj.garLongitude
		addressInfo.garLatitude = addressObj.garLatitude
		addFlag.value = false;
	}

	if(options.defaultFlag && 'true' == options.defaultFlag){
		addressInfo.defaultFlag = true;
	}
  takeLocation();
})
const reset = () => {
	addressInfo.addressArea = ''
	addressInfo.contactPerson = ''
	addressInfo.contactIphoneNumber = ''
	addressInfo.defaultFlag = false
	addressInfo.addressDetail = ''
	addressInfo.garAddressId = ''
	addressInfo.garLongitude = ''
	addressInfo.garLatitude = ''
	addFlag.value = true
}
</script>

<style lang="scss" scoped>
::v-deep .u-textarea {
	width: 100%;
	padding: 0px !important;
	background: white !important;
}

.wrap {
	box-sizing: border-box;
	padding: 15rpx;
	// background-color: $u-info-light;
	height: 100%;
	width: 100%;
	background: linear-gradient(to bottom, #19a97c, $u-info-light, $u-info-light, $u-info-light);

	.wrap-from-container {
		width: 100%;
		box-sizing: border-box;
		padding: 40rpx;
		background-color: #ffffff;
		margin-bottom: 20rpx;
		border-radius: 15rpx;
	}

	.bottom {
		margin-top: 20rpx;
		padding: 40rpx;
		background-color: #ffffff;
		font-size: 28rpx;
		border-radius: 15rpx;

		color: #909399;

		.default {
			margin-top: 50rpx;
			display: flex;
			justify-content: space-between;
			border-bottom: solid 2rpx $u-border-color;
			line-height: 64rpx;

			.tips {
				font-size: 20rpx;
			}

			.right {}
		}
	}




	.submit-button {
		display: flex;
		margin: auto;
		width: 80%;
		line-height: 100rpx;
		position: absolute;
		bottom: 30rpx;
		left: 10%;
		font-size: 30rpx;
		color: #ffffff;

		.add {
			background-color: #19a97c;
			border-radius: 60rpx;
			width: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
		}

		.update-box {
			width: 100%;
			display: flex;
			justify-content: space-around;

			.del {
				width: 100%;
				display: flex;
				align-items: center;
				justify-content: center;
				border-radius: 60rpx;
				background-color: $u-error-disabled;
				margin-right: 30rpx;
			}

			.update {
				width: 100%;
				background-color: #19a97c;
				border-radius: 60rpx;
				display: flex;
				align-items: center;
				justify-content: center;
			}
		}
	}
}

.click-box {
	@include handleClick;
}
</style>