Files
cheflinkuser/src/pages/address/save-address/house.vue
T
2026-02-26 09:32:03 +08:00

277 lines
8.8 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() {
visitMethodRef.value?.onOpen()
}
const visitMethod = ref(t('components.visit.leaveItToMePersonally')) // 默认选择亲自送达
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 || ''
}
})
})
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">
{{ `${t(`pages.address.choose-type.${addressStore.addressInfo.type}`)}` }}
</text>
<image src="@img/chef/142.png" class="w-32rpx h-32rpx shrink-0 rotate-90"></image>
</view>
</view>
<!-- Other Details -->
<view class="mt-44rpx">
<view class="mb-20rpx text-36rpx lh-36rpx text-#333 font-500">{{ t('pages.address.otherDetails') }}</view>
<view class="bg-#F6F6F6 rounded-16rpx px-24rpx h-98rpx flex items-center">
<wd-input
v-model.trim="addressStore.addressInfo.houseExtra"
:cursorSpacing="20"
:focus-when-clear="false"
:maxlength="20"
:placeholder="t('pages.address.house.tips')"
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>