ch-tgr-h5/src/views/User/Address.vue
2026-05-12 15:19:26 +08:00

154 lines
7.1 KiB
Vue

<template>
<BasePage>
<van-cell-group class="b_l_w" style="margin-bottom: 132px;">
<van-swipe-cell v-for="(item, index) in data">
<van-cell>
<template #title>
<div style=" display: flex;align-items: center; justify-content: space-between; width: 100%; ">
<div style="display: flex; width: 90%">
<div style="display: flex; flex-direction: column">
<div style="display: flex; align-items: center">
<span>{{ item.name }}</span>
<span style="margin-left: 6px">
{{ item.phone }}</span>
<van-tag v-if="item.defaulted" style="margin-left: 6px" round type="primary">
{{ "默认地址" }}
</van-tag>
</div>
<span style="font-size: 12px">
{{ item.province + item.city + item.county + "-" + item.address }}</span>
</div>
</div>
<van-icon size="large" name="edit" @click="beforeEdit(item)" />
</div>
</template>
</van-cell>
<template #right>
<van-button style="height: 100%;" square text="删除" type="danger" class="delete-button"
@click="deleted(item)" />
</template>
</van-swipe-cell>
</van-cell-group>
<van-action-sheet v-model:show="showEditor" :title="mode == 'add' ? '新增地址' : '编辑地址'">
<div class="address-edit">
<van-form @submit="save">
<van-cell-group inset>
<van-field v-model="tempAddress.name" label="收货人" placeholder="请输入收货人" size="small"
:rules="[{ required: true, message: '请填写收货人' }]" clearable required />
<van-field v-model="tempAddress.phone" label="手机号" type="tel" placeholder="请输入手机号" size="small"
:rules="[{ required: true, message: '请填写手机号' }]" clearable required />
<van-field is-link type="textarea" autosize v-model="regionName" label="地区" placeholder="请选择地区"
size="small" @click="showRegion = true;" readonly
:rules="[{ required: true, message: '请选择地区' }]" required />
<van-field v-model="tempAddress.address" label="详细地址" placeholder="请输入详细地址" size="small"
type="textarea" autosize :rules="[{ required: true, message: '请填写详细地址' }]" clearable
required />
<van-cell size="small">
<template #title>
<span>是否设为默认地址</span>
</template>
<template #right-icon>
<van-switch v-model="tempAddress.defaulted" />
</template>
</van-cell>
<van-cell size="small">
<template #title>
<van-button round type="primary" size="large" native-type="save"
:loading="isSaving">保存</van-button>
</template>
</van-cell>
</van-cell-group>
</van-form>
</div>
</van-action-sheet>
<van-popup v-model:show="showRegion" round position="bottom" teleport="body">
<van-area v-model="regionCode" :area-list="areaList" @confirm="onAreaConfirm"
@cancel="showRegion = false" />
</van-popup>
<van-action-bar>
<van-action-bar-button color="#ca2904" text="新增地址" @click="beforeAdd" />
</van-action-bar>
</BasePage>
</template>
<script>
import { areaList } from '@vant/area-data';
export default {
name: 'Address',
mounted() {
this.loadData();
},
data() {
return {
loading: true,
data: [],
showEditor: false,
showRegion: false,
regionCode: '',
regionName: '',
tempAddress: {},
mode: "add",
isSaving: false,
areaList,
}
},
methods: {
loadData() {
this.$get('/v1/client/DUseraddressClient').then(res => {
this.data = res.data || [];
});
},
beforeAdd() {
this.mode = "add";
this.regionCode = '';
this.regionName = '';
this.tempAddress = { defaulted: this.data.length == 0 };
this.showEditor = true;
},
beforeEdit(e) {
this.mode = "edit";
this.regionName = e.province + e.city + e.county;
this.regionCode = e.countyCode || e.provinceCode || '';
this.tempAddress = JSON.parse(JSON.stringify(e));
this.showEditor = true;
},
save() {
this.isSaving = true;
let api = '/v1/client/DUseraddressClient';
const method = this.mode == 'edit' ? 'PUT' : 'POST';
if (this.mode == 'edit')
api = `/v1/client/DUseraddressClient/${this.tempAddress.id}`
this.$request(api, this.tempAddress, method).then(data => {
this.loadData();
this.showEditor = false;
this.$showSuccessToast('保存成功');
}).finally(() => {
this.isSaving = false;
});
},
deleted(e) {
this.$del(`/v1/client/DUseraddressClient/${e.id}`).then(data => {
this.loadData();
});
},
onAreaConfirm(e) {
this.showRegion = false;
const options = e.selectedOptions;
// 省级: options[0]直接是省份节点
// 市级: 需要从options[0].children中找到匹配的
// 区级: options[2]直接是区县节点
this.tempAddress.province = options[0]?.text || '';
this.tempAddress.provinceCode = options[0]?.value || '';
const cityOption = options[0]?.children?.find(c => c.value === options[1]?.value);
this.tempAddress.city = cityOption?.text || options[1]?.text || '';
this.tempAddress.cityCode = options[1]?.value || '';
this.tempAddress.county = options[2]?.text || '';
this.tempAddress.countyCode = options[2]?.value || '';
this.regionName = this.tempAddress.province + this.tempAddress.city + this.tempAddress.county;
this.regionCode = this.tempAddress.countyCode;
},
}
}
</script>