diff --git a/contracts/admin-openapi.json b/contracts/admin-openapi.json index 5222231..cf4f927 100644 --- a/contracts/admin-openapi.json +++ b/contracts/admin-openapi.json @@ -3206,6 +3206,71 @@ "x-permissions": ["coin-adjustment:create"] } }, + "/admin/operations/gift-records": { + "get": { + "operationId": "listGiftRecords", + "responses": { + "200": { + "$ref": "#/components/responses/GiftRecordPageResponse" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/Page" + }, + { + "$ref": "#/components/parameters/PageSize" + }, + { + "name": "scene", + "in": "query", + "schema": { + "type": "string", + "enum": ["room", "direct"] + } + }, + { + "name": "sender_display_user_id", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "sender_user_id", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "sender_username", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "start_at_ms", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "end_at_ms", + "in": "query", + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "x-permission": "gift-record:view", + "x-permissions": ["gift-record:view"] + } + }, "/admin/operations/coin-ledger": { "get": { "operationId": "listCoinLedger", @@ -7810,6 +7875,16 @@ } } }, + "GiftRecordPageResponse": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponseGiftRecordPage" + } + } + } + }, "BDProfilePageResponse": { "description": "OK", "content": { @@ -9289,6 +9364,27 @@ } } }, + "ApiPageGiftRecord": { + "type": "object", + "required": ["items", "page", "pageSize", "total"], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GiftRecord" + } + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, "ApiPageBDProfile": { "type": "object", "required": ["items", "page", "pageSize", "total"], @@ -9669,6 +9765,21 @@ } ] }, + "ApiResponseGiftRecordPage": { + "allOf": [ + { + "$ref": "#/components/schemas/Envelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ApiPageGiftRecord" + } + } + } + ] + }, "ApiResponseBDProfilePage": { "allOf": [ { @@ -10878,6 +10989,99 @@ } } }, + "GiftRecordUser": { + "type": "object", + "required": ["userId"], + "properties": { + "avatar": { + "type": "string" + }, + "defaultDisplayUserId": { + "type": "string" + }, + "displayUserId": { + "type": "string" + }, + "prettyDisplayUserId": { + "type": "string" + }, + "prettyId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "GiftRecordGift": { + "type": "object", + "required": ["giftId", "name", "coverUrl"], + "properties": { + "coverUrl": { + "type": "string" + }, + "giftId": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "GiftRecord": { + "type": "object", + "required": [ + "transactionId", + "scene", + "sender", + "receiver", + "gift", + "giftCount", + "unitValue", + "giftValue", + "createdAtMs" + ], + "properties": { + "createdAtMs": { + "type": "integer", + "format": "int64" + }, + "gift": { + "$ref": "#/components/schemas/GiftRecordGift" + }, + "giftCount": { + "type": "integer", + "format": "int32" + }, + "giftValue": { + "type": "integer", + "format": "int64" + }, + "receiver": { + "$ref": "#/components/schemas/GiftRecordUser" + }, + "roomId": { + "type": "string" + }, + "scene": { + "type": "string", + "enum": ["room", "direct"] + }, + "sender": { + "$ref": "#/components/schemas/GiftRecordUser" + }, + "transactionId": { + "type": "string" + }, + "unitValue": { + "type": "integer", + "format": "int64" + } + } + }, "CoinLedgerUser": { "type": "object", "required": ["userId"], diff --git a/src/app/navigation/menu.js b/src/app/navigation/menu.js index b2ad44b..c4429b4 100644 --- a/src/app/navigation/menu.js +++ b/src/app/navigation/menu.js @@ -186,6 +186,7 @@ export const fallbackNavigation = [ id: "operations", label: "运营管理", children: [ + routeNavItem("operation-gift-records", { icon: CardGiftcardOutlined }), routeNavItem("operation-coin-ledger", { icon: ReceiptLongOutlined }), routeNavItem("operation-coin-seller-ledger", { icon: ReceiptLongOutlined }), routeNavItem("operation-coin-adjustment", { icon: WalletOutlined }), diff --git a/src/app/permissions.ts b/src/app/permissions.ts index 7e4f8c3..f77cdc4 100644 --- a/src/app/permissions.ts +++ b/src/app/permissions.ts @@ -57,6 +57,7 @@ export const PERMISSIONS = { financeOrderCoinSellerRechargeGrant: "finance-order:coin-seller-recharge:grant", coinLedgerView: "coin-ledger:view", coinSellerLedgerView: "coin-seller-ledger:view", + giftRecordView: "gift-record:view", coinAdjustmentView: "coin-adjustment:view", coinAdjustmentCreate: "coin-adjustment:create", reportView: "report:view", @@ -250,6 +251,7 @@ export const MENU_CODES = { operations: "operations", operationCoinLedger: "operation-coin-ledger", operationCoinSellerLedger: "operation-coin-seller-ledger", + operationGiftRecords: "operation-gift-records", operationCoinAdjustment: "operation-coin-adjustment", operationReports: "operation-reports", operationGiftDiamond: "operation-gift-diamond", diff --git a/src/features/games/api.ts b/src/features/games/api.ts index 2003562..bd75dbf 100644 --- a/src/features/games/api.ts +++ b/src/features/games/api.ts @@ -8,7 +8,7 @@ export interface GamePlatformDto { platformName: string; status: string; apiBaseUrl: string; - // 服务端按 adapterType 选择真实厂商协议:yomi_v4/leadercc_v1/zeeone_v1/baishun_v1/vivagames_v1/reyou_v1。 + // 服务端按 adapterType 选择真实厂商协议;AMG 使用 amg_v1,RSA 私钥仍通过 callbackSecret 单独提交。 adapterType: string; // callbackSecret 由后台列表返回,用于配置页直接核对和轮换厂商 key。 callbackSecret?: string; diff --git a/src/features/games/hooks/useGamesPage.js b/src/features/games/hooks/useGamesPage.js index 1082bfc..a4419aa 100644 --- a/src/features/games/hooks/useGamesPage.js +++ b/src/features/games/hooks/useGamesPage.js @@ -65,6 +65,7 @@ const writableBridgeAdapterTypes = new Set([ "vivagames_v1", "reyou_v1", "zgame_v1", + "amg_v1", ]); const emptyCatalog = { items: [], pageSize: 50 }; diff --git a/src/features/games/pages/GameListPage.jsx b/src/features/games/pages/GameListPage.jsx index 21f64f5..68699e1 100644 --- a/src/features/games/pages/GameListPage.jsx +++ b/src/features/games/pages/GameListPage.jsx @@ -54,6 +54,7 @@ const adapterTypeOptions = [ ["vivagames_v1", "VIVAGAMES V1"], ["reyou_v1", "热游 Reyou V1"], ["zgame_v1", "ZGame V1"], + ["amg_v1", "AMG V1"], ]; const baseColumns = [ diff --git a/src/features/operations/api.test.ts b/src/features/operations/api.test.ts index c481214..c3be323 100644 --- a/src/features/operations/api.test.ts +++ b/src/features/operations/api.test.ts @@ -9,6 +9,7 @@ import { listCoinLedger, listCoinAdjustments, listCoinSellerLedger, + listGiftRecords, listWheelDraws, lookupCoinAdjustmentTarget, updateGiftDiamondRatios, @@ -110,6 +111,36 @@ test("coin ledger API sends type filter", async () => { expect(listInit?.method).toBe("GET"); }); +test("gift record API uses generated path with sender, scene and UTC range filters", async () => { + vi.stubGlobal( + "fetch", + vi.fn( + async () => new Response(JSON.stringify({ code: 0, data: { items: [], page: 1, pageSize: 30, total: 0 } })), + ), + ); + + await listGiftRecords({ + end_at_ms: 2000, + page: 1, + page_size: 30, + scene: "room", + sender_display_user_id: "888888", + sender_user_id: "1001", + sender_username: "送礼人", + start_at_ms: 1000, + }); + + const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0]; + expect(String(listUrl)).toContain("/api/v1/admin/operations/gift-records?"); + expect(String(listUrl)).toContain("scene=room"); + expect(String(listUrl)).toContain("sender_display_user_id=888888"); + expect(String(listUrl)).toContain("sender_user_id=1001"); + expect(String(listUrl)).toContain("sender_username=%E9%80%81%E7%A4%BC%E4%BA%BA"); + expect(String(listUrl)).toContain("start_at_ms=1000"); + expect(String(listUrl)).toContain("end_at_ms=2000"); + expect(listInit?.method).toBe("GET"); +}); + test("coin seller ledger API uses generated admin path and filters", async () => { vi.stubGlobal( "fetch", diff --git a/src/features/operations/api.ts b/src/features/operations/api.ts index d9f9f8a..9e42631 100644 --- a/src/features/operations/api.ts +++ b/src/features/operations/api.ts @@ -22,6 +22,33 @@ export interface GiftDiamondRatioItem { updatedAtMs?: number; } +export interface GiftRecordUserDto { + userId: string; + displayUserId?: string; + defaultDisplayUserId?: string; + prettyDisplayUserId?: string; + prettyId?: string; + username?: string; + avatar?: string; +} + +export interface GiftRecordDto { + transactionId: string; + scene: "room" | "direct"; + roomId?: string; + sender: GiftRecordUserDto; + receiver: GiftRecordUserDto; + gift: { + giftId: string; + name: string; + coverUrl?: string; + }; + giftCount: number; + unitValue: number; + giftValue: number; + createdAtMs: number; +} + export interface GiftDiamondRatioResponse { regionId: number; items: GiftDiamondRatioItem[]; @@ -132,6 +159,14 @@ export function listCoinLedger(query: PageQuery = {}): Promise> { + const endpoint = API_ENDPOINTS.listGiftRecords; + return apiRequest>(apiEndpointPath(API_OPERATIONS.listGiftRecords), { + method: endpoint.method, + query, + }); +} + export function listCoinSellerLedger(query: PageQuery = {}): Promise> { const endpoint = API_ENDPOINTS.listCoinSellerLedger; return apiRequest>(apiEndpointPath(API_OPERATIONS.listCoinSellerLedger), { diff --git a/src/features/operations/components/GiftRecordTable.jsx b/src/features/operations/components/GiftRecordTable.jsx new file mode 100644 index 0000000..a1c3343 --- /dev/null +++ b/src/features/operations/components/GiftRecordTable.jsx @@ -0,0 +1,220 @@ +import CardGiftcardOutlined from "@mui/icons-material/CardGiftcardOutlined"; +import { useMemo, useState } from "react"; +import { listGiftRecords } from "@/features/operations/api"; +import styles from "@/features/operations/operations.module.css"; +import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js"; +import { AdminFilterResetButton, AdminListBody, AdminListToolbar } from "@/shared/ui/AdminListLayout.jsx"; +import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx"; +import { DataState } from "@/shared/ui/DataState.jsx"; +import { DataTable } from "@/shared/ui/DataTable.jsx"; +import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx"; +import { TimeText } from "@/shared/ui/TimeText.jsx"; +import { createOptionsColumnFilter, createUserIdentityColumnFilter } from "@/shared/ui/tableFilters.js"; +import { + emptyUserIdentityFilter, + isUserIdentityFilterEmpty, + userIdentityFilterParams, +} from "@/shared/ui/userIdentityFilter.js"; + +const pageSize = 30; + +const sceneOptions = [ + { label: "房间送礼", value: "room" }, + { label: "私聊送礼", value: "direct" }, +]; + +export function GiftRecordTable() { + const [page, setPage] = useState(1); + const [scene, setScene] = useState(""); + const [senderFilter, setSenderFilter] = useState(emptyUserIdentityFilter); + const [timeRange, setTimeRange] = useState({ endMs: "", startMs: "" }); + const filters = useMemo( + () => ({ + end_at_ms: timeRange.endMs || "", + scene, + ...userIdentityFilterParams(senderFilter, { + displayUserId: "sender_display_user_id", + userId: "sender_user_id", + username: "sender_username", + }), + start_at_ms: timeRange.startMs || "", + }), + [scene, senderFilter, timeRange.endMs, timeRange.startMs], + ); + const query = usePaginatedQuery({ + errorMessage: "获取送礼记录失败", + fetcher: listGiftRecords, + filters, + page, + pageSize, + queryKey: ["gift-records", filters, page], + }); + const data = query.data || { items: [], page, pageSize, total: 0 }; + const items = data.items || []; + const total = data.total || 0; + const hasActiveFilters = Boolean( + !isUserIdentityFilterEmpty(senderFilter) || scene || timeRange.startMs || timeRange.endMs, + ); + + const changeScene = (value) => { + setScene(value); + setPage(1); + }; + const changeSenderFilter = (value) => { + setSenderFilter(value); + setPage(1); + }; + const changeTimeRange = (value) => { + setTimeRange(value); + setPage(1); + }; + const resetFilters = () => { + setScene(""); + setSenderFilter(emptyUserIdentityFilter); + setTimeRange({ endMs: "", startMs: "" }); + setPage(1); + }; + + const columns = useMemo( + () => [ + { + key: "index", + label: "序号", + render: (_entry, index) => {index + 1}, + resizable: false, + width: "72px", + }, + { + filter: createUserIdentityColumnFilter({ + value: senderFilter, + onChange: changeSenderFilter, + }), + key: "sender", + label: "送礼人", + render: (entry) => , + width: "minmax(210px, 1fr)", + }, + { + key: "receiver", + label: "收礼人", + render: (entry) => , + width: "minmax(210px, 1fr)", + }, + { + key: "gift", + label: "礼物", + render: (entry) => , + width: "minmax(220px, 1fr)", + }, + { + key: "giftValue", + label: "数量与价值", + render: (entry) => , + width: "minmax(190px, 0.9fr)", + }, + { + filter: createOptionsColumnFilter({ + emptyLabel: "全部场景", + options: sceneOptions, + placeholder: "送礼场景", + value: scene, + onChange: changeScene, + }), + key: "scene", + label: "场景", + render: (entry) => , + width: "minmax(132px, 0.7fr)", + }, + { + key: "createdAtMs", + label: "送礼时间", + render: (entry) => , + width: "minmax(170px, 0.8fr)", + }, + ], + [scene, senderFilter], + ); + + return ( +
+ + + + + } + /> + + + 0 + ? { + page, + pageSize: data.pageSize || pageSize, + total, + onPageChange: setPage, + } + : undefined + } + rowKey={(entry) => entry.transactionId} + /> + + +
+ ); +} + +function GiftCell({ gift = {} }) { + return ( +
+ + {gift.coverUrl ? : } + + + {gift.name || "-"} + {gift.giftId ? {gift.giftId} : null} + +
+ ); +} + +function GiftValueCell({ entry }) { + return ( +
+ + 数量 + × {formatNumber(entry.giftCount)} + + + 单价 + {formatNumber(entry.unitValue)} + + + 总价值 + {formatNumber(entry.giftValue)} + +
+ ); +} + +function SceneCell({ entry }) { + const direct = entry.scene === "direct"; + return ( + + + {direct ? "私聊" : "房间"} + + {!direct && entry.roomId ? {entry.roomId} : null} + + ); +} + +function formatNumber(value) { + return Number(value || 0).toLocaleString("zh-CN"); +} diff --git a/src/features/operations/components/GiftRecordTable.test.jsx b/src/features/operations/components/GiftRecordTable.test.jsx new file mode 100644 index 0000000..c917fb6 --- /dev/null +++ b/src/features/operations/components/GiftRecordTable.test.jsx @@ -0,0 +1,69 @@ +import { fireEvent, render, screen } from "@testing-library/react"; +import { afterEach, expect, test, vi } from "vitest"; +import { GiftRecordTable } from "@/features/operations/components/GiftRecordTable.jsx"; +import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js"; + +vi.mock("@/shared/hooks/usePaginatedQuery.js", () => ({ + usePaginatedQuery: vi.fn(), +})); + +afterEach(() => { + vi.clearAllMocks(); +}); + +test("gift record table uses public user identities and keeps gift facts compact", () => { + vi.mocked(usePaginatedQuery).mockReturnValue({ + data: { + items: [ + { + createdAtMs: 1770000000000, + gift: { coverUrl: "https://cdn.example/rose.webp", giftId: "rose", name: "玫瑰" }, + giftCount: 3, + giftValue: 300, + receiver: { displayUserId: "202", userId: "2002", username: "收礼人" }, + roomId: "room-9", + scene: "room", + sender: { + defaultDisplayUserId: "101", + displayUserId: "888888", + prettyDisplayUserId: "888888", + prettyId: "pretty-1", + userId: "1001", + username: "送礼人", + }, + transactionId: "wallet-gift-1", + unitValue: 100, + }, + ], + page: 1, + pageSize: 30, + total: 1, + }, + error: null, + loading: false, + reload: vi.fn(), + }); + + render(); + + expect(screen.getByText("1")).toBeInTheDocument(); + expect(screen.getAllByText("送礼人").length).toBeGreaterThanOrEqual(2); + expect(screen.getAllByText("收礼人").length).toBeGreaterThanOrEqual(2); + expect(screen.getByText("玫瑰")).toBeInTheDocument(); + expect(screen.getByText("× 3")).toBeInTheDocument(); + expect(screen.getByText("300")).toBeInTheDocument(); + expect(screen.getByText("房间")).toBeInTheDocument(); + expect(screen.getByText("room-9")).toBeInTheDocument(); + expect(screen.getByText("已加载 1 条 · 共 1 条")).toBeInTheDocument(); + + fireEvent.click(screen.getByRole("button", { name: "送礼人" })); + fireEvent.change(screen.getByPlaceholderText("输入短 ID"), { target: { value: "888888" } }); + fireEvent.click(screen.getByRole("button", { name: "搜索" })); + + expect(usePaginatedQuery).toHaveBeenLastCalledWith( + expect.objectContaining({ + filters: expect.objectContaining({ sender_display_user_id: "888888" }), + page: 1, + }), + ); +}); diff --git a/src/features/operations/operations.module.css b/src/features/operations/operations.module.css index 1bcf017..5685528 100644 --- a/src/features/operations/operations.module.css +++ b/src/features/operations/operations.module.css @@ -36,6 +36,140 @@ overflow: auto; } +.giftRecordIndex { + color: var(--text-tertiary); + font-variant-numeric: tabular-nums; + font-weight: 750; +} + +.giftRecordGift { + display: flex; + min-width: 0; + align-items: center; + gap: var(--space-3); +} + +.giftRecordCover { + display: inline-flex; + width: 48px; + height: 48px; + flex: 0 0 auto; + align-items: center; + justify-content: center; + overflow: hidden; + border: 1px solid var(--border-soft); + border-radius: 14px; + background: linear-gradient(145deg, var(--bg-card-strong), var(--primary-hover)); + color: var(--primary); +} + +.giftRecordCover img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.giftRecordGiftText, +.giftRecordScene { + display: grid; + min-width: 0; + gap: 4px; +} + +.giftRecordGiftName { + overflow: hidden; + color: var(--text-primary); + font-weight: 780; + text-overflow: ellipsis; + white-space: nowrap; +} + +.giftRecordGiftId, +.giftRecordRoomId { + overflow: hidden; + color: var(--text-tertiary); + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.giftRecordMetrics { + display: grid; + min-width: 0; + grid-template-columns: repeat(3, minmax(0, auto)); + align-items: center; + gap: var(--space-3); +} + +.giftRecordMetric { + display: grid; + min-width: 0; + gap: 3px; +} + +.giftRecordMetric span { + color: var(--text-tertiary); + font-size: 11px; + white-space: nowrap; +} + +.giftRecordMetric strong { + color: var(--text-primary); + font-size: var(--admin-font-size); + font-variant-numeric: tabular-nums; + font-weight: 760; + white-space: nowrap; +} + +.giftRecordTotal { + padding-left: var(--space-3); + border-left: 1px solid var(--border-soft); +} + +.giftRecordTotal strong { + color: var(--primary); +} + +.giftRecordSceneBadge { + display: inline-flex; + width: max-content; + min-height: 24px; + align-items: center; + padding: 0 9px; + border: 1px solid transparent; + border-radius: 999px; + font-size: 12px; + font-weight: 760; +} + +.giftRecordSceneRoom { + border-color: var(--primary-border); + background: var(--primary-hover); + color: var(--primary); +} + +.giftRecordSceneDirect { + border-color: rgba(124, 58, 237, 0.2); + background: rgba(124, 58, 237, 0.08); + color: #7c3aed; +} + +@media (prefers-reduced-motion: no-preference) { + .giftRecordCover, + .giftRecordSceneBadge { + transition: + border-color 160ms ease, + box-shadow 160ms ease, + transform 160ms ease; + } + + .giftRecordGift:hover .giftRecordCover { + border-color: var(--primary-border-strong); + box-shadow: 0 8px 18px rgba(37, 99, 235, 0.1); + transform: translateY(-1px); + } +} + .adjustmentAmount { font-size: calc(var(--admin-font-size) + 4px); } diff --git a/src/features/operations/pages/GiftRecordPage.jsx b/src/features/operations/pages/GiftRecordPage.jsx new file mode 100644 index 0000000..e689d0a --- /dev/null +++ b/src/features/operations/pages/GiftRecordPage.jsx @@ -0,0 +1,10 @@ +import { GiftRecordTable } from "@/features/operations/components/GiftRecordTable.jsx"; +import { AdminListPage } from "@/shared/ui/AdminListLayout.jsx"; + +export function GiftRecordPage() { + return ( + + + + ); +} diff --git a/src/features/operations/routes.js b/src/features/operations/routes.js index 3d3c8b4..19c7d8d 100644 --- a/src/features/operations/routes.js +++ b/src/features/operations/routes.js @@ -1,6 +1,14 @@ import { MENU_CODES, PERMISSIONS } from "@/app/permissions"; export const operationsRoutes = [ + { + label: "送礼记录", + loader: () => import("./pages/GiftRecordPage.jsx").then((module) => module.GiftRecordPage), + menuCode: MENU_CODES.operationGiftRecords, + pageKey: "operation-gift-records", + path: "/operations/gift-records", + permission: PERMISSIONS.giftRecordView, + }, { label: "金币流水", loader: () => import("./pages/CoinLedgerPage.jsx").then((module) => module.CoinLedgerPage), diff --git a/src/shared/api/generated/endpoints.ts b/src/shared/api/generated/endpoints.ts index a17b388..dc61526 100644 --- a/src/shared/api/generated/endpoints.ts +++ b/src/shared/api/generated/endpoints.ts @@ -203,6 +203,7 @@ export const API_OPERATIONS = { listFinanceWithdrawalApplications: "listFinanceWithdrawalApplications", listFirstRechargeRewardClaims: "listFirstRechargeRewardClaims", listGameWhitelistUsers: "listGameWhitelistUsers", + listGiftRecords: "listGiftRecords", listGifts: "listGifts", listGiftTypes: "listGiftTypes", listH5Links: "listH5Links", @@ -1710,6 +1711,13 @@ export const API_ENDPOINTS: Record = { permission: "game:view", permissions: ["game:view"] }, + listGiftRecords: { + method: "GET", + operationId: API_OPERATIONS.listGiftRecords, + path: "/v1/admin/operations/gift-records", + permission: "gift-record:view", + permissions: ["gift-record:view"] + }, listGifts: { method: "GET", operationId: API_OPERATIONS.listGifts, diff --git a/src/shared/api/generated/schema.d.ts b/src/shared/api/generated/schema.d.ts index cfafa7d..4457815 100644 --- a/src/shared/api/generated/schema.d.ts +++ b/src/shared/api/generated/schema.d.ts @@ -2060,6 +2060,22 @@ export interface paths { patch?: never; trace?: never; }; + "/admin/operations/gift-records": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["listGiftRecords"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/admin/operations/coin-ledger": { parameters: { query?: never; @@ -4887,6 +4903,12 @@ export interface components { pageSize: number; total: number; }; + ApiPageGiftRecord: { + items: components["schemas"]["GiftRecord"][]; + page: number; + pageSize: number; + total: number; + }; ApiPageBDProfile: { items: components["schemas"]["BDProfile"][]; page: number; @@ -5043,6 +5065,9 @@ export interface components { ApiResponseCoinSellerLedgerPage: components["schemas"]["Envelope"] & { data?: components["schemas"]["ApiPageCoinSellerLedger"]; }; + ApiResponseGiftRecordPage: components["schemas"]["Envelope"] & { + data?: components["schemas"]["ApiPageGiftRecord"]; + }; ApiResponseBDProfilePage: components["schemas"]["Envelope"] & { data?: components["schemas"]["ApiPageBDProfile"]; }; @@ -5403,6 +5428,37 @@ export interface components { child?: components["schemas"]["CoinSellerSubApplicationReviewChild"]; relation?: components["schemas"]["CoinSellerSubRelation"]; }; + GiftRecordUser: { + avatar?: string; + defaultDisplayUserId?: string; + displayUserId?: string; + prettyDisplayUserId?: string; + prettyId?: string; + userId: string; + username?: string; + }; + GiftRecordGift: { + coverUrl: string; + giftId: string; + name: string; + }; + GiftRecord: { + /** Format: int64 */ + createdAtMs: number; + gift: components["schemas"]["GiftRecordGift"]; + /** Format: int32 */ + giftCount: number; + /** Format: int64 */ + giftValue: number; + receiver: components["schemas"]["GiftRecordUser"]; + roomId?: string; + /** @enum {string} */ + scene: "room" | "direct"; + sender: components["schemas"]["GiftRecordUser"]; + transactionId: string; + /** Format: int64 */ + unitValue: number; + }; CoinLedgerUser: { avatar?: string; displayUserId?: string; @@ -6147,6 +6203,15 @@ export interface components { }; }; /** @description OK */ + GiftRecordPageResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ApiResponseGiftRecordPage"]; + }; + }; + /** @description OK */ BDProfilePageResponse: { headers: { [name: string]: unknown; @@ -9193,6 +9258,27 @@ export interface operations { 200: components["responses"]["EmptyResponse"]; }; }; + listGiftRecords: { + parameters: { + query?: { + page?: components["parameters"]["Page"]; + page_size?: components["parameters"]["PageSize"]; + scene?: "room" | "direct"; + sender_display_user_id?: string; + sender_user_id?: string; + sender_username?: string; + start_at_ms?: number; + end_at_ms?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["GiftRecordPageResponse"]; + }; + }; listCoinLedger: { parameters: { query?: {