feat: add report list page
This commit is contained in:
parent
b96fdb4f6a
commit
c22b23cb8c
@ -1471,6 +1471,18 @@
|
|||||||
"x-permissions": ["coin-ledger:view"]
|
"x-permissions": ["coin-ledger:view"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/operations/reports": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "listReports",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/components/responses/EmptyResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-permission": "report:view",
|
||||||
|
"x-permissions": ["report:view"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/payment/recharge-bills": {
|
"/admin/payment/recharge-bills": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "listRechargeBills",
|
"operationId": "listRechargeBills",
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import CardGiftcardOutlined from "@mui/icons-material/CardGiftcardOutlined";
|
|||||||
import CategoryOutlined from "@mui/icons-material/CategoryOutlined";
|
import CategoryOutlined from "@mui/icons-material/CategoryOutlined";
|
||||||
import DashboardOutlined from "@mui/icons-material/DashboardOutlined";
|
import DashboardOutlined from "@mui/icons-material/DashboardOutlined";
|
||||||
import EventAvailableOutlined from "@mui/icons-material/EventAvailableOutlined";
|
import EventAvailableOutlined from "@mui/icons-material/EventAvailableOutlined";
|
||||||
|
import FlagOutlined from "@mui/icons-material/FlagOutlined";
|
||||||
import GroupsOutlined from "@mui/icons-material/GroupsOutlined";
|
import GroupsOutlined from "@mui/icons-material/GroupsOutlined";
|
||||||
import HistoryOutlined from "@mui/icons-material/HistoryOutlined";
|
import HistoryOutlined from "@mui/icons-material/HistoryOutlined";
|
||||||
import HubOutlined from "@mui/icons-material/HubOutlined";
|
import HubOutlined from "@mui/icons-material/HubOutlined";
|
||||||
@ -44,6 +45,7 @@ const iconMap = {
|
|||||||
dashboard: DashboardOutlined,
|
dashboard: DashboardOutlined,
|
||||||
event_available: EventAvailableOutlined,
|
event_available: EventAvailableOutlined,
|
||||||
explore: MapOutlined,
|
explore: MapOutlined,
|
||||||
|
flag: FlagOutlined,
|
||||||
gift: CardGiftcardOutlined,
|
gift: CardGiftcardOutlined,
|
||||||
inventory: Inventory2Outlined,
|
inventory: Inventory2Outlined,
|
||||||
leaderboard: LeaderboardOutlined,
|
leaderboard: LeaderboardOutlined,
|
||||||
@ -144,6 +146,7 @@ export const fallbackNavigation = [
|
|||||||
children: [
|
children: [
|
||||||
routeNavItem("operation-coin-ledger", { icon: ReceiptLongOutlined }),
|
routeNavItem("operation-coin-ledger", { icon: ReceiptLongOutlined }),
|
||||||
routeNavItem("operation-coin-adjustment", { icon: WalletOutlined }),
|
routeNavItem("operation-coin-adjustment", { icon: WalletOutlined }),
|
||||||
|
routeNavItem("operation-reports", { icon: FlagOutlined }),
|
||||||
routeNavItem("lucky-gift", { icon: RedeemOutlined }),
|
routeNavItem("lucky-gift", { icon: RedeemOutlined }),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export const PERMISSIONS = {
|
|||||||
coinLedgerView: "coin-ledger:view",
|
coinLedgerView: "coin-ledger:view",
|
||||||
coinAdjustmentView: "coin-adjustment:view",
|
coinAdjustmentView: "coin-adjustment:view",
|
||||||
coinAdjustmentCreate: "coin-adjustment:create",
|
coinAdjustmentCreate: "coin-adjustment:create",
|
||||||
|
reportView: "report:view",
|
||||||
paymentBillView: "payment-bill:view",
|
paymentBillView: "payment-bill:view",
|
||||||
paymentProductView: "payment-product:view",
|
paymentProductView: "payment-product:view",
|
||||||
paymentProductCreate: "payment-product:create",
|
paymentProductCreate: "payment-product:create",
|
||||||
@ -160,6 +161,7 @@ export const MENU_CODES = {
|
|||||||
operations: "operations",
|
operations: "operations",
|
||||||
operationCoinLedger: "operation-coin-ledger",
|
operationCoinLedger: "operation-coin-ledger",
|
||||||
operationCoinAdjustment: "operation-coin-adjustment",
|
operationCoinAdjustment: "operation-coin-adjustment",
|
||||||
|
operationReports: "operation-reports",
|
||||||
luckyGift: "lucky-gift",
|
luckyGift: "lucky-gift",
|
||||||
activities: "activities",
|
activities: "activities",
|
||||||
dailyTaskList: "daily-task-list",
|
dailyTaskList: "daily-task-list",
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import type {
|
|||||||
CoinLedgerEntryDto,
|
CoinLedgerEntryDto,
|
||||||
CoinLedgerUserDto,
|
CoinLedgerUserDto,
|
||||||
PageQuery,
|
PageQuery,
|
||||||
|
ReportDto,
|
||||||
} from "@/shared/api/types";
|
} from "@/shared/api/types";
|
||||||
|
|
||||||
export function listCoinLedger(query: PageQuery = {}): Promise<ApiPage<CoinLedgerEntryDto>> {
|
export function listCoinLedger(query: PageQuery = {}): Promise<ApiPage<CoinLedgerEntryDto>> {
|
||||||
@ -26,6 +27,14 @@ export function listCoinAdjustments(query: PageQuery = {}): Promise<ApiPage<Coin
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function listReports(query: PageQuery = {}): Promise<ApiPage<ReportDto>> {
|
||||||
|
const endpoint = API_ENDPOINTS.listReports;
|
||||||
|
return apiRequest<ApiPage<ReportDto>>(apiEndpointPath(API_OPERATIONS.listReports), {
|
||||||
|
method: endpoint.method,
|
||||||
|
query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function lookupCoinAdjustmentTarget(userId: string): Promise<CoinLedgerUserDto> {
|
export function lookupCoinAdjustmentTarget(userId: string): Promise<CoinLedgerUserDto> {
|
||||||
const endpoint = API_ENDPOINTS.lookupCoinAdjustmentTarget;
|
const endpoint = API_ENDPOINTS.lookupCoinAdjustmentTarget;
|
||||||
return apiRequest<CoinLedgerUserDto>(apiEndpointPath(API_OPERATIONS.lookupCoinAdjustmentTarget), {
|
return apiRequest<CoinLedgerUserDto>(apiEndpointPath(API_OPERATIONS.lookupCoinAdjustmentTarget), {
|
||||||
|
|||||||
@ -185,6 +185,56 @@
|
|||||||
background: var(--bg-card-strong);
|
background: var(--bg-card-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reportTargetType {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 700;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reportReason {
|
||||||
|
display: -webkit-box;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.55;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reportImages {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reportImage,
|
||||||
|
.reportImageCount {
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-control);
|
||||||
|
background: var(--bg-card-strong);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reportImage img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.detailGrid {
|
.detailGrid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
260
src/features/operations/pages/ReportListPage.jsx
Normal file
260
src/features/operations/pages/ReportListPage.jsx
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
import MeetingRoomOutlined from "@mui/icons-material/MeetingRoomOutlined";
|
||||||
|
import PersonOutlineOutlined from "@mui/icons-material/PersonOutlineOutlined";
|
||||||
|
import { useMemo, useState } from "react";
|
||||||
|
import { listReports } from "@/features/operations/api";
|
||||||
|
import styles from "@/features/operations/operations.module.css";
|
||||||
|
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
|
||||||
|
import {
|
||||||
|
AdminFilterResetButton,
|
||||||
|
AdminListBody,
|
||||||
|
AdminListPage,
|
||||||
|
AdminListToolbar,
|
||||||
|
} from "@/shared/ui/AdminListLayout.jsx";
|
||||||
|
import { DataState } from "@/shared/ui/DataState.jsx";
|
||||||
|
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
||||||
|
import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx";
|
||||||
|
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
|
||||||
|
import { formatMillis } from "@/shared/utils/time.js";
|
||||||
|
|
||||||
|
const pageSize = 50;
|
||||||
|
|
||||||
|
const targetTypeOptions = [
|
||||||
|
{ label: "全部目标", value: "" },
|
||||||
|
{ label: "用户", value: "user" },
|
||||||
|
{ label: "房间", value: "room" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const reportTypeOptions = [
|
||||||
|
{ label: "全部类型", value: "" },
|
||||||
|
{ label: "政治", value: "politics" },
|
||||||
|
{ label: "色情", value: "pornography" },
|
||||||
|
{ label: "血腥暴力", value: "graphic_violence" },
|
||||||
|
{ label: "言语辱骂", value: "verbal_abuse" },
|
||||||
|
{ label: "欺诈", value: "fraud" },
|
||||||
|
{ label: "违法内容", value: "illegal_content" },
|
||||||
|
{ label: "未成年人", value: "minors" },
|
||||||
|
{ label: "线下交易", value: "in_person_transactions" },
|
||||||
|
{ label: "其他", value: "other" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
key: "targetType",
|
||||||
|
label: "举报目标",
|
||||||
|
render: (report) => <TargetTypeLabel report={report} />,
|
||||||
|
width: "minmax(120px, 0.55fr)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "target",
|
||||||
|
label: "举报信息",
|
||||||
|
render: (report) => <TargetCell report={report} />,
|
||||||
|
width: "minmax(300px, 1.3fr)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "reportType",
|
||||||
|
label: "举报类型",
|
||||||
|
render: (report) => reportTypeLabel(report.reportType),
|
||||||
|
width: "minmax(150px, 0.7fr)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "reason",
|
||||||
|
label: "举报理由",
|
||||||
|
render: (report) => <span className={styles.reportReason}>{report.reason || "-"}</span>,
|
||||||
|
width: "minmax(220px, 1fr)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "imageUrls",
|
||||||
|
label: "举报图片",
|
||||||
|
render: (report) => <EvidenceImages imageUrls={report.imageUrls} />,
|
||||||
|
width: "minmax(180px, 0.8fr)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "createdAtMs",
|
||||||
|
label: "提交时间",
|
||||||
|
render: (report) => formatMillis(report.createdAtMs),
|
||||||
|
width: "minmax(170px, 0.75fr)",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function ReportListPage() {
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [keyword, setKeyword] = useState("");
|
||||||
|
const [targetType, setTargetType] = useState("");
|
||||||
|
const [reportType, setReportType] = useState("");
|
||||||
|
const [timeRange, setTimeRange] = useState({ endMs: "", startMs: "" });
|
||||||
|
|
||||||
|
const filters = useMemo(
|
||||||
|
() => ({
|
||||||
|
end_at_ms: timeRange.endMs || "",
|
||||||
|
keyword,
|
||||||
|
report_type: reportType,
|
||||||
|
start_at_ms: timeRange.startMs || "",
|
||||||
|
target_type: targetType,
|
||||||
|
}),
|
||||||
|
[keyword, reportType, targetType, timeRange.endMs, timeRange.startMs],
|
||||||
|
);
|
||||||
|
const query = usePaginatedQuery({
|
||||||
|
errorMessage: "获取举报列表失败",
|
||||||
|
fetcher: listReports,
|
||||||
|
filters,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
queryKey: ["reports", filters, page],
|
||||||
|
});
|
||||||
|
const data = query.data || { items: [], total: 0, page, pageSize };
|
||||||
|
const items = data.items || [];
|
||||||
|
const total = data.total || 0;
|
||||||
|
|
||||||
|
const changeFilter = (setter) => (value) => {
|
||||||
|
setter(value);
|
||||||
|
setPage(1);
|
||||||
|
};
|
||||||
|
const changeTimeRange = (nextRange) => {
|
||||||
|
setTimeRange(nextRange);
|
||||||
|
setPage(1);
|
||||||
|
};
|
||||||
|
const resetFilters = () => {
|
||||||
|
setKeyword("");
|
||||||
|
setTargetType("");
|
||||||
|
setReportType("");
|
||||||
|
setTimeRange({ endMs: "", startMs: "" });
|
||||||
|
setPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableColumns = columns.map((column) => {
|
||||||
|
if (column.key === "target") {
|
||||||
|
return {
|
||||||
|
...column,
|
||||||
|
filter: createTextColumnFilter({
|
||||||
|
placeholder: "长 ID / 短 ID / 昵称",
|
||||||
|
value: keyword,
|
||||||
|
onChange: changeFilter(setKeyword),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (column.key === "targetType") {
|
||||||
|
return {
|
||||||
|
...column,
|
||||||
|
filter: createOptionsColumnFilter({
|
||||||
|
options: targetTypeOptions,
|
||||||
|
value: targetType,
|
||||||
|
onChange: changeFilter(setTargetType),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (column.key === "reportType") {
|
||||||
|
return {
|
||||||
|
...column,
|
||||||
|
filter: createOptionsColumnFilter({
|
||||||
|
options: reportTypeOptions,
|
||||||
|
value: reportType,
|
||||||
|
onChange: changeFilter(setReportType),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AdminListPage>
|
||||||
|
<AdminListToolbar
|
||||||
|
filters={
|
||||||
|
<>
|
||||||
|
<TimeRangeFilter value={timeRange} onChange={changeTimeRange} />
|
||||||
|
<AdminFilterResetButton
|
||||||
|
disabled={!keyword && !targetType && !reportType && !timeRange.startMs && !timeRange.endMs}
|
||||||
|
onClick={resetFilters}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DataState error={query.error} loading={query.loading} onRetry={query.reload}>
|
||||||
|
<AdminListBody>
|
||||||
|
<DataTable
|
||||||
|
columns={tableColumns}
|
||||||
|
items={items}
|
||||||
|
minWidth="1140px"
|
||||||
|
pagination={
|
||||||
|
total > 0
|
||||||
|
? {
|
||||||
|
page,
|
||||||
|
pageSize: data.pageSize || pageSize,
|
||||||
|
total,
|
||||||
|
onPageChange: setPage,
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
rowKey={(report) => report.reportId}
|
||||||
|
/>
|
||||||
|
</AdminListBody>
|
||||||
|
</DataState>
|
||||||
|
</AdminListPage>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TargetTypeLabel({ report }) {
|
||||||
|
const isRoom = report.targetType === "room";
|
||||||
|
return (
|
||||||
|
<span className={styles.reportTargetType}>
|
||||||
|
{isRoom ? <MeetingRoomOutlined fontSize="small" /> : <PersonOutlineOutlined fontSize="small" />}
|
||||||
|
{isRoom ? "房间" : "用户"}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TargetCell({ report }) {
|
||||||
|
const target = report.target || {};
|
||||||
|
if (report.targetType === "room") {
|
||||||
|
const room = target.room || {};
|
||||||
|
return (
|
||||||
|
<div className={styles.identity}>
|
||||||
|
<span className={styles.avatar}>
|
||||||
|
{room.coverUrl ? <img alt="" src={room.coverUrl} /> : <MeetingRoomOutlined fontSize="small" />}
|
||||||
|
</span>
|
||||||
|
<span className={styles.identityText}>
|
||||||
|
<span className={styles.primaryText}>{room.title || "-"}</span>
|
||||||
|
<span className={styles.meta}>{targetMeta(room.roomShortId, room.roomId || report.roomId)}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const user = target.user || {};
|
||||||
|
return (
|
||||||
|
<div className={styles.identity}>
|
||||||
|
<span className={styles.avatar}>
|
||||||
|
{user.avatar ? <img alt="" src={user.avatar} /> : <PersonOutlineOutlined fontSize="small" />}
|
||||||
|
</span>
|
||||||
|
<span className={styles.identityText}>
|
||||||
|
<span className={styles.primaryText}>{user.username || "-"}</span>
|
||||||
|
<span className={styles.meta}>
|
||||||
|
{targetMeta(user.displayUserId || user.defaultDisplayUserId, user.userId || report.userId)}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EvidenceImages({ imageUrls = [] }) {
|
||||||
|
const urls = Array.isArray(imageUrls) ? imageUrls.filter(Boolean) : [];
|
||||||
|
if (!urls.length) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={styles.reportImages}>
|
||||||
|
{urls.slice(0, 4).map((url) => (
|
||||||
|
<a className={styles.reportImage} href={url} key={url} rel="noreferrer" target="_blank">
|
||||||
|
<img alt="" src={url} />
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
{urls.length > 4 ? <span className={styles.reportImageCount}>+{urls.length - 4}</span> : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function targetMeta(shortId, longId) {
|
||||||
|
return `短ID ${shortId || "-"} · 长ID ${longId || "-"}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportTypeLabel(value) {
|
||||||
|
return reportTypeOptions.find((item) => item.value === value)?.label || value || "-";
|
||||||
|
}
|
||||||
@ -17,4 +17,12 @@ export const operationsRoutes = [
|
|||||||
path: "/operations/coin-adjustments",
|
path: "/operations/coin-adjustments",
|
||||||
permission: PERMISSIONS.coinAdjustmentView,
|
permission: PERMISSIONS.coinAdjustmentView,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "举报列表",
|
||||||
|
loader: () => import("./pages/ReportListPage.jsx").then((module) => module.ReportListPage),
|
||||||
|
menuCode: MENU_CODES.operationReports,
|
||||||
|
pageKey: "operation-reports",
|
||||||
|
path: "/operations/reports",
|
||||||
|
permission: PERMISSIONS.reportView,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -131,6 +131,7 @@ export const API_OPERATIONS = {
|
|||||||
listRegionBlocks: "listRegionBlocks",
|
listRegionBlocks: "listRegionBlocks",
|
||||||
listRegions: "listRegions",
|
listRegions: "listRegions",
|
||||||
listRegistrationRewardClaims: "listRegistrationRewardClaims",
|
listRegistrationRewardClaims: "listRegistrationRewardClaims",
|
||||||
|
listReports: "listReports",
|
||||||
listResourceGrants: "listResourceGrants",
|
listResourceGrants: "listResourceGrants",
|
||||||
listResourceGroups: "listResourceGroups",
|
listResourceGroups: "listResourceGroups",
|
||||||
listResources: "listResources",
|
listResources: "listResources",
|
||||||
@ -1028,6 +1029,13 @@ export const API_ENDPOINTS: Record<ApiOperationId, ApiEndpoint> = {
|
|||||||
permission: "registration-reward:view",
|
permission: "registration-reward:view",
|
||||||
permissions: ["registration-reward:view"]
|
permissions: ["registration-reward:view"]
|
||||||
},
|
},
|
||||||
|
listReports: {
|
||||||
|
method: "GET",
|
||||||
|
operationId: API_OPERATIONS.listReports,
|
||||||
|
path: "/v1/admin/operations/reports",
|
||||||
|
permission: "report:view",
|
||||||
|
permissions: ["report:view"]
|
||||||
|
},
|
||||||
listResourceGrants: {
|
listResourceGrants: {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
operationId: API_OPERATIONS.listResourceGrants,
|
operationId: API_OPERATIONS.listResourceGrants,
|
||||||
|
|||||||
28
src/shared/api/generated/schema.d.ts
vendored
28
src/shared/api/generated/schema.d.ts
vendored
@ -1012,6 +1012,22 @@ export interface paths {
|
|||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/admin/operations/reports": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get: operations["listReports"];
|
||||||
|
put?: never;
|
||||||
|
post?: never;
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/admin/payment/recharge-bills": {
|
"/admin/payment/recharge-bills": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
@ -3785,6 +3801,18 @@ export interface operations {
|
|||||||
200: components["responses"]["EmptyResponse"];
|
200: components["responses"]["EmptyResponse"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
listReports: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
200: components["responses"]["EmptyResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
listRechargeBills: {
|
listRechargeBills: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|||||||
@ -245,6 +245,43 @@ export interface CoinAdjustmentCreateDto {
|
|||||||
user: CoinLedgerUserDto;
|
user: CoinLedgerUserDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ReportUserDto {
|
||||||
|
avatar?: string;
|
||||||
|
defaultDisplayUserId?: string;
|
||||||
|
displayUserId?: string;
|
||||||
|
userId?: string;
|
||||||
|
username?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReportRoomDto {
|
||||||
|
coverUrl?: string;
|
||||||
|
roomId?: string;
|
||||||
|
roomShortId?: string;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReportTargetDto {
|
||||||
|
room?: ReportRoomDto;
|
||||||
|
type: "user" | "room" | string;
|
||||||
|
user?: ReportUserDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReportDto {
|
||||||
|
createdAtMs?: number;
|
||||||
|
imageUrls?: string[];
|
||||||
|
reason?: string;
|
||||||
|
reportId: string;
|
||||||
|
reporterUserId?: string;
|
||||||
|
reportType?: string;
|
||||||
|
requestId?: string;
|
||||||
|
roomId?: string;
|
||||||
|
status?: string;
|
||||||
|
target: ReportTargetDto;
|
||||||
|
targetType: "user" | "room" | string;
|
||||||
|
updatedAtMs?: number;
|
||||||
|
userId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RechargeBillDto {
|
export interface RechargeBillDto {
|
||||||
appCode?: string;
|
appCode?: string;
|
||||||
coinAmount: number;
|
coinAmount: number;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user