|
|
@@ -20,18 +20,15 @@ import {
|
|
|
Table,
|
|
|
Typography,
|
|
|
} from "antd";
|
|
|
-import type { ColumnsType, TablePaginationConfig } from "antd/es/table";
|
|
|
import type { Dayjs } from "dayjs";
|
|
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
import { useGlobalConsts } from "@/contexts/GlobalConstsContext";
|
|
|
import {
|
|
|
exportNewUserEngagementExcel,
|
|
|
- fetchNewUserEngagementPage,
|
|
|
fetchNewUserEngagementSummary,
|
|
|
} from "@/services/newUserEngagementReport";
|
|
|
import type {
|
|
|
NewUserEngagementMetricItemAdminDTO,
|
|
|
- NewUserEngagementReportAdminDTO,
|
|
|
NewUserEngagementReportAdminQuery,
|
|
|
NewUserEngagementReportSummaryAdminDTO,
|
|
|
} from "@/types/api/newUserEngagementReport";
|
|
|
@@ -41,28 +38,7 @@ import dayjs from "@/utils/dayjs";
|
|
|
const { RangePicker } = DatePicker;
|
|
|
const { Title, Text } = Typography;
|
|
|
|
|
|
-const PAGE_SIZE = 20;
|
|
|
-
|
|
|
-/** Build query from form values and pagination */
|
|
|
-function buildQuery(
|
|
|
- startDay: string,
|
|
|
- endDay: string,
|
|
|
- playmateKeyword?: string,
|
|
|
- userKeyword?: string,
|
|
|
- pageIndex = 1,
|
|
|
- pageSize = PAGE_SIZE,
|
|
|
-): NewUserEngagementReportAdminQuery {
|
|
|
- return {
|
|
|
- startDay,
|
|
|
- endDay,
|
|
|
- playmateKeyword: playmateKeyword?.trim() || undefined,
|
|
|
- userKeyword: userKeyword?.trim() || undefined,
|
|
|
- pageIndex,
|
|
|
- pageSize,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-/** Summary query (no pagination) for summary and export */
|
|
|
+/** Summary query for summary and export */
|
|
|
function buildSummaryQuery(
|
|
|
startDay: string,
|
|
|
endDay: string,
|
|
|
@@ -95,24 +71,16 @@ const NewUserReportPage: React.FC = () => {
|
|
|
useState<NewUserEngagementReportSummaryAdminDTO | null>(null);
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
const [exportLoading, setExportLoading] = useState(false);
|
|
|
- const [dataSource, setDataSource] = useState<
|
|
|
- NewUserEngagementReportAdminDTO[]
|
|
|
- >([]);
|
|
|
- const [total, setTotal] = useState(0);
|
|
|
- const [queryParams, setQueryParams] = useState<{
|
|
|
+ const [filterParams, setFilterParams] = useState<{
|
|
|
startDay: string;
|
|
|
endDay: string;
|
|
|
playmateKeyword?: string;
|
|
|
userKeyword?: string;
|
|
|
- pageIndex: number;
|
|
|
- pageSize: number;
|
|
|
}>(() => {
|
|
|
const last7 = getLast7DaysRange();
|
|
|
return {
|
|
|
startDay: last7.beginDateTime,
|
|
|
endDay: last7.endDateTime,
|
|
|
- pageIndex: 1,
|
|
|
- pageSize: PAGE_SIZE,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
@@ -137,47 +105,21 @@ const NewUserReportPage: React.FC = () => {
|
|
|
[message],
|
|
|
);
|
|
|
|
|
|
- const loadPage = useCallback(
|
|
|
- async (params: typeof queryParams) => {
|
|
|
+ const loadAll = useCallback(
|
|
|
+ async (params: typeof filterParams) => {
|
|
|
setLoading(true);
|
|
|
try {
|
|
|
- const res = await fetchNewUserEngagementPage(
|
|
|
- buildQuery(
|
|
|
- params.startDay,
|
|
|
- params.endDay,
|
|
|
- params.playmateKeyword,
|
|
|
- params.userKeyword,
|
|
|
- params.pageIndex,
|
|
|
- params.pageSize,
|
|
|
- ),
|
|
|
- );
|
|
|
- setDataSource(res?.items ?? []);
|
|
|
- setTotal(res?.total ?? 0);
|
|
|
- } catch (err) {
|
|
|
- console.error("Failed to load report page:", err);
|
|
|
- message.error("加载列表失败");
|
|
|
- setDataSource([]);
|
|
|
- setTotal(0);
|
|
|
- } finally {
|
|
|
- setLoading(false);
|
|
|
- }
|
|
|
- },
|
|
|
- [message],
|
|
|
- );
|
|
|
-
|
|
|
- const loadAll = useCallback(
|
|
|
- async (params: typeof queryParams) => {
|
|
|
- await Promise.all([
|
|
|
- loadSummary(
|
|
|
+ await loadSummary(
|
|
|
params.startDay,
|
|
|
params.endDay,
|
|
|
params.playmateKeyword,
|
|
|
params.userKeyword,
|
|
|
- ),
|
|
|
- loadPage(params),
|
|
|
- ]);
|
|
|
+ );
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
},
|
|
|
- [loadSummary, loadPage],
|
|
|
+ [loadSummary],
|
|
|
);
|
|
|
|
|
|
useEffect(() => {
|
|
|
@@ -190,8 +132,8 @@ const NewUserReportPage: React.FC = () => {
|
|
|
}, [form]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
- void loadAll(queryParams);
|
|
|
- }, [queryParams, loadAll]);
|
|
|
+ void loadAll(filterParams);
|
|
|
+ }, [filterParams, loadAll]);
|
|
|
|
|
|
const handleSearch = () => {
|
|
|
const values = form.getFieldsValue();
|
|
|
@@ -202,13 +144,11 @@ const NewUserReportPage: React.FC = () => {
|
|
|
}
|
|
|
const startDay = range[0].format("YYYY-MM-DD");
|
|
|
const endDay = range[1].format("YYYY-MM-DD");
|
|
|
- setQueryParams({
|
|
|
+ setFilterParams({
|
|
|
startDay,
|
|
|
endDay,
|
|
|
playmateKeyword: values.playmateKeyword,
|
|
|
userKeyword: values.userKeyword,
|
|
|
- pageIndex: 1,
|
|
|
- pageSize: queryParams.pageSize,
|
|
|
});
|
|
|
};
|
|
|
|
|
|
@@ -219,11 +159,9 @@ const NewUserReportPage: React.FC = () => {
|
|
|
playmateKeyword: "",
|
|
|
userKeyword: "",
|
|
|
});
|
|
|
- setQueryParams({
|
|
|
+ setFilterParams({
|
|
|
startDay: last7.beginDateTime,
|
|
|
endDay: last7.endDateTime,
|
|
|
- pageIndex: 1,
|
|
|
- pageSize: PAGE_SIZE,
|
|
|
});
|
|
|
};
|
|
|
|
|
|
@@ -265,51 +203,6 @@ const NewUserReportPage: React.FC = () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- const handleTableChange = (pagination: TablePaginationConfig) => {
|
|
|
- setQueryParams((prev) => ({
|
|
|
- ...prev,
|
|
|
- pageIndex: pagination.current ?? 1,
|
|
|
- pageSize: pagination.pageSize ?? PAGE_SIZE,
|
|
|
- }));
|
|
|
- };
|
|
|
-
|
|
|
- const columns: ColumnsType<NewUserEngagementReportAdminDTO> = [
|
|
|
- { title: "日期", dataIndex: "day", key: "day", width: 120 },
|
|
|
- {
|
|
|
- title: "陪玩师编号",
|
|
|
- dataIndex: "playmateUserNo",
|
|
|
- key: "playmateUserNo",
|
|
|
- width: 140,
|
|
|
- },
|
|
|
- {
|
|
|
- title: "陪玩师昵称",
|
|
|
- dataIndex: "playmateNickname",
|
|
|
- key: "playmateNickname",
|
|
|
- width: 140,
|
|
|
- },
|
|
|
- { title: "用户编号", dataIndex: "userNo", key: "userNo", width: 140 },
|
|
|
- {
|
|
|
- title: "用户昵称",
|
|
|
- dataIndex: "userNickname",
|
|
|
- key: "userNickname",
|
|
|
- width: 140,
|
|
|
- },
|
|
|
- {
|
|
|
- title: "欢迎语发送次数",
|
|
|
- dataIndex: "welcomeSendCount",
|
|
|
- key: "welcomeSendCount",
|
|
|
- width: 120,
|
|
|
- align: "right",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "首次私聊次数",
|
|
|
- dataIndex: "pushFirstChatCount",
|
|
|
- key: "pushFirstChatCount",
|
|
|
- width: 120,
|
|
|
- align: "right",
|
|
|
- },
|
|
|
- ];
|
|
|
-
|
|
|
return (
|
|
|
<div className="flex flex-col gap-6 p-6">
|
|
|
<div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
|
|
|
@@ -357,7 +250,7 @@ const NewUserReportPage: React.FC = () => {
|
|
|
</Button>
|
|
|
<Button
|
|
|
icon={<ReloadOutlined />}
|
|
|
- onClick={() => loadAll(queryParams)}
|
|
|
+ onClick={() => loadAll(filterParams)}
|
|
|
loading={loading}
|
|
|
>
|
|
|
刷新
|
|
|
@@ -492,29 +385,6 @@ const NewUserReportPage: React.FC = () => {
|
|
|
)}
|
|
|
</Card>
|
|
|
)}
|
|
|
-
|
|
|
- <Card title="明细列表" size="small" className="mt-4">
|
|
|
- <Table<NewUserEngagementReportAdminDTO>
|
|
|
- columns={columns}
|
|
|
- dataSource={dataSource}
|
|
|
- rowKey={(r, i) =>
|
|
|
- `${r.day ?? ""}-${r.playmateUserNo ?? ""}-${r.userNo ?? ""}-${i}`
|
|
|
- }
|
|
|
- loading={loading}
|
|
|
- pagination={{
|
|
|
- current: queryParams.pageIndex,
|
|
|
- pageSize: queryParams.pageSize,
|
|
|
- total,
|
|
|
- showSizeChanger: true,
|
|
|
- showTotal: (t) => `共 ${t} 条`,
|
|
|
- pageSizeOptions: ["10", "20", "50", "100"],
|
|
|
- }}
|
|
|
- onChange={handleTableChange}
|
|
|
- scroll={{ x: 900 }}
|
|
|
- size="small"
|
|
|
- bordered
|
|
|
- />
|
|
|
- </Card>
|
|
|
</Spin>
|
|
|
</div>
|
|
|
);
|