财务模块
This commit is contained in:
parent
7025ae9e30
commit
88eae83dbe
@ -2825,6 +2825,103 @@
|
|||||||
"x-permissions": ["payment-bill:view"]
|
"x-permissions": ["payment-bill:view"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/payment/recharge-bills/summary": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getRechargeBillSummary",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "keyword",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "recharge_type",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "status",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "region_id",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "start_at_ms",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "end_at_ms",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/components/responses/EmptyResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-permission": "payment-bill:view",
|
||||||
|
"x-permissions": ["payment-bill:view"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/payment/recharge-bills/google-paid/refresh": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "refreshGoogleRechargePaid",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"transactionIds": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["transactionIds"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/components/responses/EmptyResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-permission": "payment-bill:view",
|
||||||
|
"x-permissions": ["payment-bill:view"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/payment/recharge-regions": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "listRechargeRegions",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/components/responses/EmptyResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-permission": "payment-bill:view",
|
||||||
|
"x-permissions": ["payment-bill:view"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/payment/recharge-products": {
|
"/admin/payment/recharge-products": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "listRechargeProducts",
|
"operationId": "listRechargeProducts",
|
||||||
|
|||||||
@ -7,12 +7,15 @@ import {
|
|||||||
approveFinanceWithdrawalApplication,
|
approveFinanceWithdrawalApplication,
|
||||||
createFinanceApplication,
|
createFinanceApplication,
|
||||||
fetchFinanceApplicationOptions,
|
fetchFinanceApplicationOptions,
|
||||||
|
fetchFinanceRechargeSummary,
|
||||||
fetchFinanceSession,
|
fetchFinanceSession,
|
||||||
filterOperationsByPermissions,
|
filterOperationsByPermissions,
|
||||||
listFinanceApplications,
|
listFinanceApplications,
|
||||||
listFinanceRechargeDetails,
|
listFinanceRechargeDetails,
|
||||||
|
listFinanceRechargeRegions,
|
||||||
listMyFinanceApplications,
|
listMyFinanceApplications,
|
||||||
listFinanceWithdrawalApplications,
|
listFinanceWithdrawalApplications,
|
||||||
|
refreshFinanceGoogleRechargePaid,
|
||||||
rejectFinanceApplication,
|
rejectFinanceApplication,
|
||||||
rejectFinanceWithdrawalApplication
|
rejectFinanceWithdrawalApplication
|
||||||
} from "./api.js";
|
} from "./api.js";
|
||||||
@ -24,7 +27,7 @@ import { FinanceRechargeDetailList } from "./components/FinanceRechargeDetailLis
|
|||||||
import { FinanceShell } from "./components/FinanceShell.jsx";
|
import { FinanceShell } from "./components/FinanceShell.jsx";
|
||||||
import { FinanceWithdrawalApplicationList } from "./components/FinanceWithdrawalApplicationList.jsx";
|
import { FinanceWithdrawalApplicationList } from "./components/FinanceWithdrawalApplicationList.jsx";
|
||||||
import { DEFAULT_APPLICATION_FORM } from "./constants.js";
|
import { DEFAULT_APPLICATION_FORM } from "./constants.js";
|
||||||
import { buildApplicationPayload, validateApplicationPayload } from "./format.js";
|
import { EMPTY_RECHARGE_SUMMARY, buildApplicationPayload, validateApplicationPayload } from "./format.js";
|
||||||
import { useToast } from "@/shared/ui/ToastProvider.jsx";
|
import { useToast } from "@/shared/ui/ToastProvider.jsx";
|
||||||
|
|
||||||
const emptyOptions = { apps: [], operations: [], walletIdentities: [] };
|
const emptyOptions = { apps: [], operations: [], walletIdentities: [] };
|
||||||
@ -35,11 +38,14 @@ export function FinanceApp() {
|
|||||||
const [sessionState, setSessionState] = useState({ error: "", loading: true, session: null });
|
const [sessionState, setSessionState] = useState({ error: "", loading: true, session: null });
|
||||||
const [optionsState, setOptionsState] = useState({ data: emptyOptions, error: "", loading: false });
|
const [optionsState, setOptionsState] = useState({ data: emptyOptions, error: "", loading: false });
|
||||||
const [rechargeDetailsState, setRechargeDetailsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
const [rechargeDetailsState, setRechargeDetailsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
||||||
|
const [rechargeSummaryState, setRechargeSummaryState] = useState({ data: EMPTY_RECHARGE_SUMMARY, error: "", loading: false });
|
||||||
|
const [rechargeRegionsState, setRechargeRegionsState] = useState({ appCode: "", items: [], loading: false });
|
||||||
|
const [googlePaidRefreshing, setGooglePaidRefreshing] = useState(false);
|
||||||
const [myApplicationsState, setMyApplicationsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
const [myApplicationsState, setMyApplicationsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
||||||
const [applicationsState, setApplicationsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
const [applicationsState, setApplicationsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
||||||
const [withdrawalsState, setWithdrawalsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
const [withdrawalsState, setWithdrawalsState] = useState({ data: { items: [], page: 1, pageSize, total: 0 }, error: "", loading: false });
|
||||||
const [activeView, setActiveView] = useState("create");
|
const [activeView, setActiveView] = useState("create");
|
||||||
const [rechargeDetailFilters, setRechargeDetailFilters] = useState({ appCode: "", keyword: "", page: 1, timeRange: { endMs: "", startMs: "" } });
|
const [rechargeDetailFilters, setRechargeDetailFilters] = useState({ appCode: "", keyword: "", page: 1, regionId: "", timeRange: { endMs: "", startMs: "" } });
|
||||||
const [myFilters, setMyFilters] = useState({ appCode: "", keyword: "", operation: "", page: 1, status: "" });
|
const [myFilters, setMyFilters] = useState({ appCode: "", keyword: "", operation: "", page: 1, status: "" });
|
||||||
const [filters, setFilters] = useState({ appCode: "", keyword: "", operation: "", page: 1, status: "pending" });
|
const [filters, setFilters] = useState({ appCode: "", keyword: "", operation: "", page: 1, status: "pending" });
|
||||||
const [withdrawalFilters, setWithdrawalFilters] = useState({ appCode: "", keyword: "", page: 1 });
|
const [withdrawalFilters, setWithdrawalFilters] = useState({ appCode: "", keyword: "", page: 1 });
|
||||||
@ -88,6 +94,7 @@ export function FinanceApp() {
|
|||||||
keyword: rechargeDetailFilters.keyword,
|
keyword: rechargeDetailFilters.keyword,
|
||||||
page: rechargeDetailFilters.page,
|
page: rechargeDetailFilters.page,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
|
region_id: rechargeDetailFilters.appCode ? rechargeDetailFilters.regionId : "",
|
||||||
start_at_ms: rechargeDetailFilters.timeRange.startMs,
|
start_at_ms: rechargeDetailFilters.timeRange.startMs,
|
||||||
stat_tz: "Asia/Shanghai",
|
stat_tz: "Asia/Shanghai",
|
||||||
status: "succeeded"
|
status: "succeeded"
|
||||||
@ -165,6 +172,58 @@ export function FinanceApp() {
|
|||||||
}
|
}
|
||||||
}, [optionsState.data.apps, rechargeDetailQuery, session?.canViewAppRechargeDetails]);
|
}, [optionsState.data.apps, rechargeDetailQuery, session?.canViewAppRechargeDetails]);
|
||||||
|
|
||||||
|
const loadRechargeSummary = useCallback(async () => {
|
||||||
|
if (!session?.canViewAppRechargeDetails) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRechargeSummaryState((current) => ({ ...current, error: "", loading: true }));
|
||||||
|
try {
|
||||||
|
const data = await fetchFinanceRechargeSummary(rechargeDetailQuery, optionsState.data.apps);
|
||||||
|
setRechargeSummaryState({ data, error: "", loading: false });
|
||||||
|
} catch (err) {
|
||||||
|
setRechargeSummaryState((current) => ({ ...current, error: err.message || "加载充值汇总失败", loading: false }));
|
||||||
|
}
|
||||||
|
}, [optionsState.data.apps, rechargeDetailQuery, session?.canViewAppRechargeDetails]);
|
||||||
|
|
||||||
|
const rechargeAppCode = rechargeDetailFilters.appCode;
|
||||||
|
const loadRechargeRegions = useCallback(async () => {
|
||||||
|
if (!session?.canViewAppRechargeDetails || !rechargeAppCode) {
|
||||||
|
setRechargeRegionsState({ appCode: "", items: [], loading: false });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRechargeRegionsState((current) => ({ ...current, appCode: rechargeAppCode, loading: true }));
|
||||||
|
try {
|
||||||
|
const items = await listFinanceRechargeRegions(rechargeAppCode);
|
||||||
|
setRechargeRegionsState({ appCode: rechargeAppCode, items, loading: false });
|
||||||
|
} catch {
|
||||||
|
setRechargeRegionsState({ appCode: rechargeAppCode, items: [], loading: false });
|
||||||
|
}
|
||||||
|
}, [rechargeAppCode, session?.canViewAppRechargeDetails]);
|
||||||
|
|
||||||
|
const refreshGooglePaid = useCallback(
|
||||||
|
async (transactionIds) => {
|
||||||
|
if (!rechargeAppCode || !transactionIds?.length || googlePaidRefreshing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setGooglePaidRefreshing(true);
|
||||||
|
try {
|
||||||
|
const results = await refreshFinanceGoogleRechargePaid(rechargeAppCode, transactionIds);
|
||||||
|
const failed = results.filter((item) => item.error).length;
|
||||||
|
const succeeded = results.length - failed;
|
||||||
|
showToast(
|
||||||
|
failed ? `谷歌实付同步完成:成功 ${succeeded} 笔,失败 ${failed} 笔` : `谷歌实付同步完成:${succeeded} 笔`,
|
||||||
|
failed ? "warning" : "success"
|
||||||
|
);
|
||||||
|
await loadRechargeDetails();
|
||||||
|
} catch (err) {
|
||||||
|
showToast(err.message || "查询谷歌实付失败", "error");
|
||||||
|
} finally {
|
||||||
|
setGooglePaidRefreshing(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[googlePaidRefreshing, loadRechargeDetails, rechargeAppCode, showToast]
|
||||||
|
);
|
||||||
|
|
||||||
const loadApplications = useCallback(async () => {
|
const loadApplications = useCallback(async () => {
|
||||||
if (!session?.canAuditApplication) {
|
if (!session?.canAuditApplication) {
|
||||||
return;
|
return;
|
||||||
@ -203,6 +262,14 @@ export function FinanceApp() {
|
|||||||
loadRechargeDetails();
|
loadRechargeDetails();
|
||||||
}, [loadRechargeDetails]);
|
}, [loadRechargeDetails]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadRechargeSummary();
|
||||||
|
}, [loadRechargeSummary]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadRechargeRegions();
|
||||||
|
}, [loadRechargeRegions]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadApplications();
|
loadApplications();
|
||||||
}, [loadApplications]);
|
}, [loadApplications]);
|
||||||
@ -330,6 +397,7 @@ export function FinanceApp() {
|
|||||||
onRefresh={() => {
|
onRefresh={() => {
|
||||||
loadOptions();
|
loadOptions();
|
||||||
loadRechargeDetails();
|
loadRechargeDetails();
|
||||||
|
loadRechargeSummary();
|
||||||
loadMyApplications();
|
loadMyApplications();
|
||||||
loadApplications();
|
loadApplications();
|
||||||
loadWithdrawals();
|
loadWithdrawals();
|
||||||
@ -341,10 +409,18 @@ export function FinanceApp() {
|
|||||||
bills={rechargeDetailsState.data}
|
bills={rechargeDetailsState.data}
|
||||||
error={rechargeDetailsState.error}
|
error={rechargeDetailsState.error}
|
||||||
filters={rechargeDetailFilters}
|
filters={rechargeDetailFilters}
|
||||||
|
googlePaidRefreshing={googlePaidRefreshing}
|
||||||
loading={rechargeDetailsState.loading}
|
loading={rechargeDetailsState.loading}
|
||||||
options={optionsState.data}
|
options={optionsState.data}
|
||||||
|
regions={rechargeRegionsState.items}
|
||||||
|
summary={rechargeSummaryState.data}
|
||||||
|
summaryLoading={rechargeSummaryState.loading}
|
||||||
onFiltersChange={updateRechargeDetailFilters}
|
onFiltersChange={updateRechargeDetailFilters}
|
||||||
onReload={loadRechargeDetails}
|
onRefreshGooglePaid={refreshGooglePaid}
|
||||||
|
onReload={() => {
|
||||||
|
loadRechargeDetails();
|
||||||
|
loadRechargeSummary();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
) : activeView === "applications" && session.canAuditApplication ? (
|
) : activeView === "applications" && session.canAuditApplication ? (
|
||||||
<FinanceApplicationList
|
<FinanceApplicationList
|
||||||
|
|||||||
@ -2,7 +2,14 @@ import { getMe, refreshSession } from "@/features/auth/api";
|
|||||||
import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints";
|
import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints";
|
||||||
import { apiRequest, getAccessToken } from "@/shared/api/request";
|
import { apiRequest, getAccessToken } from "@/shared/api/request";
|
||||||
import { FINANCE_OPERATIONS, FINANCE_PERMISSIONS, WALLET_IDENTITIES } from "./constants.js";
|
import { FINANCE_OPERATIONS, FINANCE_PERMISSIONS, WALLET_IDENTITIES } from "./constants.js";
|
||||||
import { normalizeApplicationPage, normalizeRechargeBillPage, normalizeWithdrawalApplicationPage } from "./format.js";
|
import {
|
||||||
|
mergeRechargeSummaries,
|
||||||
|
normalizeApplicationPage,
|
||||||
|
normalizeRechargeBillPage,
|
||||||
|
normalizeRechargeRegions,
|
||||||
|
normalizeRechargeSummary,
|
||||||
|
normalizeWithdrawalApplicationPage
|
||||||
|
} from "./format.js";
|
||||||
|
|
||||||
const appCodeHeader = "X-App-Code";
|
const appCodeHeader = "X-App-Code";
|
||||||
|
|
||||||
@ -96,6 +103,41 @@ export async function listFinanceRechargeDetails(query = {}, apps = []) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchFinanceRechargeSummary(query = {}, apps = []) {
|
||||||
|
const selectedAppCode = stringValue(query.app_code ?? query.appCode);
|
||||||
|
const cleanQuery = cleanRechargeBillQuery(query);
|
||||||
|
|
||||||
|
if (selectedAppCode) {
|
||||||
|
return getRechargeSummaryForApp(selectedAppCode, cleanQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
const appCodes = normalizeApps(apps).map((app) => app.appCode);
|
||||||
|
if (!appCodes.length) {
|
||||||
|
return mergeRechargeSummaries([]);
|
||||||
|
}
|
||||||
|
const summaries = await Promise.all(appCodes.map((appCode) => getRechargeSummaryForApp(appCode, cleanQuery)));
|
||||||
|
return mergeRechargeSummaries(summaries);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listFinanceRechargeRegions(appCode) {
|
||||||
|
const endpoint = API_ENDPOINTS.listRechargeRegions;
|
||||||
|
const data = await apiRequest(apiEndpointPath(API_OPERATIONS.listRechargeRegions), {
|
||||||
|
headers: { [appCodeHeader]: appCode },
|
||||||
|
method: endpoint.method
|
||||||
|
});
|
||||||
|
return normalizeRechargeRegions(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function refreshFinanceGoogleRechargePaid(appCode, transactionIds) {
|
||||||
|
const endpoint = API_ENDPOINTS.refreshGoogleRechargePaid;
|
||||||
|
const data = await apiRequest(apiEndpointPath(API_OPERATIONS.refreshGoogleRechargePaid), {
|
||||||
|
body: { transactionIds },
|
||||||
|
headers: { [appCodeHeader]: appCode },
|
||||||
|
method: endpoint.method
|
||||||
|
});
|
||||||
|
return Array.isArray(data?.items) ? data.items : [];
|
||||||
|
}
|
||||||
|
|
||||||
export async function createFinanceApplication(payload) {
|
export async function createFinanceApplication(payload) {
|
||||||
const endpoint = API_ENDPOINTS.createFinanceApplication;
|
const endpoint = API_ENDPOINTS.createFinanceApplication;
|
||||||
return apiRequest(apiEndpointPath(API_OPERATIONS.createFinanceApplication), {
|
return apiRequest(apiEndpointPath(API_OPERATIONS.createFinanceApplication), {
|
||||||
@ -152,6 +194,16 @@ async function currentSession() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getRechargeSummaryForApp(appCode, query = {}) {
|
||||||
|
const endpoint = API_ENDPOINTS.getRechargeBillSummary;
|
||||||
|
const data = await apiRequest(apiEndpointPath(API_OPERATIONS.getRechargeBillSummary), {
|
||||||
|
headers: { [appCodeHeader]: appCode },
|
||||||
|
method: endpoint.method,
|
||||||
|
query
|
||||||
|
});
|
||||||
|
return normalizeRechargeSummary(data);
|
||||||
|
}
|
||||||
|
|
||||||
async function listRechargeBillsForApp(appCode, query = {}) {
|
async function listRechargeBillsForApp(appCode, query = {}) {
|
||||||
const endpoint = API_ENDPOINTS.listRechargeBills;
|
const endpoint = API_ENDPOINTS.listRechargeBills;
|
||||||
const data = await apiRequest(apiEndpointPath(API_OPERATIONS.listRechargeBills), {
|
const data = await apiRequest(apiEndpointPath(API_OPERATIONS.listRechargeBills), {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import CloudSyncOutlined from "@mui/icons-material/CloudSyncOutlined";
|
||||||
import RefreshOutlined from "@mui/icons-material/RefreshOutlined";
|
import RefreshOutlined from "@mui/icons-material/RefreshOutlined";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
@ -10,29 +11,48 @@ import TableRow from "@mui/material/TableRow";
|
|||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx";
|
import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx";
|
||||||
import {
|
import {
|
||||||
|
EMPTY_RECHARGE_SUMMARY,
|
||||||
formatAmount,
|
formatAmount,
|
||||||
formatMicroMoney,
|
formatMicroMoney,
|
||||||
formatTime,
|
formatTime,
|
||||||
formatUsdMinor,
|
formatUsdMinor,
|
||||||
formatPercent,
|
|
||||||
rechargeTypeLabel,
|
rechargeTypeLabel,
|
||||||
} from "../format.js";
|
} from "../format.js";
|
||||||
|
|
||||||
export function FinanceRechargeDetailList({ bills, error, filters, loading, onFiltersChange, onReload, options }) {
|
export function FinanceRechargeDetailList({
|
||||||
|
bills,
|
||||||
|
error,
|
||||||
|
filters,
|
||||||
|
googlePaidRefreshing,
|
||||||
|
loading,
|
||||||
|
onFiltersChange,
|
||||||
|
onRefreshGooglePaid,
|
||||||
|
onReload,
|
||||||
|
options,
|
||||||
|
regions,
|
||||||
|
summary,
|
||||||
|
summaryLoading,
|
||||||
|
}) {
|
||||||
const items = bills.items || [];
|
const items = bills.items || [];
|
||||||
const page = Number(bills.page || filters.page || 1);
|
const page = Number(bills.page || filters.page || 1);
|
||||||
const pageSize = Number(bills.pageSize || 50);
|
const pageSize = Number(bills.pageSize || 50);
|
||||||
const total = Number(bills.total || 0);
|
const total = Number(bills.total || 0);
|
||||||
const hasNextPage = page * pageSize < total;
|
const hasNextPage = page * pageSize < total;
|
||||||
|
const regionOptions = regions || [];
|
||||||
|
const pendingGoogleTxIds = items
|
||||||
|
.filter((item) => item.rechargeType === "google_play_recharge" && !item.paidSyncedAtMs)
|
||||||
|
.map((item) => item.transactionId)
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="finance-panel finance-list">
|
<section className="finance-panel finance-list">
|
||||||
|
<RechargeSummaryCards loading={summaryLoading} summary={summary} />
|
||||||
<div className="finance-toolbar finance-toolbar--recharge-details">
|
<div className="finance-toolbar finance-toolbar--recharge-details">
|
||||||
<TextField
|
<TextField
|
||||||
label="APP"
|
label="APP"
|
||||||
select
|
select
|
||||||
value={filters.appCode}
|
value={filters.appCode}
|
||||||
onChange={(event) => onFiltersChange({ appCode: event.target.value })}
|
onChange={(event) => onFiltersChange({ appCode: event.target.value, regionId: "" })}
|
||||||
>
|
>
|
||||||
<MenuItem value="">全部 APP</MenuItem>
|
<MenuItem value="">全部 APP</MenuItem>
|
||||||
{options.apps.map((app) => (
|
{options.apps.map((app) => (
|
||||||
@ -41,6 +61,21 @@ export function FinanceRechargeDetailList({ bills, error, filters, loading, onFi
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</TextField>
|
</TextField>
|
||||||
|
<TextField
|
||||||
|
disabled={!filters.appCode}
|
||||||
|
helperText={filters.appCode ? "" : "先选择 APP"}
|
||||||
|
label="区域"
|
||||||
|
select
|
||||||
|
value={filters.regionId}
|
||||||
|
onChange={(event) => onFiltersChange({ regionId: event.target.value })}
|
||||||
|
>
|
||||||
|
<MenuItem value="">全部区域</MenuItem>
|
||||||
|
{regionOptions.map((region) => (
|
||||||
|
<MenuItem key={region.regionId} value={String(region.regionId)}>
|
||||||
|
{region.name || region.regionCode || region.regionId}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
<TimeRangeFilter
|
<TimeRangeFilter
|
||||||
label="充值时间 · 中国时区"
|
label="充值时间 · 中国时区"
|
||||||
value={filters.timeRange}
|
value={filters.timeRange}
|
||||||
@ -51,6 +86,15 @@ export function FinanceRechargeDetailList({ bills, error, filters, loading, onFi
|
|||||||
value={filters.keyword}
|
value={filters.keyword}
|
||||||
onChange={(event) => onFiltersChange({ keyword: event.target.value })}
|
onChange={(event) => onFiltersChange({ keyword: event.target.value })}
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
disabled={googlePaidRefreshing || !filters.appCode || !pendingGoogleTxIds.length}
|
||||||
|
startIcon={<CloudSyncOutlined fontSize="small" />}
|
||||||
|
title={filters.appCode ? "查询本页谷歌订单的用户实付币种和金额" : "先选择 APP 后可查询"}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => onRefreshGooglePaid(pendingGoogleTxIds)}
|
||||||
|
>
|
||||||
|
{googlePaidRefreshing ? "查询中…" : "查询谷歌实付"}
|
||||||
|
</Button>
|
||||||
<Button startIcon={<RefreshOutlined fontSize="small" />} variant="outlined" onClick={onReload}>
|
<Button startIcon={<RefreshOutlined fontSize="small" />} variant="outlined" onClick={onReload}>
|
||||||
刷新列表
|
刷新列表
|
||||||
</Button>
|
</Button>
|
||||||
@ -131,6 +175,32 @@ export function FinanceRechargeDetailList({ bills, error, filters, loading, onFi
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function RechargeSummaryCards({ loading, summary }) {
|
||||||
|
const data = summary || EMPTY_RECHARGE_SUMMARY;
|
||||||
|
const cards = [
|
||||||
|
{ bucket: data.total, key: "total", label: "充值总和" },
|
||||||
|
{ bucket: data.thirdParty, key: "thirdParty", label: "三方充值" },
|
||||||
|
{ bucket: data.googlePlay, key: "googlePlay", label: "谷歌充值" },
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div className="finance-summary-grid">
|
||||||
|
{cards.map(({ bucket, key, label }) => (
|
||||||
|
<div className="finance-summary-card" key={key}>
|
||||||
|
<span className="finance-summary-card__label">{label}</span>
|
||||||
|
<strong className="finance-summary-card__value">
|
||||||
|
{loading ? "…" : formatUsdMinor(bucket.usdMinorAmount, "USD")}
|
||||||
|
</strong>
|
||||||
|
<small>
|
||||||
|
{loading
|
||||||
|
? "统计中"
|
||||||
|
: `${formatAmount(bucket.billCount)} 笔 · ${formatAmount(bucket.coinAmount)} 金币`}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Stacked({ primary, secondary }) {
|
function Stacked({ primary, secondary }) {
|
||||||
return (
|
return (
|
||||||
<span className="finance-stack">
|
<span className="finance-stack">
|
||||||
@ -176,27 +246,58 @@ function userPaidText(item) {
|
|||||||
if (item.userPaidText) {
|
if (item.userPaidText) {
|
||||||
return item.userPaidText;
|
return item.userPaidText;
|
||||||
}
|
}
|
||||||
if (hasNumber(item.userPaidAmountMinor)) {
|
if (hasPositiveNumber(item.userPaidAmountMicro) && item.userPaidCurrencyCode) {
|
||||||
return formatUsdMinor(item.userPaidAmountMinor, item.currencyCode || "USD");
|
return formatMicroMoney(item.userPaidAmountMicro, item.userPaidCurrencyCode);
|
||||||
}
|
}
|
||||||
if (hasNumber(item.providerAmountMinor)) {
|
if (isGoogleBill(item) && !item.paidSyncedAtMs) {
|
||||||
return formatUsdMinor(item.providerAmountMinor, item.currencyCode || "USD");
|
return "未同步(点“查询谷歌实付”)";
|
||||||
}
|
}
|
||||||
if (hasNumber(item.userPaidAmountMicro)) {
|
if (hasPositiveNumber(item.userPaidAmountMinor)) {
|
||||||
return formatMicroMoney(item.userPaidAmountMicro, item.currencyCode || "USD");
|
return formatUsdMinor(item.userPaidAmountMinor, item.userPaidCurrencyCode || item.currencyCode || "USD");
|
||||||
}
|
}
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
function taxDeductionText(item) {
|
function taxDeductionText(item) {
|
||||||
const rate = formatPercent(item.taxRate);
|
const currency = item.userPaidCurrencyCode || item.currencyCode || "USD";
|
||||||
const amount =
|
const fee = hasPositiveNumber(item.providerFeeMicro) ? item.providerFeeMicro : 0;
|
||||||
item.taxDeductionText ||
|
const tax = hasPositiveNumber(item.providerTaxMicro) ? item.providerTaxMicro : 0;
|
||||||
(hasNumber(item.taxDeductionMinor) ? formatUsdMinor(item.taxDeductionMinor, item.currencyCode || "USD") : "");
|
const deduction = fee + tax;
|
||||||
if (amount && rate) {
|
if (deduction > 0) {
|
||||||
return `${amount} / ${rate}`;
|
const parts = [formatMicroMoney(deduction, currency)];
|
||||||
|
if (hasPositiveNumber(item.userPaidAmountMicro)) {
|
||||||
|
const percent = (deduction / item.userPaidAmountMicro) * 100;
|
||||||
|
parts.push(`${percent.toLocaleString("zh-CN", { maximumFractionDigits: 2 })}%`);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span className="finance-stack">
|
||||||
|
<span>{parts.join(" / ")}</span>
|
||||||
|
<small>{deductionBreakdown(fee, tax, currency)}</small>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return amount || rate || "-";
|
if (item.taxDeductionText) {
|
||||||
|
return item.taxDeductionText;
|
||||||
|
}
|
||||||
|
if (isGoogleBill(item) && !item.paidSyncedAtMs) {
|
||||||
|
return "未同步";
|
||||||
|
}
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
function deductionBreakdown(fee, tax, currency) {
|
||||||
|
const parts = [];
|
||||||
|
if (fee > 0) {
|
||||||
|
parts.push(`手续费 ${formatMicroMoney(fee, currency)}`);
|
||||||
|
}
|
||||||
|
if (tax > 0) {
|
||||||
|
parts.push(`税费 ${formatMicroMoney(tax, currency)}`);
|
||||||
|
}
|
||||||
|
return parts.join(" + ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isGoogleBill(item) {
|
||||||
|
return item.rechargeType === "google_play_recharge" || item.providerCode === "google_play";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasNumber(value) {
|
function hasNumber(value) {
|
||||||
@ -205,3 +306,7 @@ function hasNumber(value) {
|
|||||||
}
|
}
|
||||||
return Number.isFinite(Number(value));
|
return Number.isFinite(Number(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasPositiveNumber(value) {
|
||||||
|
return hasNumber(value) && Number(value) > 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -138,7 +138,12 @@ export function normalizeRechargeBill(item = {}) {
|
|||||||
exchangeUsdMinorAmount: numberValue(item.exchangeUsdMinorAmount ?? item.exchange_usd_minor_amount),
|
exchangeUsdMinorAmount: numberValue(item.exchangeUsdMinorAmount ?? item.exchange_usd_minor_amount),
|
||||||
externalRef: stringValue(item.externalRef ?? item.external_ref),
|
externalRef: stringValue(item.externalRef ?? item.external_ref),
|
||||||
id: stringValue(item.id ?? item.transactionId ?? item.transaction_id),
|
id: stringValue(item.id ?? item.transactionId ?? item.transaction_id),
|
||||||
|
paidSyncedAtMs: numberOrNull(item.paidSyncedAtMs ?? item.paid_synced_at_ms),
|
||||||
providerAmountMinor: numberOrNull(item.providerAmountMinor ?? item.provider_amount_minor),
|
providerAmountMinor: numberOrNull(item.providerAmountMinor ?? item.provider_amount_minor),
|
||||||
|
providerCode: stringValue(item.providerCode ?? item.provider_code),
|
||||||
|
providerFeeMicro: numberOrNull(item.providerFeeMicro ?? item.provider_fee_micro),
|
||||||
|
providerNetMicro: numberOrNull(item.providerNetMicro ?? item.provider_net_micro),
|
||||||
|
providerTaxMicro: numberOrNull(item.providerTaxMicro ?? item.provider_tax_micro),
|
||||||
rechargeType: stringValue(item.rechargeType ?? item.recharge_type),
|
rechargeType: stringValue(item.rechargeType ?? item.recharge_type),
|
||||||
status: stringValue(item.status),
|
status: stringValue(item.status),
|
||||||
taxDeductionMinor: numberOrNull(
|
taxDeductionMinor: numberOrNull(
|
||||||
@ -167,6 +172,7 @@ export function normalizeRechargeBill(item = {}) {
|
|||||||
item.providerAmountMinor ??
|
item.providerAmountMinor ??
|
||||||
item.provider_amount_minor,
|
item.provider_amount_minor,
|
||||||
),
|
),
|
||||||
|
userPaidCurrencyCode: stringValue(item.userPaidCurrencyCode ?? item.user_paid_currency_code),
|
||||||
userPaidText: stringValue(
|
userPaidText: stringValue(
|
||||||
item.userPaidText ??
|
item.userPaidText ??
|
||||||
item.user_paid_text ??
|
item.user_paid_text ??
|
||||||
@ -188,6 +194,61 @@ export function normalizeRechargeBillPage(data = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EMPTY_RECHARGE_SUMMARY_BUCKET = { billCount: 0, coinAmount: 0, usdMinorAmount: 0 };
|
||||||
|
|
||||||
|
export const EMPTY_RECHARGE_SUMMARY = {
|
||||||
|
googlePlay: EMPTY_RECHARGE_SUMMARY_BUCKET,
|
||||||
|
thirdParty: EMPTY_RECHARGE_SUMMARY_BUCKET,
|
||||||
|
total: EMPTY_RECHARGE_SUMMARY_BUCKET,
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalizeRechargeSummaryBucket(bucket = {}) {
|
||||||
|
return {
|
||||||
|
billCount: numberValue(bucket.billCount ?? bucket.bill_count) || 0,
|
||||||
|
coinAmount: numberValue(bucket.coinAmount ?? bucket.coin_amount) || 0,
|
||||||
|
usdMinorAmount: numberValue(bucket.usdMinorAmount ?? bucket.usd_minor_amount) || 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeRechargeSummary(data = {}) {
|
||||||
|
return {
|
||||||
|
googlePlay: normalizeRechargeSummaryBucket(data.googlePlay ?? data.google_play),
|
||||||
|
thirdParty: normalizeRechargeSummaryBucket(data.thirdParty ?? data.third_party),
|
||||||
|
total: normalizeRechargeSummaryBucket(data.total),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mergeRechargeSummaries(summaries = []) {
|
||||||
|
const merged = normalizeRechargeSummary({});
|
||||||
|
for (const summary of summaries) {
|
||||||
|
for (const key of ["googlePlay", "thirdParty", "total"]) {
|
||||||
|
merged[key] = {
|
||||||
|
billCount: merged[key].billCount + summary[key].billCount,
|
||||||
|
coinAmount: merged[key].coinAmount + summary[key].coinAmount,
|
||||||
|
usdMinorAmount: merged[key].usdMinorAmount + summary[key].usdMinorAmount,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeRechargeRegions(data = {}) {
|
||||||
|
const items = Array.isArray(data.items) ? data.items : Array.isArray(data) ? data : [];
|
||||||
|
return items
|
||||||
|
.map((item) => {
|
||||||
|
const regionId = numberOrNull(item.regionId ?? item.region_id);
|
||||||
|
if (!regionId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: stringValue(item.name),
|
||||||
|
regionCode: stringValue(item.regionCode ?? item.region_code),
|
||||||
|
regionId,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
export function operationLabel(value, operations = FINANCE_OPERATIONS) {
|
export function operationLabel(value, operations = FINANCE_OPERATIONS) {
|
||||||
return operations.find((item) => item.value === value)?.label || value || "-";
|
return operations.find((item) => item.value === value)?.label || value || "-";
|
||||||
}
|
}
|
||||||
@ -199,6 +260,15 @@ export function rechargeTypeLabel(value) {
|
|||||||
if (value === "google_play_recharge") {
|
if (value === "google_play_recharge") {
|
||||||
return "谷歌充值";
|
return "谷歌充值";
|
||||||
}
|
}
|
||||||
|
if (value === "mifapay") {
|
||||||
|
return "三方充值 · MiFaPay";
|
||||||
|
}
|
||||||
|
if (value === "v5pay") {
|
||||||
|
return "三方充值 · V5Pay";
|
||||||
|
}
|
||||||
|
if (value === "usdt_trc20") {
|
||||||
|
return "三方充值 · USDT";
|
||||||
|
}
|
||||||
return value || "-";
|
return value || "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -173,7 +173,36 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.finance-toolbar--recharge-details {
|
.finance-toolbar--recharge-details {
|
||||||
grid-template-columns: minmax(170px, 1fr) minmax(280px, 1.35fr) minmax(180px, 1fr) auto;
|
grid-template-columns: minmax(150px, 1fr) minmax(130px, 0.85fr) minmax(250px, 1.3fr) minmax(160px, 1fr) auto auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finance-summary-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(200px, 1fr));
|
||||||
|
gap: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.finance-summary-card {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-control);
|
||||||
|
background: var(--bg-card-strong);
|
||||||
|
padding: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.finance-summary-card__label {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finance-summary-card__value {
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finance-summary-card small {
|
||||||
|
color: var(--text-tertiary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.finance-error {
|
.finance-error {
|
||||||
@ -411,7 +440,8 @@ a {
|
|||||||
|
|
||||||
.finance-form-grid,
|
.finance-form-grid,
|
||||||
.finance-evidence-grid,
|
.finance-evidence-grid,
|
||||||
.finance-toolbar {
|
.finance-toolbar,
|
||||||
|
.finance-summary-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,6 +120,7 @@ export const API_OPERATIONS = {
|
|||||||
getInviteActivityRewardConfig: "getInviteActivityRewardConfig",
|
getInviteActivityRewardConfig: "getInviteActivityRewardConfig",
|
||||||
getLuckyGiftConfig: "getLuckyGiftConfig",
|
getLuckyGiftConfig: "getLuckyGiftConfig",
|
||||||
getLuckyGiftDrawSummary: "getLuckyGiftDrawSummary",
|
getLuckyGiftDrawSummary: "getLuckyGiftDrawSummary",
|
||||||
|
getRechargeBillSummary: "getRechargeBillSummary",
|
||||||
getRedPacket: "getRedPacket",
|
getRedPacket: "getRedPacket",
|
||||||
getRedPacketConfig: "getRedPacketConfig",
|
getRedPacketConfig: "getRedPacketConfig",
|
||||||
getRegion: "getRegion",
|
getRegion: "getRegion",
|
||||||
@ -193,6 +194,7 @@ export const API_OPERATIONS = {
|
|||||||
listPrettyIds: "listPrettyIds",
|
listPrettyIds: "listPrettyIds",
|
||||||
listRechargeBills: "listRechargeBills",
|
listRechargeBills: "listRechargeBills",
|
||||||
listRechargeProducts: "listRechargeProducts",
|
listRechargeProducts: "listRechargeProducts",
|
||||||
|
listRechargeRegions: "listRechargeRegions",
|
||||||
listRedPackets: "listRedPackets",
|
listRedPackets: "listRedPackets",
|
||||||
listRegionBlocks: "listRegionBlocks",
|
listRegionBlocks: "listRegionBlocks",
|
||||||
listRegions: "listRegions",
|
listRegions: "listRegions",
|
||||||
@ -235,6 +237,7 @@ export const API_OPERATIONS = {
|
|||||||
publishHostAgencyPolicy: "publishHostAgencyPolicy",
|
publishHostAgencyPolicy: "publishHostAgencyPolicy",
|
||||||
recyclePrettyId: "recyclePrettyId",
|
recyclePrettyId: "recyclePrettyId",
|
||||||
refresh: "refresh",
|
refresh: "refresh",
|
||||||
|
refreshGoogleRechargePaid: "refreshGoogleRechargePaid",
|
||||||
rejectFinanceApplication: "rejectFinanceApplication",
|
rejectFinanceApplication: "rejectFinanceApplication",
|
||||||
rejectFinanceWithdrawalApplication: "rejectFinanceWithdrawalApplication",
|
rejectFinanceWithdrawalApplication: "rejectFinanceWithdrawalApplication",
|
||||||
replaceCoinSellerSalaryRates: "replaceCoinSellerSalaryRates",
|
replaceCoinSellerSalaryRates: "replaceCoinSellerSalaryRates",
|
||||||
@ -1078,6 +1081,13 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
|||||||
permission: "lucky-gift:view",
|
permission: "lucky-gift:view",
|
||||||
permissions: ["lucky-gift:view"]
|
permissions: ["lucky-gift:view"]
|
||||||
},
|
},
|
||||||
|
getRechargeBillSummary: {
|
||||||
|
method: "GET",
|
||||||
|
operationId: API_OPERATIONS.getRechargeBillSummary,
|
||||||
|
path: "/v1/admin/payment/recharge-bills/summary",
|
||||||
|
permission: "payment-bill:view",
|
||||||
|
permissions: ["payment-bill:view"]
|
||||||
|
},
|
||||||
getRedPacket: {
|
getRedPacket: {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
operationId: API_OPERATIONS.getRedPacket,
|
operationId: API_OPERATIONS.getRedPacket,
|
||||||
@ -1587,6 +1597,13 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
|||||||
permission: "payment-product:view",
|
permission: "payment-product:view",
|
||||||
permissions: ["payment-product:view"]
|
permissions: ["payment-product:view"]
|
||||||
},
|
},
|
||||||
|
listRechargeRegions: {
|
||||||
|
method: "GET",
|
||||||
|
operationId: API_OPERATIONS.listRechargeRegions,
|
||||||
|
path: "/v1/admin/payment/recharge-regions",
|
||||||
|
permission: "payment-bill:view",
|
||||||
|
permissions: ["payment-bill:view"]
|
||||||
|
},
|
||||||
listRedPackets: {
|
listRedPackets: {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
operationId: API_OPERATIONS.listRedPackets,
|
operationId: API_OPERATIONS.listRedPackets,
|
||||||
@ -1871,6 +1888,13 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
|||||||
operationId: API_OPERATIONS.refresh,
|
operationId: API_OPERATIONS.refresh,
|
||||||
path: "/v1/auth/refresh"
|
path: "/v1/auth/refresh"
|
||||||
},
|
},
|
||||||
|
refreshGoogleRechargePaid: {
|
||||||
|
method: "POST",
|
||||||
|
operationId: API_OPERATIONS.refreshGoogleRechargePaid,
|
||||||
|
path: "/v1/admin/payment/recharge-bills/google-paid/refresh",
|
||||||
|
permission: "payment-bill:view",
|
||||||
|
permissions: ["payment-bill:view"]
|
||||||
|
},
|
||||||
rejectFinanceApplication: {
|
rejectFinanceApplication: {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
operationId: API_OPERATIONS.rejectFinanceApplication,
|
operationId: API_OPERATIONS.rejectFinanceApplication,
|
||||||
|
|||||||
97
src/shared/api/generated/schema.d.ts
vendored
97
src/shared/api/generated/schema.d.ts
vendored
@ -1876,6 +1876,54 @@ export interface paths {
|
|||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/admin/payment/recharge-bills/summary": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get: operations["getRechargeBillSummary"];
|
||||||
|
put?: never;
|
||||||
|
post?: never;
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
|
"/admin/payment/recharge-bills/google-paid/refresh": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["refreshGoogleRechargePaid"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
|
"/admin/payment/recharge-regions": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get: operations["listRechargeRegions"];
|
||||||
|
put?: never;
|
||||||
|
post?: never;
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/admin/payment/recharge-products": {
|
"/admin/payment/recharge-products": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
@ -6735,6 +6783,55 @@ export interface operations {
|
|||||||
200: components["responses"]["RechargeBillPageResponse"];
|
200: components["responses"]["RechargeBillPageResponse"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
getRechargeBillSummary: {
|
||||||
|
parameters: {
|
||||||
|
query?: {
|
||||||
|
keyword?: string;
|
||||||
|
recharge_type?: string;
|
||||||
|
status?: string;
|
||||||
|
region_id?: number;
|
||||||
|
start_at_ms?: number;
|
||||||
|
end_at_ms?: number;
|
||||||
|
};
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
200: components["responses"]["EmptyResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
refreshGoogleRechargePaid: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
transactionIds: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
200: components["responses"]["EmptyResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
listRechargeRegions: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
200: components["responses"]["EmptyResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
listRechargeProducts: {
|
listRechargeProducts: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user