2b41b010 by lttnew

地址

1 parent 67e1a42f
......@@ -63,11 +63,16 @@
<view class="form-item">
<text class="form-label">省市区</text>
<picker class="form-picker" mode="region" :value="region" @change="onRegionChange">
<view class="picker-value">
{{ region[0] || '请选择' }} {{ region[1] || '' }} {{ region[2] || '' }}
<view class="form-picker data-picker-wrap">
<uni-data-picker
v-model="regionValue"
:localdata="regionsList"
:clear-icon="false"
popup-title="请选择省市区"
placeholder="请选择"
@change="onRegionChange"
/>
</view>
</picker>
</view>
<view class="form-item">
......@@ -94,6 +99,8 @@ const list = ref([]);
const addressPopup = ref(null);
const isEdit = ref(false);
const editId = ref(null);
const regionsList = ref([]);
let regionsListPromise = null;
const form = ref({
name: '',
......@@ -105,9 +112,11 @@ const form = ref({
});
const region = ref([]);
const regionValue = ref([]);
onMounted(() => {
initData();
getRegionsList();
});
const initData = async () => {
......@@ -171,7 +180,8 @@ const handleSetDefault = async (item) => {
});
};
const handleEdit = (item) => {
const handleEdit = async (item) => {
if (!await ensureRegionsReady()) return;
isEdit.value = true;
editId.value = item.id;
form.value = {
......@@ -183,10 +193,12 @@ const handleEdit = (item) => {
a: item.a
};
region.value = [item.province, item.city, item.area];
regionValue.value = getRegionValueByNames(region.value);
addressPopup.value.open();
};
const goAddAddress = () => {
const goAddAddress = async () => {
if (!await ensureRegionsReady()) return;
isEdit.value = false;
editId.value = null;
form.value = {
......@@ -198,11 +210,57 @@ const goAddAddress = () => {
a: ''
};
region.value = [];
regionValue.value = [];
addressPopup.value.open();
};
const onRegionChange = (e) => {
region.value = e.detail.value;
const selected = e?.detail?.value || [];
region.value = selected.map(item => getNodeText(item)).filter(Boolean);
regionValue.value = selected.map(item => getNodeValue(item)).filter(Boolean);
};
const ensureRegionsReady = async () => {
await getRegionsList();
if (regionsList.value.length) return true;
uni.showToast({ title: '地区数据加载失败,请稍后重试', icon: 'none' });
return false;
};
const getRegionsList = async () => {
if (regionsList.value.length) return;
if (regionsListPromise) return regionsListPromise;
regionsListPromise = api.regionsList(null, { showLoading: false })
.then(res => {
regionsList.value = res.data || [];
if (region.value.length) {
regionValue.value = getRegionValueByNames(region.value);
}
})
.catch(e => {
console.error('获取地区数据失败', e);
regionsList.value = [];
})
.finally(() => {
regionsListPromise = null;
});
return regionsListPromise;
};
const getNodeText = (node) => node?.text ?? node?.label ?? node?.name ?? node;
const getNodeValue = (node) => node?.value ?? node?.id ?? node;
const getRegionValueByNames = (names = []) => {
if (!names.length || !regionsList.value.length) return [];
const path = [];
let list = regionsList.value;
for (const name of names) {
const node = list.find(item => getNodeText(item) === name);
if (!node) return [];
path.push(getNodeValue(node));
list = node.children || [];
}
return path;
};
const closePopup = () => {
......@@ -430,6 +488,64 @@ const submitAddress = async () => {
font-size: 28rpx;
color: #333;
}
&.data-picker-wrap {
padding: 0;
:deep(.uni-data-tree) {
width: 100%;
}
:deep(.uni-data-tree-input) {
width: 100%;
}
:deep(.input-value) {
position: relative;
display: flex;
width: 100%;
height: 80rpx;
border: none;
background: transparent;
padding: 0 20rpx;
box-sizing: border-box;
}
:deep(.selected-area) {
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
color: #333;
padding-right: 0;
box-sizing: border-box;
}
:deep(.selected-list) {
justify-content: flex-start;
}
:deep(.placeholder) {
color: #999;
}
:deep(.arrow-area) {
display: none;
}
:deep(.input-arrow) {
display: none;
}
:deep(.uni-data-tree-dialog .selected-area) {
overflow: hidden;
}
:deep(.uni-data-tree-dialog .selected-area ::-webkit-scrollbar) {
display: none;
width: 0;
height: 0;
}
}
}
.form-textarea {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!