|
@@ -30,30 +30,110 @@
|
|
|
>
|
|
>
|
|
|
</div>
|
|
</div>
|
|
|
<el-form-item prop="refundAddressId" label-width="0">
|
|
<el-form-item prop="refundAddressId" label-width="0">
|
|
|
- <el-select
|
|
|
|
|
- v-model="form.refundAddressId"
|
|
|
|
|
- placeholder="请选择退货地址"
|
|
|
|
|
- class="w-full"
|
|
|
|
|
- :loading="addressLoading"
|
|
|
|
|
|
|
+ <el-popover
|
|
|
|
|
+ v-model:visible="addressPickerVisible"
|
|
|
|
|
+ trigger="click"
|
|
|
|
|
+ placement="bottom-start"
|
|
|
|
|
+ :width="520"
|
|
|
|
|
+ popper-class="refund-address-popper"
|
|
|
>
|
|
>
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in addressList"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- :label="`收货人:${item.consignee} ${item.phone} | 收货地址:${item.province}${item.city}${item.district} ${item.address}`"
|
|
|
|
|
- :value="item.id"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="py-2 leading-tight">
|
|
|
|
|
- <div class="font-bold text-gray-800"
|
|
|
|
|
- >收货人:{{ item.consignee }}
|
|
|
|
|
- {{ item.phone }}</div
|
|
|
|
|
- >
|
|
|
|
|
- <div class="text-xs text-gray-500 mt-1"
|
|
|
|
|
- >收货地址:{{ item.province }}{{ item.city
|
|
|
|
|
- }}{{ item.district }} {{ item.address }}</div
|
|
|
|
|
|
|
+ <template #reference>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="w-full rounded-md border px-3 py-2 flex items-center justify-between cursor-pointer transition"
|
|
|
|
|
+ :class="
|
|
|
|
|
+ addressPickerVisible
|
|
|
|
|
+ ? 'border-emerald-400 ring-2 ring-emerald-100'
|
|
|
|
|
+ : 'border-gray-200'
|
|
|
|
|
+ "
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="flex-1 min-w-0">
|
|
|
|
|
+ <template v-if="selectedAddress">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="text-sm text-gray-900 truncate"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ selectedAddress.name }}
|
|
|
|
|
+ {{ selectedAddress.mobile }}
|
|
|
|
|
+ <el-tag
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ Number(
|
|
|
|
|
+ selectedAddress.defaultReturnFlag
|
|
|
|
|
+ ) === 1
|
|
|
|
|
+ "
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ class="ml-2"
|
|
|
|
|
+ >默认</el-tag
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="text-xs text-gray-500 truncate mt-0.5"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ selectedAddress.address }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <div class="text-sm text-gray-400">
|
|
|
|
|
+ 请选择退货地址
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-icon class="ml-2 text-gray-400"
|
|
|
|
|
+ ><ArrowDown
|
|
|
|
|
+ /></el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="max-h-72 overflow-auto p-2">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="addressLoading"
|
|
|
|
|
+ class="py-6 flex items-center justify-center text-gray-500 text-sm"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-icon class="is-loading mr-2"
|
|
|
|
|
+ ><Loading
|
|
|
|
|
+ /></el-icon>
|
|
|
|
|
+ 加载中
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-else-if="!addressList.length"
|
|
|
|
|
+ class="py-6 text-center text-gray-400 text-sm"
|
|
|
|
|
+ >
|
|
|
|
|
+ 暂无可用退货地址
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-else class="space-y-2">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="item in addressList"
|
|
|
|
|
+ :key="item.id"
|
|
|
|
|
+ class="rounded-md border px-3 py-2 cursor-pointer transition"
|
|
|
|
|
+ :class="
|
|
|
|
|
+ String(form.refundAddressId) ===
|
|
|
|
|
+ String(item.id)
|
|
|
|
|
+ ? 'border-emerald-400 bg-emerald-50'
|
|
|
|
|
+ : 'border-gray-100 hover:border-gray-200 hover:bg-gray-50'
|
|
|
|
|
+ "
|
|
|
|
|
+ @click="handleSelectAddress(item)"
|
|
|
>
|
|
>
|
|
|
|
|
+ <div class="flex items-center">
|
|
|
|
|
+ <div class="font-medium text-gray-900">
|
|
|
|
|
+ {{ item.name }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="ml-2 text-sm text-gray-500">
|
|
|
|
|
+ {{ item.mobile }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-tag
|
|
|
|
|
+ v-if="Number(item.defaultReturnFlag) === 1"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ class="ml-2"
|
|
|
|
|
+ >默认</el-tag
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text-xs text-gray-500 mt-1">
|
|
|
|
|
+ {{ item.address }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-option>
|
|
|
|
|
- </el-select>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-popover>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="退货说明" prop="description">
|
|
<el-form-item label="退货说明" prop="description">
|
|
@@ -88,9 +168,9 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
- import { ref, reactive } from 'vue';
|
|
|
|
|
|
|
+ import { ref, reactive, computed } from 'vue';
|
|
|
import { EleMessage } from 'ele-admin-plus/es';
|
|
import { EleMessage } from 'ele-admin-plus/es';
|
|
|
- import { WarningFilled } from '@element-plus/icons-vue';
|
|
|
|
|
|
|
+ import { ArrowDown, Loading, WarningFilled } from '@element-plus/icons-vue';
|
|
|
import { useRouter } from 'vue-router';
|
|
import { useRouter } from 'vue-router';
|
|
|
import request from '@/utils/request';
|
|
import request from '@/utils/request';
|
|
|
|
|
|
|
@@ -98,9 +178,17 @@
|
|
|
const visible = ref(false);
|
|
const visible = ref(false);
|
|
|
const loading = ref(false);
|
|
const loading = ref(false);
|
|
|
const addressLoading = ref(false);
|
|
const addressLoading = ref(false);
|
|
|
|
|
+ const addressPickerVisible = ref(false);
|
|
|
const formRef = ref(null);
|
|
const formRef = ref(null);
|
|
|
const currentRefundOrderId = ref('');
|
|
const currentRefundOrderId = ref('');
|
|
|
const addressList = ref([]);
|
|
const addressList = ref([]);
|
|
|
|
|
+ const selectedAddress = computed(() => {
|
|
|
|
|
+ const id = String(form.refundAddressId || '');
|
|
|
|
|
+ if (!id) return null;
|
|
|
|
|
+ return (
|
|
|
|
|
+ addressList.value.find((a) => String(a.id) === id) || null
|
|
|
|
|
+ );
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
const form = reactive({
|
|
const form = reactive({
|
|
|
refundAddressId: '',
|
|
refundAddressId: '',
|
|
@@ -117,17 +205,16 @@
|
|
|
|
|
|
|
|
const fetchAddressList = () => {
|
|
const fetchAddressList = () => {
|
|
|
addressLoading.value = true;
|
|
addressLoading.value = true;
|
|
|
- // Assuming there's an endpoint to get the shop's return addresses.
|
|
|
|
|
- // Replace with the correct endpoint if different.
|
|
|
|
|
|
|
+ // 使用图2的接口获取退款地址列表
|
|
|
request
|
|
request
|
|
|
- .get('/shop/shopAddress/list')
|
|
|
|
|
|
|
+ .get('/shop/shopAddress/getRefundAddressList')
|
|
|
.then((res) => {
|
|
.then((res) => {
|
|
|
if (res.data.code === 200) {
|
|
if (res.data.code === 200) {
|
|
|
addressList.value = res.data.data || [];
|
|
addressList.value = res.data.data || [];
|
|
|
- // Auto-select the default address if available
|
|
|
|
|
|
|
+ // 自动选择默认退货地址(依据接口文档中的 defaultReturnFlag === 1)
|
|
|
if (addressList.value.length > 0 && !form.refundAddressId) {
|
|
if (addressList.value.length > 0 && !form.refundAddressId) {
|
|
|
const defaultAddr = addressList.value.find(
|
|
const defaultAddr = addressList.value.find(
|
|
|
- (a) => a.isDefault === 1
|
|
|
|
|
|
|
+ (a) => Number(a.defaultReturnFlag) === 1
|
|
|
);
|
|
);
|
|
|
form.refundAddressId = defaultAddr
|
|
form.refundAddressId = defaultAddr
|
|
|
? defaultAddr.id
|
|
? defaultAddr.id
|
|
@@ -146,10 +233,17 @@
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ const handleSelectAddress = (item) => {
|
|
|
|
|
+ form.refundAddressId = item.id;
|
|
|
|
|
+ addressPickerVisible.value = false;
|
|
|
|
|
+ formRef.value?.validateField?.('refundAddressId');
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
const open = (refundOrderId) => {
|
|
const open = (refundOrderId) => {
|
|
|
currentRefundOrderId.value = refundOrderId;
|
|
currentRefundOrderId.value = refundOrderId;
|
|
|
form.refundAddressId = '';
|
|
form.refundAddressId = '';
|
|
|
form.description = '';
|
|
form.description = '';
|
|
|
|
|
+ addressPickerVisible.value = false;
|
|
|
if (formRef.value) {
|
|
if (formRef.value) {
|
|
|
formRef.value.clearValidate();
|
|
formRef.value.clearValidate();
|
|
|
}
|
|
}
|
|
@@ -159,8 +253,7 @@
|
|
|
|
|
|
|
|
const handleManageAddress = () => {
|
|
const handleManageAddress = () => {
|
|
|
// Navigate to address management page if exists
|
|
// Navigate to address management page if exists
|
|
|
- EleMessage.info('前往地址管理页面');
|
|
|
|
|
- // router.push('/setting/address');
|
|
|
|
|
|
|
+ router.push('/mallLogistics/address');
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
const handleSubmit = async () => {
|
|
@@ -207,9 +300,8 @@
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
- /* 隐藏原生select的边框使其更贴合设计图,或者使用自定义样式 */
|
|
|
|
|
- :deep(.el-select .el-input__wrapper) {
|
|
|
|
|
- padding: 8px 15px;
|
|
|
|
|
|
|
+ :deep(.refund-address-popper) {
|
|
|
|
|
+ padding: 0;
|
|
|
}
|
|
}
|
|
|
:deep(.el-textarea__inner) {
|
|
:deep(.el-textarea__inner) {
|
|
|
background-color: #f9fafb;
|
|
background-color: #f9fafb;
|