329 lines
11 KiB
Vue
329 lines
11 KiB
Vue
<script setup lang="ts">
|
|
import ChooseImage from "@/components/choose-image/choose-image.vue";
|
|
import chooseState from "../components/choose-state.vue";
|
|
import { getStateListApi } from '@/pages-user/service'
|
|
|
|
|
|
const { t } = useI18n()
|
|
import VisitMethod from '@/components/visit-method/index.vue'
|
|
import BuildingType from './components/building-type.vue'
|
|
import {useAddressStore} from "../store/address";
|
|
import {appUserAddressAddPost, appUserAddressEditPost} from "@/service";
|
|
import {UserAddressType} from "@/constant/enums";
|
|
const addressStore = useAddressStore()
|
|
|
|
const visitMethodRef = ref<InstanceType<typeof VisitMethod>>()
|
|
const buildingTypeRef = ref<InstanceType<typeof BuildingType>>()
|
|
function openVisitMethod() {
|
|
// deliveryType: 1-亲自送达(0) 2-放门口(1),打开时回显当前选中
|
|
visitMethodRef.value?.onOpen(+addressStore.addressInfo.deliveryType === 2 ? 1 : 0)
|
|
}
|
|
|
|
const visitMethod = ref(t('components.visit.putItAtTheDoor')) // 默认选择放在门口
|
|
function visitMethodConfirm(data: any) {
|
|
console.log('visitMethodConfirm', data)
|
|
visitMethod.value = data.label;
|
|
addressStore.addressInfo.deliveryType = data.value + 1; // 更新地址信息中的送达方式
|
|
}
|
|
|
|
function openBuildingType() {
|
|
buildingTypeRef.value?.onOpen()
|
|
}
|
|
|
|
|
|
// 选择图片 - 添加安全检查
|
|
const chooseImageRef = ref<InstanceType<typeof ChooseImage>>()
|
|
const images = ref<string>('')
|
|
function chooseImage() {
|
|
if (chooseImageRef.value?.init) {
|
|
chooseImageRef.value.init();
|
|
}
|
|
}
|
|
|
|
// 图片选择回调 - 修复类型问题
|
|
function onImageChange(files: string[]) {
|
|
if (files.length > 0) {
|
|
// 确保 images 数组不为空
|
|
images.value = files[0]; // 只取第一个图片
|
|
} else {
|
|
images.value = ''; // 如果没有选择图片,清空
|
|
}
|
|
}
|
|
|
|
function removeImage() {
|
|
images.value = ''
|
|
}
|
|
|
|
function saveAddress() {
|
|
console.log('保存地址信息', addressStore.addressInfo);
|
|
if(addressStore.addressInfo.id) {
|
|
appUserAddressEditPost({
|
|
body: {
|
|
...addressStore.addressInfo,
|
|
deliveryImage: images.value
|
|
}
|
|
}).then(res=> {
|
|
uni.navigateBack()
|
|
addressStore.clearAddressInfo()
|
|
})
|
|
} else {
|
|
appUserAddressAddPost({
|
|
body: {
|
|
...addressStore.addressInfo,
|
|
deliveryImage: images.value
|
|
}
|
|
}).then(res=> {
|
|
uni.navigateBack()
|
|
addressStore.clearAddressInfo()
|
|
})
|
|
}
|
|
}
|
|
|
|
onLoad(()=> {
|
|
isSwitch.value = false
|
|
if(addressStore.addressInfo.deliveryImage) {
|
|
images.value = addressStore.addressInfo.deliveryImage
|
|
}
|
|
// 回显送达偏好
|
|
if(+addressStore.addressInfo.deliveryType === 1) {
|
|
visitMethod.value = t('components.visit.leaveItToMePersonally')
|
|
}
|
|
if(+addressStore.addressInfo.deliveryType === 2) {
|
|
visitMethod.value = t('components.visit.putItAtTheDoor')
|
|
}
|
|
|
|
getStateListApi().then(res=> {
|
|
stateList.value = res.data
|
|
if(addressStore.addressInfo.state) {
|
|
addressStore.addressInfo.stateName = res.data.find(item => item.id === addressStore.addressInfo.state)?.name || ''
|
|
}
|
|
})
|
|
})
|
|
|
|
onReady(() => {
|
|
if (addressStore.pendingIntroBuildingType && !addressStore.addressInfo.id) {
|
|
buildingTypeRef.value?.openIntroSheet?.()
|
|
}
|
|
})
|
|
|
|
onUnload(()=> {
|
|
if(!isSwitch.value) {
|
|
addressStore.clearAddressInfo()
|
|
}
|
|
})
|
|
|
|
const isSwitch = ref(false)
|
|
function submitType(value: string) {
|
|
addressStore.addressInfo.type = value
|
|
isSwitch.value = true
|
|
switch (value) {
|
|
case UserAddressType.HOUSE:
|
|
uni.redirectTo({
|
|
url: '/pages/address/save-address/house',
|
|
})
|
|
break;
|
|
case UserAddressType.APARTMENT:
|
|
uni.redirectTo({
|
|
url: '/pages/address/save-address/apartment',
|
|
})
|
|
break;
|
|
case UserAddressType.OFFICE:
|
|
uni.redirectTo({
|
|
url: '/pages/address/save-address/office',
|
|
})
|
|
break;
|
|
case UserAddressType.HOTEL:
|
|
uni.redirectTo({
|
|
url: '/pages/address/save-address/hotel',
|
|
})
|
|
break;
|
|
case UserAddressType.OTHER:
|
|
uni.redirectTo({
|
|
url: '/pages/address/save-address/other',
|
|
})
|
|
break;
|
|
}
|
|
}
|
|
|
|
const chooseStateRef = ref()
|
|
const stateList = ref([])
|
|
function openState() {
|
|
chooseStateRef.value?.init(stateList.value, addressStore.addressInfo.state)
|
|
}
|
|
function chooseStateConfirm(data: any) {
|
|
addressStore.addressInfo.state = data.id
|
|
addressStore.addressInfo.stateName = data.name
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<view>
|
|
<navbar :title="t('pages.address.titleDetail')" />
|
|
<!-- 地址搜索结果名字 -->
|
|
<view class="px-30rpx pt-38rpx border-bottom pb-52rpx">
|
|
<view class="text-32rpx lh-32rpx text-#333 mb-62rpx">
|
|
{{ addressStore.addressInfo.displayName }}
|
|
{{ addressStore.addressInfo.formattedAddress }}
|
|
</view>
|
|
|
|
|
|
<!-- State -->
|
|
<view class="mb-44rpx">
|
|
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('common.state') }}</view>
|
|
<view @click="openState" class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex-center-sb">
|
|
<text class="text-30rpx lh-30rpx text-#333">
|
|
{{ addressStore.addressInfo.stateName ? addressStore.addressInfo.stateName : t('common.placeholder.pleaseSelect') }}
|
|
</text>
|
|
<image src="@img/chef/142.png" class="w-32rpx h-32rpx shrink-0"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 房屋类型 -->
|
|
<view>
|
|
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.choose-type.navTitle') }}</view>
|
|
<view @click="openBuildingType" class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex-center-sb">
|
|
<text class="text-30rpx lh-30rpx text-#333">
|
|
{{
|
|
addressStore.addressInfo.type
|
|
? t(`pages.address.choose-type.${addressStore.addressInfo.type}`)
|
|
: t('common.placeholder.pleaseSelect')
|
|
}}
|
|
</text>
|
|
<image src="@img/chef/142.png" class="w-32rpx h-32rpx shrink-0 rotate-90"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Apartment/Unit/Floor (required) -->
|
|
<view class="mt-44rpx">
|
|
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.apartment.titleApartment') }}</view>
|
|
<view class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex items-center">
|
|
<wd-input
|
|
v-model.trim="addressStore.addressInfo.apartmentUnitFloor"
|
|
:cursorSpacing="20"
|
|
:focus-when-clear="false"
|
|
:maxlength="20"
|
|
:placeholder="t('pages.address.apartment.titleApartmentTips')"
|
|
clearable
|
|
custom-class="flex-1 !text-30rpx lh-30rpx !text-#333 !bg-transparent"
|
|
no-border
|
|
placeholderStyle="font-size: 30rpx;color: #999;"
|
|
>
|
|
</wd-input>
|
|
</view>
|
|
</view>
|
|
<!-- Building Name -->
|
|
<view class="mt-44rpx">
|
|
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.apartment.titleBuilding') }}</view>
|
|
<view class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex items-center">
|
|
<wd-input
|
|
v-model.trim="addressStore.addressInfo.buildingName"
|
|
:cursorSpacing="20"
|
|
:focus-when-clear="false"
|
|
:maxlength="20"
|
|
:placeholder="t('pages.address.apartment.titleBuildingTips')"
|
|
clearable
|
|
custom-class="flex-1 !text-30rpx lh-30rpx !text-#333 !bg-transparent"
|
|
no-border
|
|
placeholderStyle="font-size: 30rpx;color: #999;"
|
|
>
|
|
</wd-input>
|
|
</view>
|
|
</view>
|
|
<!-- Entry Code -->
|
|
<view class="mt-44rpx">
|
|
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.apartment.titleEntry') }}</view>
|
|
<view class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex items-center">
|
|
<wd-input
|
|
v-model.trim="addressStore.addressInfo.entranceCodeApartment"
|
|
:cursorSpacing="20"
|
|
:focus-when-clear="false"
|
|
:maxlength="20"
|
|
:placeholder="t('pages.address.apartment.titleEntryTips')"
|
|
clearable
|
|
custom-class="flex-1 !text-30rpx lh-30rpx !text-#333 !bg-transparent"
|
|
no-border
|
|
placeholderStyle="font-size: 30rpx;color: #999;"
|
|
>
|
|
</wd-input>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="px-30rpx py-52rpx">
|
|
<!-- Delivery Point Information -->
|
|
<view class="mb-44rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.deliveryPointInfo') }}</view>
|
|
|
|
<view @click="openVisitMethod" class="flex-center-sb">
|
|
<view>
|
|
<view class="text-32rpx lh-32rpx text-#333 mb-12rpx">{{ visitMethod }}</view>
|
|
<view class="text-32rpx lh-32rpx text-#999">{{ t('pages.address.moreOptions') }}</view>
|
|
</view>
|
|
<image src="@img/chef/142.png" class="w-32rpx h-32rpx shrink-0"></image>
|
|
</view>
|
|
|
|
<view class="mt-52rpx">
|
|
<view class="text-36rpx lh-36rpx text-#333 font-500 mb-24rpx">{{ t('pages.address.deliveryInstructions') }}</view>
|
|
<view
|
|
class="min-h-240rpx box-border bg-#F6F6F6 rounded-20rpx overflow-hidden p-20rpx"
|
|
>
|
|
<wd-textarea
|
|
:maxlength="250"
|
|
custom-class="!bg-#F6F6F6"
|
|
custom-textarea-container-class="!bg-#F6F6F6"
|
|
no-border
|
|
auto-height
|
|
v-model="addressStore.addressInfo.deliveryRemark"
|
|
:placeholder="t('pages.address.pleaseTip')"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="mt-24rpx relative w-240rpx h-240rpx" @click="chooseImage">
|
|
<image
|
|
v-if="images"
|
|
class="absolute top--10rpx right--10rpx z-1 w-36rpx h-36rpx"
|
|
src="@img/chef/113.png"
|
|
@click.stop="removeImage"
|
|
></image>
|
|
<view v-if="!images" class="flex flex-col items-center justify-center w-240rpx h-240rpx bg-#f6f6f6 rounded-20rpx">
|
|
<wd-icon name="add" size="32px" color="#3d3d3d"></wd-icon>
|
|
<text class="text-30rpx lh-30rpx text-#333 mt-22rpx">{{ t('common.addPicture') }}</text>
|
|
</view>
|
|
<image
|
|
v-else
|
|
:src="images"
|
|
class="w-240rpx h-240rpx rounded-20rpx"
|
|
mode="aspectFill"
|
|
></image>
|
|
</view>
|
|
</view>
|
|
|
|
|
|
<fixed-bottom-large-btn
|
|
class="z-100"
|
|
fixed
|
|
:text="t('common.saveAndContinue')"
|
|
@click="saveAddress"
|
|
/>
|
|
|
|
<visit-method @confirm="visitMethodConfirm" ref="visitMethodRef" />
|
|
<!-- 房屋类型 -->
|
|
<building-type ref="buildingTypeRef" @submit="submitType" />
|
|
|
|
<ChooseImage ref="chooseImageRef" @change="onImageChange"/>
|
|
|
|
<!-- 所在州 -->
|
|
<choose-state ref="chooseStateRef" @confirm="chooseStateConfirm" />
|
|
</view>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
:deep(.wd-textarea) {
|
|
padding: 0 !important;
|
|
}
|
|
</style>
|
|
<style>
|
|
page {
|
|
background-color: #fff;
|
|
}
|
|
</style> |