forked from wangziqi/gongxue-base
feat: add tenant finance operations UI
This commit is contained in:
381
apps/taro/src/services/tenantFinance.ts
Normal file
381
apps/taro/src/services/tenantFinance.ts
Normal file
@@ -0,0 +1,381 @@
|
||||
import { apiRequest } from './api';
|
||||
|
||||
export type PaymentProvider = 'wechat_pay' | 'alipay' | 'manual' | string;
|
||||
export type BillType = 'payment' | 'refund' | 'combined';
|
||||
|
||||
export interface TenantRefundItem {
|
||||
id: string;
|
||||
refundNo?: string;
|
||||
orderId?: string;
|
||||
paymentId?: string | null;
|
||||
orderNo?: string;
|
||||
orderStatus?: string;
|
||||
paymentProvider?: string | null;
|
||||
provider?: string | null;
|
||||
providerRefundNo?: string | null;
|
||||
status?: string;
|
||||
amountCents?: number;
|
||||
amount?: number;
|
||||
reason?: string | null;
|
||||
entitlementAction?: string;
|
||||
requestedBy?: string | null;
|
||||
reviewedBy?: string | null;
|
||||
processedBy?: string | null;
|
||||
requestedAt?: string;
|
||||
reviewedAt?: string | null;
|
||||
processedAt?: string | null;
|
||||
succeededAt?: string | null;
|
||||
failedAt?: string | null;
|
||||
cancelledAt?: string | null;
|
||||
failureReason?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ReconciliationBatchItem {
|
||||
id: string;
|
||||
provider?: PaymentProvider;
|
||||
billDate?: string;
|
||||
billType?: BillType;
|
||||
source?: string;
|
||||
sourceName?: string | null;
|
||||
sourceHash?: string | null;
|
||||
status?: string;
|
||||
totalCount?: number;
|
||||
matchedCount?: number;
|
||||
mismatchCount?: number;
|
||||
missingLocalCount?: number;
|
||||
missingProviderCount?: number;
|
||||
duplicateCount?: number;
|
||||
ignoredCount?: number;
|
||||
amountCents?: number;
|
||||
refundAmountCents?: number;
|
||||
feeCents?: number;
|
||||
error?: string | null;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ReconciliationItem {
|
||||
id: string;
|
||||
batchId?: string;
|
||||
rowNo?: number;
|
||||
provider?: PaymentProvider;
|
||||
transactionType?: string;
|
||||
providerTradeNo?: string | null;
|
||||
providerRefundNo?: string | null;
|
||||
orderNo?: string | null;
|
||||
refundNo?: string | null;
|
||||
amountCents?: number;
|
||||
refundAmountCents?: number;
|
||||
feeCents?: number;
|
||||
providerStatus?: string | null;
|
||||
localStatus?: string | null;
|
||||
orderId?: string | null;
|
||||
paymentId?: string | null;
|
||||
refundRequestId?: string | null;
|
||||
matchStatus?: string;
|
||||
severity?: string;
|
||||
issueCode?: string | null;
|
||||
details?: Record<string, unknown>;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface ReconciliationIssueItem {
|
||||
id: string;
|
||||
issueNo?: string;
|
||||
batchId?: string;
|
||||
itemId?: string;
|
||||
provider?: PaymentProvider;
|
||||
transactionType?: string;
|
||||
issueCode?: string | null;
|
||||
matchStatus?: string;
|
||||
severity?: string;
|
||||
status?: string;
|
||||
resolutionType?: string;
|
||||
orderId?: string | null;
|
||||
paymentId?: string | null;
|
||||
refundRequestId?: string | null;
|
||||
orderNo?: string | null;
|
||||
refundNo?: string | null;
|
||||
providerTradeNo?: string | null;
|
||||
providerRefundNo?: string | null;
|
||||
amountCents?: number;
|
||||
refundAmountCents?: number;
|
||||
assignedTo?: string | null;
|
||||
assignedToName?: string | null;
|
||||
createdByName?: string | null;
|
||||
resolvedByName?: string | null;
|
||||
resolvedAt?: string | null;
|
||||
dueAt?: string | null;
|
||||
summary?: string | null;
|
||||
resolutionNote?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ProviderBillJobItem {
|
||||
id: string;
|
||||
provider?: PaymentProvider;
|
||||
billDate?: string;
|
||||
billType?: BillType;
|
||||
status?: string;
|
||||
sourceName?: string | null;
|
||||
sourceHash?: string | null;
|
||||
rowCount?: number | null;
|
||||
downloadHashType?: string | null;
|
||||
downloadHashValue?: string | null;
|
||||
downloadUrlHost?: string | null;
|
||||
reconciliationBatchId?: string | null;
|
||||
requestedBy?: string | null;
|
||||
claimedBy?: string | null;
|
||||
claimedAt?: string | null;
|
||||
completedAt?: string | null;
|
||||
failedAt?: string | null;
|
||||
errorCode?: string | null;
|
||||
errorMessage?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface CommerceOperationAnomaly {
|
||||
type?: string;
|
||||
id: string;
|
||||
severity?: 'info' | 'warning' | 'error' | 'critical' | string;
|
||||
status?: string;
|
||||
title?: string;
|
||||
provider?: PaymentProvider | null;
|
||||
orderNo?: string | null;
|
||||
refundNo?: string | null;
|
||||
amountCents?: number;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
source?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface AdjustmentVoucherItem {
|
||||
id: string;
|
||||
voucherNo?: string;
|
||||
sourceType?: string;
|
||||
sourceId?: string | null;
|
||||
reconciliationIssueId?: string | null;
|
||||
reconciliationItemId?: string | null;
|
||||
orderId?: string | null;
|
||||
paymentId?: string | null;
|
||||
refundRequestId?: string | null;
|
||||
orderNo?: string | null;
|
||||
refundNo?: string | null;
|
||||
provider?: PaymentProvider | null;
|
||||
providerTradeNo?: string | null;
|
||||
providerRefundNo?: string | null;
|
||||
adjustmentType?: string;
|
||||
direction?: string;
|
||||
amountCents?: number;
|
||||
status?: string;
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
assetId?: string | null;
|
||||
externalUrl?: string | null;
|
||||
submittedByName?: string | null;
|
||||
submittedAt?: string | null;
|
||||
reviewedByName?: string | null;
|
||||
reviewedAt?: string | null;
|
||||
reviewNote?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
createdByName?: string | null;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface AdjustmentVoucherReport {
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
totalCount?: number;
|
||||
totalAmountCents?: number;
|
||||
pendingReviewCount?: number;
|
||||
byStatus?: Record<string, unknown>[];
|
||||
byType?: Record<string, unknown>[];
|
||||
bySource?: Record<string, unknown>[];
|
||||
daily?: Record<string, unknown>[];
|
||||
}
|
||||
|
||||
export async function loadTenantRefunds(query: { status?: string; orderNo?: string; limit?: number } = {}) {
|
||||
return apiRequest<{ items?: TenantRefundItem[] }>('/api/commerce/refunds', {
|
||||
query: { ...query, limit: query.limit || 50 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function createTenantRefund(input: {
|
||||
orderNo: string;
|
||||
amountCents?: number;
|
||||
reason?: string | null;
|
||||
refundNo?: string;
|
||||
entitlementAction?: 'none' | 'revoke_on_success';
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: TenantRefundItem }>('/api/commerce/refunds', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateTenantRefundStatus(input: {
|
||||
refundId: string;
|
||||
action: string;
|
||||
note?: string | null;
|
||||
providerRefundNo?: string | null;
|
||||
providerNotifyUrl?: string | null;
|
||||
failureReason?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: TenantRefundItem }>('/api/commerce/refunds/status', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadReconciliationBatches(query: { provider?: string; status?: string; billDate?: string; limit?: number } = {}) {
|
||||
return apiRequest<{ items?: ReconciliationBatchItem[] }>('/api/commerce/reconciliation/batches', {
|
||||
query: { ...query, limit: query.limit || 30 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadReconciliationItems(query: {
|
||||
batchId?: string;
|
||||
matchStatus?: string;
|
||||
severity?: string;
|
||||
orderNo?: string;
|
||||
limit?: number;
|
||||
} = {}) {
|
||||
return apiRequest<{ items?: ReconciliationItem[] }>('/api/commerce/reconciliation/items', {
|
||||
query: { ...query, limit: query.limit || 80 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function createReconciliationIssue(input: {
|
||||
itemId: string;
|
||||
assignedTo?: string | null;
|
||||
assignedToUserId?: string | null;
|
||||
dueAt?: string | null;
|
||||
summary?: string | null;
|
||||
note?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: ReconciliationIssueItem; idempotent?: boolean }>('/api/commerce/reconciliation/issues/create', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadReconciliationIssues(query: {
|
||||
status?: string;
|
||||
severity?: string;
|
||||
assignedTo?: string;
|
||||
batchId?: string;
|
||||
orderNo?: string;
|
||||
limit?: number;
|
||||
} = {}) {
|
||||
return apiRequest<{ items?: ReconciliationIssueItem[] }>('/api/commerce/reconciliation/issues', {
|
||||
query: { ...query, limit: query.limit || 50 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateReconciliationIssueStatus(input: {
|
||||
issueId: string;
|
||||
action: 'start' | 'assign' | 'resolve' | 'ignore' | 'escalate' | 'reopen';
|
||||
note?: string | null;
|
||||
dueAt?: string | null;
|
||||
assignedTo?: string | null;
|
||||
resolutionType?: string | null;
|
||||
resolutionNote?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: ReconciliationIssueItem }>('/api/commerce/reconciliation/issues/status', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestProviderBillDownload(input: {
|
||||
provider: Exclude<PaymentProvider, 'manual'>;
|
||||
billDate: string;
|
||||
billType?: BillType;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: ProviderBillJobItem; idempotent?: boolean }>('/api/commerce/reconciliation/provider-bills/request', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadProviderBillJobs(query: { provider?: string; status?: string; billDate?: string; limit?: number } = {}) {
|
||||
return apiRequest<{ items?: ProviderBillJobItem[] }>('/api/commerce/reconciliation/provider-bills/jobs', {
|
||||
query: { ...query, limit: query.limit || 30 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadCommerceOperationAnomalies(query: { provider?: string; limit?: number } = {}) {
|
||||
return apiRequest<{ summary?: Record<string, unknown>; items?: CommerceOperationAnomaly[] }>('/api/commerce/operations/anomalies', {
|
||||
query: { ...query, limit: query.limit || 50 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadAdjustmentVouchers(query: {
|
||||
status?: string;
|
||||
sourceType?: string;
|
||||
orderNo?: string;
|
||||
voucherNo?: string;
|
||||
reconciliationIssueId?: string;
|
||||
limit?: number;
|
||||
} = {}) {
|
||||
return apiRequest<{ items?: AdjustmentVoucherItem[] }>('/api/commerce/adjustment-vouchers', {
|
||||
query: { ...query, limit: query.limit || 50 },
|
||||
});
|
||||
}
|
||||
|
||||
export async function createAdjustmentVoucher(input: {
|
||||
sourceType?: string;
|
||||
sourceId?: string | null;
|
||||
reconciliationIssueId?: string | null;
|
||||
reconciliationItemId?: string | null;
|
||||
orderId?: string | null;
|
||||
paymentId?: string | null;
|
||||
refundRequestId?: string | null;
|
||||
orderNo?: string | null;
|
||||
refundNo?: string | null;
|
||||
adjustmentType?: string;
|
||||
direction?: string;
|
||||
amountCents?: number;
|
||||
status?: 'draft' | 'submitted';
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
assetId?: string | null;
|
||||
externalUrl?: string | null;
|
||||
note?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: AdjustmentVoucherItem }>('/api/commerce/adjustment-vouchers', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateAdjustmentVoucherStatus(input: {
|
||||
voucherId: string;
|
||||
status: 'submitted' | 'approved' | 'rejected' | 'voided';
|
||||
reviewNote?: string | null;
|
||||
note?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
}) {
|
||||
return apiRequest<{ item?: AdjustmentVoucherItem; idempotent?: boolean }>('/api/commerce/adjustment-vouchers/status', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadAdjustmentVoucherReport(query: { startDate?: string; endDate?: string } = {}) {
|
||||
return apiRequest<{ item?: AdjustmentVoucherReport }>('/api/commerce/adjustment-vouchers/report', { query });
|
||||
}
|
||||
Reference in New Issue
Block a user