修改交互
This commit is contained in:
parent
42e9eb0804
commit
e915a16cb3
@ -520,8 +520,8 @@ export function OpsCenterApp({ can = denyPermission }) {
|
||||
<UserProfilesView
|
||||
apps={data.apps}
|
||||
defaultAppCode={defaultAppCode}
|
||||
key={profileRefreshKey}
|
||||
poolIDsByApp={poolIDsByApp}
|
||||
refreshKey={profileRefreshKey}
|
||||
/>
|
||||
</Suspense>
|
||||
) : null}
|
||||
|
||||
@ -9,6 +9,8 @@ import {
|
||||
fetchLuckyGiftDraws,
|
||||
fetchLuckyGiftConfigVersions,
|
||||
fetchLuckyGiftExperiments,
|
||||
fetchLuckyGiftUserProfile,
|
||||
fetchLuckyGiftUserProfiles,
|
||||
fetchOpsDashboard,
|
||||
rollbackLuckyGiftConfig,
|
||||
saveLuckyGiftConfig,
|
||||
@ -25,6 +27,8 @@ vi.mock("./api.js", () => ({
|
||||
fetchLuckyGiftDraws: vi.fn(),
|
||||
fetchLuckyGiftConfigVersions: vi.fn(),
|
||||
fetchLuckyGiftExperiments: vi.fn(),
|
||||
fetchLuckyGiftUserProfile: vi.fn(),
|
||||
fetchLuckyGiftUserProfiles: vi.fn(),
|
||||
fetchOpsDashboard: vi.fn(),
|
||||
luckyGiftPoolKey: (item = {}) =>
|
||||
`${item.app_code || item.appCode}:${item.pool_id || item.poolId}:${item.strategy_version || item.strategyVersion || "fixed_v2"}`,
|
||||
@ -83,6 +87,16 @@ beforeEach(() => {
|
||||
pageSize: 20,
|
||||
total: 1,
|
||||
});
|
||||
fetchLuckyGiftUserProfile.mockResolvedValue({});
|
||||
fetchLuckyGiftUserProfiles.mockResolvedValue({
|
||||
hasMore: false,
|
||||
items: [],
|
||||
nextCursor: "",
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
snapshotAtMs: 1767000000000,
|
||||
total: 0,
|
||||
});
|
||||
fetchOpsDashboard.mockResolvedValue({
|
||||
experiments: [mockRunningExperiment()],
|
||||
giftHostDiamondRatiosByApp: {
|
||||
@ -297,6 +311,34 @@ test("opens the requested config view from the legacy admin document redirect",
|
||||
expect(screen.getAllByText("lucky").length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("refreshes user profiles with the active filters instead of resetting the view", async () => {
|
||||
renderApp();
|
||||
await screen.findByText("运营应用");
|
||||
fireEvent.click(screen.getByRole("button", { name: /用户画像/ }));
|
||||
|
||||
await waitFor(() => expect(fetchLuckyGiftUserProfiles).toHaveBeenCalledTimes(1));
|
||||
fireEvent.mouseDown(screen.getByLabelText("用户来源"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "内部用户" }));
|
||||
const keywordInput = screen.getByPlaceholderText("短号 / 长号 / 靓号");
|
||||
fireEvent.change(keywordInput, { target: { value: "163001" } });
|
||||
fireEvent.click(screen.getByRole("button", { name: "查询" }));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(fetchLuckyGiftUserProfiles).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({ identityType: "internal", keyword: "163001" }),
|
||||
),
|
||||
);
|
||||
const requestCountBeforeRefresh = fetchLuckyGiftUserProfiles.mock.calls.length;
|
||||
fireEvent.click(screen.getByRole("button", { name: "刷新" }));
|
||||
|
||||
await waitFor(() => expect(fetchLuckyGiftUserProfiles).toHaveBeenCalledTimes(requestCountBeforeRefresh + 1));
|
||||
expect(fetchLuckyGiftUserProfiles).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({ identityType: "internal", keyword: "163001", page: 1 }),
|
||||
);
|
||||
expect(screen.getByLabelText("用户来源")).toHaveTextContent("内部用户");
|
||||
expect(keywordInput).toHaveValue("163001");
|
||||
});
|
||||
|
||||
test("lists every pool config including published non-default pools", async () => {
|
||||
renderApp();
|
||||
await screen.findByText("运营应用");
|
||||
|
||||
@ -44,7 +44,7 @@ const SORT_DIRECTION_OPTIONS = [
|
||||
["asc", "从低到高 / 从旧到新"],
|
||||
];
|
||||
|
||||
export function UserProfilesView({ apps, defaultAppCode, poolIDsByApp }) {
|
||||
export function UserProfilesView({ apps, defaultAppCode, poolIDsByApp, refreshKey = 0 }) {
|
||||
const [appCode, setAppCode] = useState(defaultAppCode);
|
||||
const [poolId, setPoolId] = useState("");
|
||||
const [identityType, setIdentityType] = useState("all");
|
||||
@ -58,6 +58,7 @@ export function UserProfilesView({ apps, defaultAppCode, poolIDsByApp }) {
|
||||
const [reloadKey, setReloadKey] = useState(0);
|
||||
const [expandedKey, setExpandedKey] = useState("");
|
||||
const [details, setDetails] = useState({});
|
||||
const handledRefreshKey = useRef(refreshKey);
|
||||
// 页码只负责兼容通用 DataTable 的滚动触发;真正翻页使用 owner 返回的不可解释 cursor,
|
||||
// 因此并发开奖插入新画像时不会因为 OFFSET 位移而把同一用户追加两次。
|
||||
const cursorsByPage = useRef({ 1: "" });
|
||||
@ -167,6 +168,16 @@ export function UserProfilesView({ apps, defaultAppCode, poolIDsByApp }) {
|
||||
setReloadKey((current) => current + 1);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (handledRefreshKey.current === refreshKey) {
|
||||
return;
|
||||
}
|
||||
handledRefreshKey.current = refreshKey;
|
||||
// 顶部刷新只重建游标和当前结果,筛选与已提交关键词继续由本组件状态持有,
|
||||
// 避免通过 React key 重挂载整页后把运营正在排查的条件恢复成默认值。
|
||||
reloadProfiles();
|
||||
}, [refreshKey, reloadProfiles]);
|
||||
|
||||
const changeAppCode = useCallback(
|
||||
(nextAppCode) => {
|
||||
setAppCode(nextAppCode);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user