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": {
|
"/admin/finance/withdrawal-applications": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "listFinanceWithdrawalApplications",
|
"operationId": "listFinanceWithdrawalApplications",
|
||||||
@ -14288,6 +14309,14 @@
|
|||||||
"appName": {
|
"appName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"sourceSystem": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "资金执行来源;hyapp_wallet 为平台钱包,likei 为 Aslan legacy 钱包"
|
||||||
|
},
|
||||||
|
"sourceApplicationId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "来源钱包的提现申请号,用于跨系统审计和幂等回调"
|
||||||
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"type": "string"
|
"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": {
|
"FinanceCoinSellerRechargeOrderInput": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["appCode", "targetUserId", "usdAmount", "providerCode", "externalOrderNo"],
|
"required": ["appCode", "targetUserId", "usdAmount", "providerCode", "externalOrderNo"],
|
||||||
|
|||||||
@ -73,6 +73,7 @@ export function FinanceWithdrawalApplicationList({
|
|||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>APP</TableCell>
|
<TableCell>APP</TableCell>
|
||||||
|
<TableCell>来源单号</TableCell>
|
||||||
<TableCell>用户ID</TableCell>
|
<TableCell>用户ID</TableCell>
|
||||||
<TableCell align="right">提现金额</TableCell>
|
<TableCell align="right">提现金额</TableCell>
|
||||||
<TableCell>提现方式</TableCell>
|
<TableCell>提现方式</TableCell>
|
||||||
@ -107,6 +108,12 @@ export function FinanceWithdrawalApplicationList({
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Stacked
|
||||||
|
primary={sourceSystemLabel(item.sourceSystem)}
|
||||||
|
secondary={item.sourceApplicationId || ""}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
<TableCell>{item.userId || "-"}</TableCell>
|
<TableCell>{item.userId || "-"}</TableCell>
|
||||||
<TableCell align="right">$ {formatAmount(item.withdrawAmount)}</TableCell>
|
<TableCell align="right">$ {formatAmount(item.withdrawAmount)}</TableCell>
|
||||||
<TableCell>{item.withdrawMethod || "-"}</TableCell>
|
<TableCell>{item.withdrawMethod || "-"}</TableCell>
|
||||||
@ -214,7 +221,7 @@ export function FinanceWithdrawalApplicationList({
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell align="center" colSpan={isOperationsReview ? 10 : 11}>
|
<TableCell align="center" colSpan={isOperationsReview ? 11 : 12}>
|
||||||
当前无数据
|
当前无数据
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</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 }) {
|
function ReviewContext({ application }) {
|
||||||
return (
|
return (
|
||||||
<span className="finance-review-context">
|
<span className="finance-review-context">
|
||||||
|
|||||||
@ -50,6 +50,8 @@ test("renders withdrawal application table with requested finance columns", () =
|
|||||||
operationsReviewerName: "运营一",
|
operationsReviewerName: "运营一",
|
||||||
operationsReviewerUserId: 11,
|
operationsReviewerUserId: 11,
|
||||||
operationsStatus: "approved",
|
operationsStatus: "approved",
|
||||||
|
sourceApplicationId: "991001",
|
||||||
|
sourceSystem: "likei",
|
||||||
status: "approved",
|
status: "approved",
|
||||||
userId: "10001",
|
userId: "10001",
|
||||||
withdrawAddress: "TRX-address",
|
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: "APP" })).toBeInTheDocument();
|
||||||
|
expect(screen.getByRole("columnheader", { name: "来源单号" })).toBeInTheDocument();
|
||||||
expect(screen.getByRole("columnheader", { name: "用户ID" })).toBeInTheDocument();
|
expect(screen.getByRole("columnheader", { name: "用户ID" })).toBeInTheDocument();
|
||||||
expect(screen.getByRole("columnheader", { name: "提现金额" })).toBeInTheDocument();
|
expect(screen.getByRole("columnheader", { name: "提现金额" })).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.getByRole("columnheader", { name: "操作" })).toBeInTheDocument();
|
expect(screen.getByRole("columnheader", { name: "操作" })).toBeInTheDocument();
|
||||||
expect(screen.getByText("lalu")).toBeInTheDocument();
|
expect(screen.getByText("lalu")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("Likei")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("991001")).toBeInTheDocument();
|
||||||
expect(screen.getByText("10001")).toBeInTheDocument();
|
expect(screen.getByText("10001")).toBeInTheDocument();
|
||||||
expect(screen.getByText("$ 12.5")).toBeInTheDocument();
|
expect(screen.getByText("$ 12.5")).toBeInTheDocument();
|
||||||
expect(screen.getByText("USDT-TRC20")).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", () => {
|
test("keeps empty withdrawal table colspan aligned with visible columns", () => {
|
||||||
const { container } = renderList(baseProps);
|
const { container } = renderList(baseProps);
|
||||||
|
|
||||||
expect(container.querySelector("tbody td")?.colSpan).toBe(11);
|
expect(container.querySelector("tbody td")?.colSpan).toBe(12);
|
||||||
expect(screen.getByText("当前无数据")).toBeInTheDocument();
|
expect(screen.getByText("当前无数据")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,8 @@ export function normalizeWithdrawalApplication(item = {}) {
|
|||||||
operationsReviewerUserId: item.operationsReviewerUserId ?? item.operations_reviewer_user_id,
|
operationsReviewerUserId: item.operationsReviewerUserId ?? item.operations_reviewer_user_id,
|
||||||
operationsStatus: stringValue(item.operationsStatus ?? item.operations_status),
|
operationsStatus: stringValue(item.operationsStatus ?? item.operations_status),
|
||||||
salaryAssetType: stringValue(item.salaryAssetType ?? item.salary_asset_type),
|
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),
|
status: stringValue(item.status),
|
||||||
updatedAtMs: numberOrNull(item.updatedAtMs ?? item.updated_at_ms),
|
updatedAtMs: numberOrNull(item.updatedAtMs ?? item.updated_at_ms),
|
||||||
userId: stringValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
|
|||||||
@ -54,6 +54,7 @@ export const API_OPERATIONS = {
|
|||||||
createEmojiPack: "createEmojiPack",
|
createEmojiPack: "createEmojiPack",
|
||||||
createExploreTab: "createExploreTab",
|
createExploreTab: "createExploreTab",
|
||||||
createExternalAdminUser: "createExternalAdminUser",
|
createExternalAdminUser: "createExternalAdminUser",
|
||||||
|
createExternalWithdrawalApplication: "createExternalWithdrawalApplication",
|
||||||
createFinanceCoinSellerRechargeOrder: "createFinanceCoinSellerRechargeOrder",
|
createFinanceCoinSellerRechargeOrder: "createFinanceCoinSellerRechargeOrder",
|
||||||
createFullServerNoticeFanout: "createFullServerNoticeFanout",
|
createFullServerNoticeFanout: "createFullServerNoticeFanout",
|
||||||
createGift: "createGift",
|
createGift: "createGift",
|
||||||
@ -712,6 +713,11 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
|||||||
permission: "external-admin-user:create",
|
permission: "external-admin-user:create",
|
||||||
permissions: ["external-admin-user:create","external-admin-user:permissions"]
|
permissions: ["external-admin-user:create","external-admin-user:permissions"]
|
||||||
},
|
},
|
||||||
|
createExternalWithdrawalApplication: {
|
||||||
|
method: "POST",
|
||||||
|
operationId: API_OPERATIONS.createExternalWithdrawalApplication,
|
||||||
|
path: "/v1/integrations/withdrawal-applications"
|
||||||
|
},
|
||||||
createFinanceCoinSellerRechargeOrder: {
|
createFinanceCoinSellerRechargeOrder: {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
operationId: API_OPERATIONS.createFinanceCoinSellerRechargeOrder,
|
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;
|
patch?: never;
|
||||||
trace?: 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": {
|
"/admin/finance/withdrawal-applications": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
@ -6652,6 +6669,10 @@ export interface components {
|
|||||||
id: number;
|
id: number;
|
||||||
appCode: string;
|
appCode: string;
|
||||||
appName?: string;
|
appName?: string;
|
||||||
|
/** @description 资金执行来源;hyapp_wallet 为平台钱包,likei 为 Aslan legacy 钱包 */
|
||||||
|
sourceSystem?: string;
|
||||||
|
/** @description 来源钱包的提现申请号,用于跨系统审计和幂等回调 */
|
||||||
|
sourceApplicationId?: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
salaryAssetType?: string;
|
salaryAssetType?: string;
|
||||||
withdrawAmount: string;
|
withdrawAmount: string;
|
||||||
@ -6679,6 +6700,19 @@ export interface components {
|
|||||||
createdAtMs: number;
|
createdAtMs: number;
|
||||||
updatedAtMs?: 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: {
|
FinanceCoinSellerRechargeOrderInput: {
|
||||||
appCode: string;
|
appCode: string;
|
||||||
targetUserId: string;
|
targetUserId: string;
|
||||||
@ -11482,6 +11516,22 @@ export interface operations {
|
|||||||
200: components["responses"]["FinanceScopeCatalogResponse"];
|
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: {
|
listFinanceWithdrawalApplications: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: {
|
query?: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user