fix cancel order payment

This commit is contained in:
Timi
2026-09-07 23:11:32 +08:00
parent 904d226943
commit 9fa6527f96
7 changed files with 74 additions and 15 deletions
+26 -1
View File
@@ -62,4 +62,29 @@ async function fundRecordDetail(id: string): Promise<FundRecord> {
return await axios.post(`${FUND_URI}/detail`, undefined, { params: { id } }); return await axios.post(`${FUND_URI}/detail`, undefined, { params: { id } });
} }
export default { list, detail, createDirectProduct, update, cancel, receivePayment, verifyPayment, rejectPayment, cancelPayment, refund, confirmNoRefund, revokeFund, fundRecordList, fundRecordDetail }; async function myReceiveRecordList(page: FundRecordPage): Promise<SalesOrderPageResult<FundRecord>> {
return await axios.post(`${FUND_URI}/my-receive/list`, withCurrentStoreId(page));
}
async function myReceiveRecordDetail(id: string): Promise<FundRecord> {
return await axios.post(`${FUND_URI}/my-receive/detail`, undefined, { params: { id } });
}
export default {
list,
detail,
createDirectProduct,
update,
cancel,
receivePayment,
verifyPayment,
rejectPayment,
cancelPayment,
refund,
confirmNoRefund,
revokeFund,
fundRecordList,
fundRecordDetail,
myReceiveRecordList,
myReceiveRecordDetail
};
+8 -3
View File
@@ -1,5 +1,5 @@
<template> <template>
<div v-can="permissionCodes.fundRecord.read" class="package-record-detail"> <div v-can="pageAccess" class="package-record-detail">
<template v-if="record"> <template v-if="record">
<section class="hero" v-entrance-transition> <section class="hero" v-entrance-transition>
<div class="header"> <div class="header">
@@ -150,9 +150,12 @@ const isOperating = ref(false);
const record = ref<FundRecord>(); const record = ref<FundRecord>();
const isLoading = ref(false); const isLoading = ref(false);
const pageAccess = computed(() => [permissionCodes.fundRecord.read, permissionCodes.fundReceive.create]);
const isPendingReceive = computed(() => record.value?.operationType === "RECEIVE" && record.value.status === "PENDING"); const isPendingReceive = computed(() => record.value?.operationType === "RECEIVE" && record.value.status === "PENDING");
const canVerifyReceive = computed(() => isPendingReceive.value && userStore.hasPermissions(permissionCodes.fundReceive.verify)); const canVerifyReceive = computed(() => isPendingReceive.value && userStore.hasPermissions(permissionCodes.fundReceive.verify));
const canCancelReceive = computed(() => isPendingReceive.value && userStore.hasPermissions(permissionCodes.fundReceive.create)); const loginUserId = computed(() => userStore.loginUser.user?.id || userStore.loginUser.id || "");
const canCancelReceive = computed(() => isPendingReceive.value && (userStore.hasPermissions(permissionCodes.fundRecord.read)
|| (userStore.hasPermissions(permissionCodes.fundReceive.create) && record.value?.operatorUserId === loginUserId.value)));
const canRevoke = computed(() => record.value?.status === "VERIFIED" const canRevoke = computed(() => record.value?.status === "VERIFIED"
&& record.value.operationType !== "REVOKE" && record.value.operationType !== "REVOKE"
&& !record.value.revokeRecordId && !record.value.revokeRecordId
@@ -177,7 +180,9 @@ async function loadData(): Promise<void> {
} }
isLoading.value = true; isLoading.value = true;
try { try {
record.value = await SalesOrderAPI.fundRecordDetail(id); record.value = userStore.hasPermissions(permissionCodes.fundRecord.read)
? await SalesOrderAPI.fundRecordDetail(id)
: await SalesOrderAPI.myReceiveRecordDetail(id);
} catch (error) { } catch (error) {
Message.error(getErrorMessage(error, "资金记录加载失败")); Message.error(getErrorMessage(error, "资金记录加载失败"));
} finally { } finally {
+13 -4
View File
@@ -1,8 +1,9 @@
<template> <template>
<div v-can="permissionCodes.fundRecord.read" class="sales-order-record-list"> <div v-can="pageAccess" class="sales-order-record-list">
<div class="filters"> <div class="filters">
<t-dropdown-menu class="menus"> <t-dropdown-menu class="menus">
<t-dropdown-item <t-dropdown-item
v-if="!isSelfReceiveOnly"
v-model="operationType" v-model="operationType"
label="操作类型" label="操作类型"
:options="operationOptions" :options="operationOptions"
@@ -82,6 +83,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { type DropdownValue } from "tdesign-mobile-vue"; import { type DropdownValue } from "tdesign-mobile-vue";
import { useUserStore } from "timi-web-api";
import SalesOrderAPI from "@/api/SalesOrderAPI"; import SalesOrderAPI from "@/api/SalesOrderAPI";
import { useNavBarStore } from "@/store/navBarStore"; import { useNavBarStore } from "@/store/navBarStore";
import type { FundOperationType, FundRecord, FundRecordStatus } from "@/types/SalesOrder"; import type { FundOperationType, FundRecord, FundRecordStatus } from "@/types/SalesOrder";
@@ -97,6 +99,7 @@ defineOptions({ name: "FundRecordList" });
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const navBarStore = useNavBarStore(); const navBarStore = useNavBarStore();
const userStore = useUserStore();
const recordList = ref<FundRecord[]>([]); const recordList = ref<FundRecord[]>([]);
const operationType = ref(route.query.operationType === "RECEIVE" ? "RECEIVE" : "ALL"); const operationType = ref(route.query.operationType === "RECEIVE" ? "RECEIVE" : "ALL");
const status = ref(route.query.status === "PENDING" ? "PENDING" : "ALL"); const status = ref(route.query.status === "PENDING" ? "PENDING" : "ALL");
@@ -105,6 +108,9 @@ const total = ref(0);
const loading = ref(false); const loading = ref(false);
const isRefreshing = ref(false); const isRefreshing = ref(false);
const noMore = ref(false); const noMore = ref(false);
const isSelfReceiveOnly = computed(() => !userStore.hasPermissions(permissionCodes.fundRecord.read)
&& userStore.hasPermissions(permissionCodes.fundReceive.create));
const pageAccess = computed(() => [permissionCodes.fundRecord.read, permissionCodes.fundReceive.create]);
const operationOptions = [ const operationOptions = [
{ label: "全部类型", value: "ALL" }, { label: "全部类型", value: "ALL" },
{ label: "线下收款", value: "RECEIVE" }, { label: "线下收款", value: "RECEIVE" },
@@ -127,13 +133,16 @@ async function loadMore(): Promise<void> {
} }
loading.value = true; loading.value = true;
try { try {
const result = await SalesOrderAPI.fundRecordList({ const page = {
index: pageIndex.value, index: pageIndex.value,
size: 15, size: 15,
salesOrderId: String(route.query.salesOrderId || "") || undefined, salesOrderId: String(route.query.salesOrderId || "") || undefined,
operationType: operationType.value === "ALL" ? undefined : operationType.value as FundOperationType, operationType: isSelfReceiveOnly.value || operationType.value === "ALL" ? undefined : operationType.value as FundOperationType,
status: status.value === "ALL" ? undefined : status.value as FundRecordStatus status: status.value === "ALL" ? undefined : status.value as FundRecordStatus
}); };
const result = isSelfReceiveOnly.value
? await SalesOrderAPI.myReceiveRecordList(page)
: await SalesOrderAPI.fundRecordList(page);
const list = result.list || []; const list = result.list || [];
recordList.value = recordList.value.concat(list); recordList.value = recordList.value.concat(list);
total.value = result.total || 0; total.value = result.total || 0;
+14 -2
View File
@@ -46,7 +46,7 @@
<strong>购买产品</strong> <strong>购买产品</strong>
<span v-text="`${items.length} 项`" /> <span v-text="`${items.length} 项`" />
</div> </div>
<div class="tips">同一 SKU 单位不能重复,数量最多三位小数</div> <div class="tips">同一 SKU 单位不能重复</div>
<div class="items"> <div class="items">
<div v-for="(item, index) in items" :key="item.clientKey" class="item"> <div v-for="(item, index) in items" :key="item.clientKey" class="item">
<div class="header"> <div class="header">
@@ -74,6 +74,13 @@
:readonly="!canPriceOverride" :readonly="!canPriceOverride"
:placeholder="getItemUnitPricePlaceholder(item)" :placeholder="getItemUnitPricePlaceholder(item)"
/> />
<template #help>
<span
v-if="item.skuId && item.unitPriceText"
class="price-tips gray"
v-text="getItemUnitPricePlaceholder(item)"
/>
</template>
</t-form-item> </t-form-item>
<t-form-item label="数量" content-align="right"> <t-form-item label="数量" content-align="right">
<t-stepper <t-stepper
@@ -293,7 +300,7 @@ function getItemUnitPrice(item: FormItem): number | undefined {
} }
function getItemUnitPricePlaceholder(item: FormItem): string { function getItemUnitPricePlaceholder(item: FormItem): string {
const salePrice = getUnit(item)?.salePrice; const salePrice = getUnit(item)?.salePrice;
return salePrice === undefined || salePrice === null ? "产品价" : `产品价:${formatProductAmount(salePrice)}`; return salePrice === undefined || salePrice === null ? "产品定价" : `产品定价:${formatProductAmount(salePrice)}`;
} }
function calculateItemAmount(item: FormItem): number | undefined { function calculateItemAmount(item: FormItem): number | undefined {
const quantity = normalizePackageQuantity(item.quantity ?? ""); const quantity = normalizePackageQuantity(item.quantity ?? "");
@@ -526,6 +533,11 @@ onUnmounted(() => navBarStore.clearRight());
} }
} }
.price-tips {
flex: 1;
text-align: right;
}
.unit-list { .unit-list {
gap: .5rem; gap: .5rem;
width: 100%; width: 100%;
+7 -1
View File
@@ -179,7 +179,12 @@
<t-cell title="收款状态" :note="getSalesPaymentStatusText(order.paymentStatus)" /> <t-cell title="收款状态" :note="getSalesPaymentStatusText(order.paymentStatus)" />
<t-cell v-if="order.paymentStatus === 'PAID'" title="全额实收时间" :note="getPaidAtText(order.paidAt)" /> <t-cell v-if="order.paymentStatus === 'PAID'" title="全额实收时间" :note="getPaidAtText(order.paidAt)" />
<t-cell title="退款状态" :note="getSalesRefundStatusText(order.refundStatus)" /> <t-cell title="退款状态" :note="getSalesRefundStatusText(order.refundStatus)" />
<t-cell v-if="canReadFund" title="查看全部资金流水" arrow @click="toFundRecords" /> <t-cell
v-if="canReadFund || canReadMyReceive"
:title="canReadFund ? '查看全部资金流水' : '查看我的收款申请'"
arrow
@click="toFundRecords"
/>
</t-cell-group> </t-cell-group>
<t-cell-group v-if="order.status === 'CANCELLED'" class="cancel-info" title="取消记录" theme="card"> <t-cell-group v-if="order.status === 'CANCELLED'" class="cancel-info" title="取消记录" theme="card">
<t-cell title="取消时间" :note="order.cancelledAt ? Time.toDateTime(order.cancelledAt) : '未知'" /> <t-cell title="取消时间" :note="order.cancelledAt ? Time.toDateTime(order.cancelledAt) : '未知'" />
@@ -252,6 +257,7 @@ const isSaving = ref(false);
const editRemark = ref(""); const editRemark = ref("");
const photoItems = ref<PhotoItem[]>([]); const photoItems = ref<PhotoItem[]>([]);
const canReadFund = computed(() => userStore.hasPermissions(permissionCodes.fundRecord.read)); const canReadFund = computed(() => userStore.hasPermissions(permissionCodes.fundRecord.read));
const canReadMyReceive = computed(() => userStore.hasPermissions(permissionCodes.fundReceive.create));
const canUpdate = computed(() => userStore.hasPermissions(permissionCodes.salesOrder.update)); const canUpdate = computed(() => userStore.hasPermissions(permissionCodes.salesOrder.update));
const canCreateFulfillment = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.create)); const canCreateFulfillment = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.create));
const canOperateStock = computed(() => userStore.hasPermissions(permissionCodes.productStock.create)); const canOperateStock = computed(() => userStore.hasPermissions(permissionCodes.productStock.create));
+2 -2
View File
@@ -89,14 +89,14 @@ const actions = computed(() => [
...(canCreate.value ? [{ ...(canCreate.value ? [{
key: "create", key: "create",
text: "直接产品下单", text: "直接产品下单",
icon: "add", icon: "task",
theme: "primary" as const, theme: "primary" as const,
action: toCreate action: toCreate
}] : []), }] : []),
...(canCreatePackageOrder.value ? [{ ...(canCreatePackageOrder.value ? [{
key: "create-package-order", key: "create-package-order",
text: "创建客户套餐", text: "创建客户套餐",
icon: "add-circle", icon: "layers",
theme: "primary" as const, theme: "primary" as const,
action: toCreatePackageOrder action: toCreatePackageOrder
}] : []) }] : [])
+4 -2
View File
@@ -160,7 +160,7 @@ async function save(): Promise<void> {
if (!requestNo.value) requestNo.value = createPackageRequestNo(); if (!requestNo.value) requestNo.value = createPackageRequestNo();
saving.value = true; saving.value = true;
try { try {
await SalesOrderAPI.receivePayment({ const record = await SalesOrderAPI.receivePayment({
salesOrderId: order.value.id, salesOrderId: order.value.id,
requestNo: requestNo.value, requestNo: requestNo.value,
amount, amount,
@@ -169,7 +169,9 @@ async function save(): Promise<void> {
remark: remark.value.trim() || null remark: remark.value.trim() || null
}); });
Message.success("收款登记已提交"); Message.success("收款登记已提交");
await router.replace(`/management/sales-orders/${order.value.id}`); await router.replace(record.id && userStore.hasPermissions(permissionCodes.fundReceive.create)
? `/management/fund-records/${record.id}`
: `/management/sales-orders/${order.value.id}`);
} catch (error) { } catch (error) {
Message.error(getErrorMessage(error, "收款登记失败,重试会复用同一请求号")); Message.error(getErrorMessage(error, "收款登记失败,重试会复用同一请求号"));
} finally { } finally {