feat(finance): show cross-app withdrawal sources
This commit is contained in:
parent
169ada93b5
commit
42e9eb0804
@ -4556,6 +4556,27 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/integrations/withdrawal-applications": {
|
||||
"post": {
|
||||
"operationId": "createExternalWithdrawalApplication",
|
||||
"description": "来源钱包使用 App 独立 Bearer token 幂等提交提现申请,不使用后台用户 JWT。",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ExternalWithdrawalApplicationInput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/components/responses/FinanceWithdrawalApplicationResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/finance/withdrawal-applications": {
|
||||
"get": {
|
||||
"operationId": "listFinanceWithdrawalApplications",
|
||||
@ -14288,6 +14309,14 @@
|
||||
"appName": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceSystem": {
|
||||
"type": "string",
|
||||
"description": "资金执行来源;hyapp_wallet 为平台钱包,likei 为 Aslan legacy 钱包"
|
||||
},
|
||||
"sourceApplicationId": {
|
||||
"type": "string",
|
||||
"description": "来源钱包的提现申请号,用于跨系统审计和幂等回调"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -14362,6 +14391,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ExternalWithdrawalApplicationInput": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"appCode",
|
||||
"sourceSystem",
|
||||
"sourceApplicationId",
|
||||
"userId",
|
||||
"salaryAssetType",
|
||||
"withdrawAmount",
|
||||
"withdrawAmountMinor",
|
||||
"withdrawMethod",
|
||||
"withdrawAddress"
|
||||
],
|
||||
"properties": {
|
||||
"appCode": { "type": "string" },
|
||||
"sourceSystem": { "type": "string" },
|
||||
"sourceApplicationId": { "type": "string" },
|
||||
"userId": { "type": "string" },
|
||||
"salaryAssetType": { "type": "string" },
|
||||
"withdrawAmount": { "type": "string" },
|
||||
"withdrawAmountMinor": { "type": "integer", "minimum": 1 },
|
||||
"withdrawMethod": { "type": "string" },
|
||||
"withdrawAddress": { "type": "string" },
|
||||
"createdAtMs": { "type": "integer", "format": "int64" }
|
||||
}
|
||||
},
|
||||
"FinanceCoinSellerRechargeOrderInput": {
|
||||
"type": "object",
|
||||
"required": ["appCode", "targetUserId", "usdAmount", "providerCode", "externalOrderNo"],
|
||||
|
||||
@ -73,6 +73,7 @@ export function FinanceWithdrawalApplicationList({
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>APP</TableCell>
|
||||
<TableCell>来源单号</TableCell>
|
||||
<TableCell>用户ID</TableCell>
|
||||
<TableCell align="right">提现金额</TableCell>
|
||||
<TableCell>提现方式</TableCell>
|
||||
@ -107,6 +108,12 @@ export function FinanceWithdrawalApplicationList({
|
||||
size="small"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Stacked
|
||||
primary={sourceSystemLabel(item.sourceSystem)}
|
||||
secondary={item.sourceApplicationId || ""}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>{item.userId || "-"}</TableCell>
|
||||
<TableCell align="right">$ {formatAmount(item.withdrawAmount)}</TableCell>
|
||||
<TableCell>{item.withdrawMethod || "-"}</TableCell>
|
||||
@ -214,7 +221,7 @@ export function FinanceWithdrawalApplicationList({
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell align="center" colSpan={isOperationsReview ? 10 : 11}>
|
||||
<TableCell align="center" colSpan={isOperationsReview ? 11 : 12}>
|
||||
当前无数据
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@ -240,6 +247,16 @@ export function FinanceWithdrawalApplicationList({
|
||||
);
|
||||
}
|
||||
|
||||
function sourceSystemLabel(value) {
|
||||
if (!value || value === "hyapp_wallet") {
|
||||
return "HY 钱包";
|
||||
}
|
||||
if (value === "likei") {
|
||||
return "Likei";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function ReviewContext({ application }) {
|
||||
return (
|
||||
<span className="finance-review-context">
|
||||
|
||||
@ -50,6 +50,8 @@ test("renders withdrawal application table with requested finance columns", () =
|
||||
operationsReviewerName: "运营一",
|
||||
operationsReviewerUserId: 11,
|
||||
operationsStatus: "approved",
|
||||
sourceApplicationId: "991001",
|
||||
sourceSystem: "likei",
|
||||
status: "approved",
|
||||
userId: "10001",
|
||||
withdrawAddress: "TRX-address",
|
||||
@ -62,6 +64,7 @@ test("renders withdrawal application table with requested finance columns", () =
|
||||
});
|
||||
|
||||
expect(screen.getByRole("columnheader", { name: "APP" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("columnheader", { name: "来源单号" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("columnheader", { name: "用户ID" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("columnheader", { name: "提现金额" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("columnheader", { name: "提现方式" })).toBeInTheDocument();
|
||||
@ -73,6 +76,8 @@ test("renders withdrawal application table with requested finance columns", () =
|
||||
expect(screen.getByRole("columnheader", { name: "财务审核原因" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("columnheader", { name: "操作" })).toBeInTheDocument();
|
||||
expect(screen.getByText("lalu")).toBeInTheDocument();
|
||||
expect(screen.getByText("Likei")).toBeInTheDocument();
|
||||
expect(screen.getByText("991001")).toBeInTheDocument();
|
||||
expect(screen.getByText("10001")).toBeInTheDocument();
|
||||
expect(screen.getByText("$ 12.5")).toBeInTheDocument();
|
||||
expect(screen.getByText("USDT-TRC20")).toBeInTheDocument();
|
||||
@ -88,7 +93,7 @@ test("renders withdrawal application table with requested finance columns", () =
|
||||
test("keeps empty withdrawal table colspan aligned with visible columns", () => {
|
||||
const { container } = renderList(baseProps);
|
||||
|
||||
expect(container.querySelector("tbody td")?.colSpan).toBe(11);
|
||||
expect(container.querySelector("tbody td")?.colSpan).toBe(12);
|
||||
expect(screen.getByText("当前无数据")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@ -31,6 +31,8 @@ export function normalizeWithdrawalApplication(item = {}) {
|
||||
operationsReviewerUserId: item.operationsReviewerUserId ?? item.operations_reviewer_user_id,
|
||||
operationsStatus: stringValue(item.operationsStatus ?? item.operations_status),
|
||||
salaryAssetType: stringValue(item.salaryAssetType ?? item.salary_asset_type),
|
||||
sourceApplicationId: stringValue(item.sourceApplicationId ?? item.source_application_id),
|
||||
sourceSystem: stringValue(item.sourceSystem ?? item.source_system),
|
||||
status: stringValue(item.status),
|
||||
updatedAtMs: numberOrNull(item.updatedAtMs ?? item.updated_at_ms),
|
||||
userId: stringValue(item.userId ?? item.user_id),
|
||||
|
||||
@ -54,6 +54,7 @@ export const API_OPERATIONS = {
|
||||
createEmojiPack: "createEmojiPack",
|
||||
createExploreTab: "createExploreTab",
|
||||
createExternalAdminUser: "createExternalAdminUser",
|
||||
createExternalWithdrawalApplication: "createExternalWithdrawalApplication",
|
||||
createFinanceCoinSellerRechargeOrder: "createFinanceCoinSellerRechargeOrder",
|
||||
createFullServerNoticeFanout: "createFullServerNoticeFanout",
|
||||
createGift: "createGift",
|
||||
@ -712,6 +713,11 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
||||
permission: "external-admin-user:create",
|
||||
permissions: ["external-admin-user:create","external-admin-user:permissions"]
|
||||
},
|
||||
createExternalWithdrawalApplication: {
|
||||
method: "POST",
|
||||
operationId: API_OPERATIONS.createExternalWithdrawalApplication,
|
||||
path: "/v1/integrations/withdrawal-applications"
|
||||
},
|
||||
createFinanceCoinSellerRechargeOrder: {
|
||||
method: "POST",
|
||||
operationId: API_OPERATIONS.createFinanceCoinSellerRechargeOrder,
|
||||
|
||||
50
src/shared/api/generated/schema.d.ts
vendored
50
src/shared/api/generated/schema.d.ts
vendored
@ -2636,6 +2636,23 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/integrations/withdrawal-applications": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** @description 来源钱包使用 App 独立 Bearer token 幂等提交提现申请,不使用后台用户 JWT。 */
|
||||
post: operations["createExternalWithdrawalApplication"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/admin/finance/withdrawal-applications": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@ -6652,6 +6669,10 @@ export interface components {
|
||||
id: number;
|
||||
appCode: string;
|
||||
appName?: string;
|
||||
/** @description 资金执行来源;hyapp_wallet 为平台钱包,likei 为 Aslan legacy 钱包 */
|
||||
sourceSystem?: string;
|
||||
/** @description 来源钱包的提现申请号,用于跨系统审计和幂等回调 */
|
||||
sourceApplicationId?: string;
|
||||
userId: string;
|
||||
salaryAssetType?: string;
|
||||
withdrawAmount: string;
|
||||
@ -6679,6 +6700,19 @@ export interface components {
|
||||
createdAtMs: number;
|
||||
updatedAtMs?: number;
|
||||
};
|
||||
ExternalWithdrawalApplicationInput: {
|
||||
appCode: string;
|
||||
sourceSystem: string;
|
||||
sourceApplicationId: string;
|
||||
userId: string;
|
||||
salaryAssetType: string;
|
||||
withdrawAmount: string;
|
||||
withdrawAmountMinor: number;
|
||||
withdrawMethod: string;
|
||||
withdrawAddress: string;
|
||||
/** Format: int64 */
|
||||
createdAtMs?: number;
|
||||
};
|
||||
FinanceCoinSellerRechargeOrderInput: {
|
||||
appCode: string;
|
||||
targetUserId: string;
|
||||
@ -11482,6 +11516,22 @@ export interface operations {
|
||||
200: components["responses"]["FinanceScopeCatalogResponse"];
|
||||
};
|
||||
};
|
||||
createExternalWithdrawalApplication: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["ExternalWithdrawalApplicationInput"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
201: components["responses"]["FinanceWithdrawalApplicationResponse"];
|
||||
};
|
||||
};
|
||||
listFinanceWithdrawalApplications: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user