feat:优化了订单、药品这些交互
This commit is contained in:
@@ -16,13 +16,6 @@ export async function getDeliveryWarehouseOrderDetail(id: number | string) {
|
||||
return requestClient.get<any>(`${prefix}detail`, { params: { id } });
|
||||
}
|
||||
|
||||
/**
|
||||
* 按订单查物流轨迹(复用平台 express-detail 接口)
|
||||
*/
|
||||
export async function expressDetailByOrderId(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`express-detail/detail-by-order`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送仓库订单发货
|
||||
*/
|
||||
|
||||
@@ -5,17 +5,13 @@ import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Button, Descriptions, Image, Tabs, Tag, Timeline } from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
expressDetailByOrderId,
|
||||
getDeliveryWarehouseOrderDetail,
|
||||
} from '#/views/system/delivery-warehouse-order/api';
|
||||
import { getDeliveryWarehouseOrderDetail } from '#/views/system/delivery-warehouse-order/api';
|
||||
|
||||
defineOptions({
|
||||
name: 'DeliveryWarehouseOrderDetailModal',
|
||||
});
|
||||
|
||||
const data = ref<Record<string, any>>({});
|
||||
const expressDetail = ref<Record<string, any>>({});
|
||||
const scrollToLogistics = ref(false);
|
||||
const logisticsAnchorRef = ref<HTMLElement | null>(null);
|
||||
/** 待发货时由列表传入,点击后关详情并打开发货弹窗 */
|
||||
@@ -29,13 +25,9 @@ const canShip = computed(() => {
|
||||
Number(data.value.status) === 1;
|
||||
return (mineUnsent || legacy) && typeof onShipFn.value === 'function';
|
||||
});
|
||||
/** 仅使用仓侧详情返回的本仓 packages,避免平台物流接口带出他仓商品 */
|
||||
const packageTabs = computed(() => {
|
||||
const packages = Array.isArray(data.value.packages)
|
||||
? data.value.packages
|
||||
: Array.isArray(expressDetail.value.packages)
|
||||
? expressDetail.value.packages
|
||||
: [];
|
||||
return packages;
|
||||
return Array.isArray(data.value.packages) ? data.value.packages : [];
|
||||
});
|
||||
const activePkg = ref('0');
|
||||
|
||||
@@ -58,27 +50,17 @@ const deliveryMethodMap: Record<number, string> = {
|
||||
};
|
||||
|
||||
/**
|
||||
* 拉取订单详情;已发货时继续拉物流轨迹
|
||||
* 拉取仓侧订单详情(含本仓药品 + 本仓包裹物流)
|
||||
*/
|
||||
async function loadDetail(id: number | string) {
|
||||
data.value = (await getDeliveryWarehouseOrderDetail(id)) || {};
|
||||
expressDetail.value = {};
|
||||
const sent =
|
||||
Number(data.value.is_send) === 1 ||
|
||||
Number(data.value.status) >= 2 ||
|
||||
!!data.value.express_no_id;
|
||||
if (sent && data.value.id) {
|
||||
try {
|
||||
expressDetail.value = await expressDetailByOrderId({
|
||||
order_id: data.value.id,
|
||||
});
|
||||
} catch {
|
||||
expressDetail.value = {};
|
||||
}
|
||||
}
|
||||
activePkg.value = '0';
|
||||
if (scrollToLogistics.value) {
|
||||
await nextTick();
|
||||
logisticsAnchorRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
logisticsAnchorRef.value?.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +101,6 @@ const [Modal, modalApi] = useVbenModal({
|
||||
onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
data.value = {};
|
||||
expressDetail.value = {};
|
||||
scrollToLogistics.value = false;
|
||||
onShipFn.value = null;
|
||||
return;
|
||||
@@ -233,7 +214,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
|
||||
<section ref="logisticsAnchorRef">
|
||||
<h3 class="section-title">物流信息</h3>
|
||||
<Tabs v-if="packageTabs.length" v-model:active-key="activePkg" type="card">
|
||||
<Tabs
|
||||
v-if="packageTabs.length"
|
||||
v-model:active-key="activePkg"
|
||||
type="card"
|
||||
>
|
||||
<Tabs.TabPane
|
||||
v-for="(pkg, idx) in packageTabs"
|
||||
:key="String(idx)"
|
||||
@@ -256,7 +241,9 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<div
|
||||
v-if="Array.isArray(pkg.express.detail) && pkg.express.detail.length"
|
||||
v-if="
|
||||
Array.isArray(pkg.express.detail) && pkg.express.detail.length
|
||||
"
|
||||
class="mt-4"
|
||||
>
|
||||
<Timeline>
|
||||
@@ -264,7 +251,9 @@ const [Modal, modalApi] = useVbenModal({
|
||||
v-for="(detail, dIdx) in pkg.express.detail"
|
||||
:key="dIdx"
|
||||
>
|
||||
<Tag :color="getColor(detail.status)">{{ detail.status }}</Tag>
|
||||
<Tag :color="getColor(detail.status)">{{
|
||||
detail.status
|
||||
}}</Tag>
|
||||
<p>{{ detail.detail_at }}</p>
|
||||
<p>{{ detail.detail }}</p>
|
||||
</Timeline.Item>
|
||||
@@ -279,8 +268,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
v-else-if="
|
||||
Number(data.is_send) === 1 ||
|
||||
Number(data.status) >= 2 ||
|
||||
expressNoRow().express_no ||
|
||||
expressDetail.express_no
|
||||
expressNoRow().express_no
|
||||
"
|
||||
>
|
||||
<Descriptions
|
||||
@@ -289,33 +277,12 @@ const [Modal, modalApi] = useVbenModal({
|
||||
size="small"
|
||||
>
|
||||
<Descriptions.Item label="物流公司">
|
||||
{{
|
||||
expressDetail.express_company_name ||
|
||||
expressNoRow().express_company_name ||
|
||||
'-'
|
||||
}}
|
||||
{{ expressNoRow().express_company_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="运单号">
|
||||
{{
|
||||
expressDetail.express_no || expressNoRow().express_no || '-'
|
||||
}}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="最新状态">
|
||||
{{ expressDetail.state_txt || '-' }}
|
||||
{{ expressNoRow().express_no || '-' }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<div v-if="Array.isArray(expressDetail.detail) && expressDetail.detail.length" class="mt-4">
|
||||
<Timeline>
|
||||
<Timeline.Item
|
||||
v-for="(detail, index) in expressDetail.detail"
|
||||
:key="index"
|
||||
>
|
||||
<Tag :color="getColor(detail.status)">{{ detail.status }}</Tag>
|
||||
<p>{{ detail.detail_at }}</p>
|
||||
<p>{{ detail.detail }}</p>
|
||||
</Timeline.Item>
|
||||
</Timeline>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="empty-tip">暂无物流</div>
|
||||
</section>
|
||||
|
||||
@@ -48,9 +48,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
onOpenChange(isOpen: boolean) {
|
||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||
if (isOpen) {
|
||||
const { values, update } = modalApi.getData<Record<string, any>>();
|
||||
const { values, update } = modalApi.getData<Record<string, any>>() || {};
|
||||
isUpdate.value = !!update;
|
||||
// 新建时清空表单,避免残留编辑态的 id/证照
|
||||
formApi.resetForm();
|
||||
if (values) {
|
||||
isUpdate.value = update;
|
||||
formApi.setValues(values);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +62,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}配送仓库`"
|
||||
class="w-[40%]"
|
||||
class="w-[720px]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
|
||||
/**
|
||||
* 配送仓库新建/编辑:仅基本信息
|
||||
* 合同与银行卡走独立报备入口,不在此表单填写
|
||||
* 配送仓库新建/编辑
|
||||
* - 三证必填,其余证照/合同选填
|
||||
* - 联系人/手机号仅新建时展示,用于开通仓管理员
|
||||
* - 银行卡仍走独立报备入口
|
||||
*/
|
||||
export const modalFormProps: VbenFormProps = {
|
||||
wrapperClass: 'grid-cols-12',
|
||||
@@ -41,6 +43,87 @@ export const modalFormProps: VbenFormProps = {
|
||||
fieldName: 'introduce',
|
||||
label: '仓库介绍',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '联系人姓名(将作为仓管理员昵称)',
|
||||
},
|
||||
fieldName: 'contact_name',
|
||||
label: '联系人',
|
||||
rules: 'required',
|
||||
help: '新建时用于开通配送仓库管理员账号',
|
||||
dependencies: {
|
||||
// 仅新建展示;编辑改账号请走「配送仓管理员」菜单
|
||||
if({ id }: { id?: number | string }) {
|
||||
return !id;
|
||||
},
|
||||
triggerFields: ['id'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '手机号(仓管理员登录手机)',
|
||||
},
|
||||
fieldName: 'phone',
|
||||
label: '手机号',
|
||||
rules: 'required',
|
||||
help: '默认初始密码 Xk123456@',
|
||||
dependencies: {
|
||||
if({ id }: { id?: number | string }) {
|
||||
return !id;
|
||||
},
|
||||
triggerFields: ['id'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'business_license_image',
|
||||
label: '营业执照',
|
||||
rules: 'required',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'drug_license_image',
|
||||
label: '药品经营许可证',
|
||||
rules: 'required',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'medical_device_license_image',
|
||||
label: '医疗器械经营许可证',
|
||||
rules: 'required',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'food_license_image',
|
||||
label: '食品经营许可证',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'pharmacist_certificate_image',
|
||||
label: '药师资格证',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'internet_drug_license_image',
|
||||
label: '互联网药品经营许可证',
|
||||
formItemClass: 'col-span-4',
|
||||
},
|
||||
{
|
||||
component: 'UploadOssFile',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
fieldName: 'contract_attachment',
|
||||
label: '合同附件',
|
||||
formItemClass: 'col-span-12',
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 平台配送仓库列表
|
||||
* 新建/编辑仅基本信息;银行卡报备对齐诊所,走独立弹窗
|
||||
* 新建/编辑含证照与建仓开号;银行卡报备对齐诊所,走独立弹窗
|
||||
*/
|
||||
import type { VxeGridListeners } from '#/adapter/vxe-table';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user