update customer package

This commit is contained in:
Timi
2026-09-06 15:49:20 +08:00
parent b8b3ecbf5d
commit 4c6920be85
19 changed files with 383 additions and 285 deletions
@@ -3,7 +3,7 @@
<template v-if="fulfillment">
<t-cell-group title="履约单信息" theme="card" v-entrance-transition>
<t-cell title="销售订单" arrow @click="toOrder" />
<t-cell title="履约类型" :note="getFulfillmentTypeText(fulfillment.fulfillmentType)" />
<t-cell title="订单项类型" :note="getSalesOrderItemTypeText(sourceItemType)" />
<t-cell title="状态"><template #note><t-tag :content="getFulfillmentStatusText(fulfillment.status)" variant="light-outline" :theme="getStatusTheme(fulfillment.status)" /></template></t-cell>
<t-cell title="履约时间">
<template #note>
@@ -52,22 +52,22 @@
<t-cell v-if="!fulfillment.itemList?.length" title="暂无履约明细" />
</t-cell-group>
<section
v-if="(isWaitingStock && canVerify) || (isPending && (canVerify || canCreate)) || (isVerified && canRevoke)"
v-if="(!isOrderCancelled && isWaitingStock && canVerify) || (!isOrderCancelled && isPending && (canVerify || canCreate)) || (isVerified && canRevoke)"
class="actions"
v-entrance-transition="140"
>
<t-button
v-if="isWaitingStock && canVerify"
v-if="!isOrderCancelled && isWaitingStock && canVerify"
theme="primary"
content="准备库存"
@click="prepareStock"
/>
<div v-if="isPending && canVerify" class="pair">
<div v-if="!isOrderCancelled && isPending && canVerify" class="pair">
<t-button theme="primary" content="核销履约" @click="verify" />
<t-button theme="danger" content="拒绝履约" @click="openReason('reject')" />
</div>
<t-button
v-if="isPending && canCreate"
v-if="!isOrderCancelled && isPending && canCreate"
theme="default"
content="撤销履约"
@click="openReason('cancel')"
@@ -119,16 +119,18 @@ import { BottomPopup } from "timi-tdesign-mobile";
import { PassTimeLabel } from "timi-web";
import { useUserStore } from "timi-web-api";
import FulfillmentAPI from "@/api/FulfillmentAPI";
import SalesOrderAPI from "@/api/SalesOrderAPI";
import PhotoScroller from "@/components/PhotoScroller.vue";
import { useNavBarStore } from "@/store/navBarStore";
import type { OrderFulfillment } from "@/types/Fulfillment";
import type { GaoSalesOrderItemType, SalesOrder } from "@/types/SalesOrder";
import type { PhotoItem } from "@/types/Photo";
import type { Attachment } from "timi-web-api";
import { createPackageRequestNo } from "@/utils/package";
import { getAttachmentReadURL } from "@/utils/attachment";
import { getErrorMessage } from "@/utils/error";
import { getProductPhotoURL } from "@/utils/product";
import { getFulfillmentStatusText, getFulfillmentTypeText, getStatusTheme } from "@/utils/salesOrder";
import { getFulfillmentStatusText, getSalesOrderItemTypeText, getStatusTheme } from "@/utils/salesOrder";
import { Message } from "@/utils/message";
import { permissionCodes } from "@/utils/permission";
import { uploadPhotoList } from "@/utils/photo";
@@ -140,6 +142,7 @@ const router = useRouter();
const navBarStore = useNavBarStore();
const userStore = useUserStore();
const fulfillment = ref<OrderFulfillment>();
const order = ref<SalesOrder>();
const loading = ref(false);
const operating = ref(false);
const reasonVisible = ref(false);
@@ -163,14 +166,25 @@ const fulfillmentPhotoURLList = computed(() => fulfillmentPhotoItems.value.map(i
const isWaitingStock = computed(() => fulfillment.value?.status === "WAITING_STOCK");
const isPending = computed(() => fulfillment.value?.status === "PENDING");
const isVerified = computed(() => fulfillment.value?.status === "VERIFIED");
const isOrderCancelled = computed(() => order.value?.status === "CANCELLED");
const canVerify = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.verify));
const canCreate = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.create));
const canRevoke = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.revoke));
const sourceItemType = computed<GaoSalesOrderItemType | undefined>(() => {
const sourceOrderItemId = fulfillment.value?.itemList?.[0]?.sourceOrderItemId;
return order.value?.itemList?.find(item => item.id === sourceOrderItemId)?.itemType;
});
async function loadData(): Promise<void> {
const id = String(route.params.id || "");
if (!id) return;
loading.value = true;
try { fulfillment.value = await FulfillmentAPI.detail(id); }
try {
const result = await FulfillmentAPI.detail(id);
fulfillment.value = result;
order.value = result.salesOrderId && userStore.hasPermissions(permissionCodes.salesOrder.read)
? await SalesOrderAPI.detail(result.salesOrderId)
: undefined;
}
catch (error) { Message.error(getErrorMessage(error, "履约单加载失败")); }
finally { loading.value = false; }
}
@@ -194,9 +208,10 @@ function getCurrentRouteDepth(): number {
}
async function prepareStock(): Promise<void> {
if (!fulfillment.value?.id || operating.value) return;
if (isOrderCancelled.value) { Message.warning("已取消订单不能准备库存"); return; }
operating.value = true;
try {
await FulfillmentAPI.prepareStock({ fulfillmentId: fulfillment.value.id });
fulfillment.value = await FulfillmentAPI.prepareStock({ fulfillmentId: fulfillment.value.id, reason: "库存已备齐" });
Message.success("库存准备已提交");
await loadData();
} catch (error) { Message.error(getErrorMessage(error, "库存准备失败")); }
@@ -204,9 +219,10 @@ async function prepareStock(): Promise<void> {
}
async function verify(): Promise<void> {
if (!fulfillment.value?.id || operating.value) return;
if (isOrderCancelled.value) { Message.warning("已取消订单不能核销履约"); return; }
operating.value = true;
try {
await FulfillmentAPI.verify({ fulfillmentId: fulfillment.value.id, reason: "" });
fulfillment.value = await FulfillmentAPI.verify({ fulfillmentId: fulfillment.value.id, reason: "" });
Message.success("履约已核销");
await loadData();
} catch (error) { Message.error(getErrorMessage(error, "履约核销失败")); }
@@ -218,8 +234,9 @@ async function submitReason(): Promise<void> {
operating.value = true;
try {
const payload = { fulfillmentId: fulfillment.value.id, reason: reason.value.trim() };
if (reasonAction.value === "reject") await FulfillmentAPI.reject(payload);
else await FulfillmentAPI.cancel(payload);
fulfillment.value = reasonAction.value === "reject"
? await FulfillmentAPI.reject(payload)
: await FulfillmentAPI.cancel(payload);
reasonVisible.value = false;
Message.success(reasonAction.value === "reject" ? "履约已拒绝" : "履约已撤销");
await loadData();
@@ -236,7 +253,7 @@ async function submitRevoke(): Promise<void> {
if (!revokeRequestNo.value) revokeRequestNo.value = createPackageRequestNo();
operating.value = true;
try {
await FulfillmentAPI.revoke({
fulfillment.value = await FulfillmentAPI.revoke({
fulfillmentId: fulfillment.value.id,
requestNo: revokeRequestNo.value,
reason: revokeReason.value.trim(),