对接快递100

This commit is contained in:
2025-11-20 22:28:31 +08:00
parent ff0eeeee30
commit 364cb1b58e
3 changed files with 260 additions and 190 deletions

View File

@@ -1,6 +1,6 @@
VITE_APP_NAME=后台管理(开发环境)
#VITE_API_URL=http://127.0.0.1:9200/api
VITE_API_URL=http://127.0.0.1:9200/api
#VITE_SERVER_API_URL=http://127.0.0.1:8000/api
VITE_API_URL=https://cms-api.websoft.top/api
#VITE_API_URL=https://cms-api.websoft.top/api

View File

@@ -20,7 +20,7 @@
<a-form-item label="配送方式" name="deliveryType">
<a-radio-group v-model:value="form.deliveryType">
<a-radio :value="0">
<span style="color: #1890ff;">快递配送</span>
<span style="color: #1890ff">快递配送</span>
</a-radio>
<a-radio :value="1">无需发货</a-radio>
<a-radio :value="2">商家送货</a-radio>
@@ -31,7 +31,7 @@
<a-form-item label="发货类型" name="deliveryMethod">
<a-radio-group v-model:value="form.deliveryMethod">
<a-radio value="manual">
<span style="color: #1890ff;">手动填写</span>
<span style="color: #1890ff">手动填写</span>
</a-radio>
<a-radio value="print">电子面单打印</a-radio>
</a-radio-group>
@@ -69,27 +69,50 @@
</a-row>
</a-form-item>
<!-- 快递单号 -->
<a-form-item
label="快递单号"
name="trackingNumber"
v-if="form.deliveryType === 0"
>
<a-input
v-model:value="form.trackingNumber"
placeholder="请输入快递单号"
:maxlength="50"
/>
</a-form-item>
<template v-if="form.deliveryType === 0">
<a-form-item label="发货人" name="sendName">
<a-input
v-model:value="form.sendName"
placeholder="请输入发货人"
:maxlength="50"
/>
</a-form-item>
<a-form-item label="发货人联系方式" name="sendPhone">
<a-input
v-model:value="form.sendPhone"
placeholder="请输入发货人联系方式"
:maxlength="50"
/>
</a-form-item>
<a-form-item label="发货地址" name="sendAddress">
<a-input
v-model:value="form.sendAddress"
placeholder="请输入发货地址"
/>
</a-form-item>
</template>
<!-- 分单发货 -->
<a-form-item label="分单发货" v-if="form.deliveryType === 0">
<a-switch
v-model:checked="form.partialDelivery"
checked-children="支持"
un-checked-children="不支持"
/>
</a-form-item>
<!-- 快递单号 -->
<!-- <a-form-item-->
<!-- label="快递单号"-->
<!-- name="trackingNumber"-->
<!-- v-if="form.deliveryType === 0"-->
<!-- >-->
<!-- <a-input-->
<!-- v-model:value="form.trackingNumber"-->
<!-- placeholder="请输入快递单号"-->
<!-- :maxlength="50"-->
<!-- />-->
<!-- </a-form-item>-->
<!-- &lt;!&ndash; 分单发货 &ndash;&gt;-->
<!-- <a-form-item label="分单发货" v-if="form.deliveryType === 0">-->
<!-- <a-switch-->
<!-- v-model:checked="form.partialDelivery"-->
<!-- checked-children="支持"-->
<!-- un-checked-children="不支持"-->
<!-- />-->
<!-- </a-form-item>-->
<!-- 发货备注 -->
<a-form-item label="发货备注" name="deliveryNote">
@@ -123,189 +146,197 @@
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { ShopOrder } from '@/api/shop/shopOrder/model';
import { updateShopOrder } from '@/api/shop/shopOrder';
import { listShopExpress } from '@/api/shop/shopExpress';
import { ShopExpress } from '@/api/shop/shopExpress/model';
import { toDateString } from 'ele-admin-pro';
import dayjs, { Dayjs } from 'dayjs';
import ExpressSettingModal from './expressSettingModal.vue';
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { ShopOrder } from '@/api/shop/shopOrder/model';
import { updateShopOrder } from '@/api/shop/shopOrder';
import { listShopExpress } from '@/api/shop/shopExpress';
import { ShopExpress } from '@/api/shop/shopExpress/model';
import { toDateString } from 'ele-admin-pro';
import dayjs, { Dayjs } from 'dayjs';
import ExpressSettingModal from './expressSettingModal.vue';
const useForm = Form.useForm;
const useForm = Form.useForm;
const props = defineProps<{
visible: boolean;
data?: ShopOrder | null;
}>();
const props = defineProps<{
visible: boolean;
data?: ShopOrder | null;
}>();
const emit = defineEmits<{
(e: 'update:visible', visible: boolean): void;
(e: 'done'): void;
}>();
const emit = defineEmits<{
(e: 'update:visible', visible: boolean): void;
(e: 'done'): void;
}>();
// 表单数据
const form = reactive({
deliveryType: 0, // 0快递配送 1无需发货 2商家送货
deliveryMethod: 'manual', // manual手动填写 print电子面单打印
expressId: undefined as number | undefined,
expressName: '',
trackingNumber: '',
partialDelivery: false,
deliveryNote: '',
deliveryTime: dayjs() as Dayjs
});
// 表单数据
const form = reactive({
deliveryType: 0, // 0快递配送 1无需发货 2商家送货
deliveryMethod: 'manual', // manual手动填写 print电子面单打印
expressId: undefined as number | undefined,
expressName: '',
trackingNumber: '',
partialDelivery: false,
deliveryNote: '',
sendName: '',
sendPhone: '',
sendAddress: '',
deliveryTime: dayjs() as Dayjs
});
// 表单验证规则
const rules = {
deliveryType: [
{ required: true, message: '请选择配送方式' }
],
deliveryMethod: [
{ required: true, message: '请选择发货类型' }
],
expressId: [
{
required: true,
message: '请选择快递公司',
validator: (_: any, value: any) => {
if (form.deliveryType === 0 && !value) {
return Promise.reject('请选择快递公司');
// 表单验证规则
const rules = {
deliveryType: [{ required: true, message: '请选择配送方式' }],
deliveryMethod: [{ required: true, message: '请选择发货类型' }],
expressId: [
{
required: true,
message: '请选择快递公司',
validator: (_: any, value: any) => {
if (form.deliveryType === 0 && !value) {
return Promise.reject('请选择快递公司');
}
return Promise.resolve();
}
return Promise.resolve();
}
],
// trackingNumber: [
// {
// required: true,
// message: '请输入快递单号',
// validator: (_: any, value: any) => {
// if (form.deliveryType === 0 && !value) {
// return Promise.reject('请输入快递单号');
// }
// return Promise.resolve();
// }
// }
// ],
deliveryTime: [{ required: true, message: '请选择发货时间' }],
sendName: [{ required: true, message: '请输入发货人' }],
sendPhone: [{ required: true, message: '请输入发货人联系方式' }],
sendAddress: [{ required: true, message: '请输入发货地址' }],
};
const formRef = ref();
const { resetFields, validate } = useForm(form, rules);
// 状态
const loading = ref(false);
const expressList = ref<ShopExpress[]>([]);
const expressModalVisible = ref(false);
// 加载快递公司列表
const loadExpressList = async () => {
try {
const data = await listShopExpress({});
expressList.value = data || [];
} catch (error) {
console.error('加载快递公司失败:', error);
}
],
trackingNumber: [
{
required: true,
message: '请输入快递单号',
validator: (_: any, value: any) => {
if (form.deliveryType === 0 && !value) {
return Promise.reject('请输入快递单号');
}
return Promise.resolve();
}
};
// 快递公司筛选
const filterExpressOption = (input: string, option: any) => {
return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
// 快递公司选择变化
const onExpressChange = (value: number) => {
const express = expressList.value.find((item) => item.expressId === value);
if (express) {
form.expressName = express.expressName || '';
}
],
deliveryTime: [
{ required: true, message: '请选择发货时间' }
]
};
};
const formRef = ref();
const { resetFields, validate } = useForm(form, rules);
// 打开快递公司设置
const openExpressModal = () => {
expressModalVisible.value = true;
};
// 状态
const loading = ref(false);
const expressList = ref<ShopExpress[]>([]);
const expressModalVisible = ref(false);
// 更新弹窗显示状态
const updateVisible = (visible: boolean) => {
emit('update:visible', visible);
};
// 加载快递公司列表
const loadExpressList = async () => {
try {
const data = await listShopExpress({});
expressList.value = data || [];
} catch (error) {
console.error('加载快递公司失败:', error);
}
};
// 快递公司筛选
const filterExpressOption = (input: string, option: any) => {
return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
// 快递公司选择变化
const onExpressChange = (value: number) => {
const express = expressList.value.find(item => item.expressId === value);
if (express) {
form.expressName = express.expressName || '';
}
};
// 打开快递公司设置
const openExpressModal = () => {
expressModalVisible.value = true;
};
// 更新弹窗显示状态
const updateVisible = (visible: boolean) => {
emit('update:visible', visible);
};
// 取消
const handleCancel = () => {
updateVisible(false);
};
// 提交发货
const handleSubmit = async () => {
try {
await validate();
loading.value = true;
const deliveryTime = toDateString(form.deliveryTime.toDate(), 'yyyy-MM-dd HH:mm:ss');
const updateData = {
...props.data,
deliveryStatus: 20, // 已发货
deliveryType: form.deliveryType,
deliveryTime: deliveryTime,
deliveryNote: form.deliveryNote
};
// 如果是快递配送,添加快递信息
if (form.deliveryType === 0) {
updateData.expressId = form.expressId;
updateData.expressName = form.expressName;
updateData.trackingNumber = form.trackingNumber;
}
// 分单发货
if(form.partialDelivery){
updateData.deliveryStatus = 30;
}
await updateShopOrder(updateData);
message.success('发货成功');
emit('done');
// 取消
const handleCancel = () => {
updateVisible(false);
} catch (error: any) {
message.error(error.message || '发货失败');
} finally {
loading.value = false;
}
};
};
// 监听弹窗显示状态
watch(
() => props.visible,
(visible) => {
if (visible) {
// 重置表单
form.deliveryType = 0;
form.deliveryMethod = 'manual';
form.expressId = undefined;
form.expressName = '';
form.trackingNumber = '';
form.partialDelivery = false;
form.deliveryNote = '';
form.deliveryTime = dayjs();
// 提交发货
const handleSubmit = async () => {
try {
await validate();
loading.value = true;
// 加载快递公司列表
loadExpressList();
} else {
resetFields();
const deliveryTime = toDateString(
form.deliveryTime.toDate(),
'yyyy-MM-dd HH:mm:ss'
);
const updateData = {
...props.data,
deliveryStatus: 20, // 已发货
deliveryType: form.deliveryType,
deliveryTime: deliveryTime,
deliveryNote: form.deliveryNote,
};
// 如果是快递配送,添加快递信息
if (form.deliveryType === 0) {
updateData.expressId = form.expressId;
updateData.sendName = form.sendName;
updateData.sendPhone = form.sendPhone;
updateData.sendAddress = form.sendAddress;
// updateData.expressName = form.expressName;
// updateData.trackingNumber = form.trackingNumber;
}
// 分单发货
if (form.partialDelivery) {
updateData.deliveryStatus = 30;
}
await updateShopOrder(updateData);
message.success('发货成功');
emit('done');
updateVisible(false);
} catch (error: any) {
console.log(error)
message.error(error.message || '发货失败');
} finally {
loading.value = false;
}
}
);
};
// 监听弹窗显示状态
watch(
() => props.visible,
(visible) => {
if (visible) {
// 重置表单
form.deliveryType = 0;
form.deliveryMethod = 'manual';
form.expressId = undefined;
form.expressName = '';
form.trackingNumber = '';
form.partialDelivery = false;
form.deliveryNote = '';
form.deliveryTime = dayjs();
// 加载快递公司列表
loadExpressList();
} else {
resetFields();
}
}
);
</script>
<style scoped>
.ant-radio-wrapper {
margin-right: 16px;
}
.ant-radio-wrapper {
margin-right: 16px;
}
</style>

View File

@@ -386,6 +386,43 @@
</a-descriptions>
</a-spin>
</a-card>
<a-card v-if="form.shopOrderDelivery" title="发货信息" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
<a-descriptions :column="2">
<a-descriptions-item
label="发货人"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.sendName || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="联系电话"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.sendPhone || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="发货地址"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.shopOrderDelivery.sendAddress || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="快递公司"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.expressName || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="物流单号"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.expressNo || '未填写' }}
</a-descriptions-item>
</a-descriptions>
</a-spin>
</a-card>
<a-card title="商品信息" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
@@ -640,6 +677,8 @@ const form = reactive<ShopOrder>({
selfTakeCode: undefined,
// 是否已收到赠品
hasTakeGift: undefined,
// 发货信息
shopOrderDelivery: undefined
});
// 请求状态