From ffad461d67cf1b9ef938ec358cd67e722db99f6a Mon Sep 17 00:00:00 2001 From: zzhyyyyy <2685922758@qq.com> Date: Tue, 7 Jul 2026 17:09:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(marquee):=20=E9=A2=84=E8=A7=88=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E3=80=8C=E6=8C=89=E6=A8=A1=E5=BC=8F=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=85=A8=E9=83=A8=E5=8F=AF=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在原内联预览基础上,把「换一批」随机预览改为分页浏览: - 上一页/下一页翻遍当前模式下 app 能露出的全部记录(不去重),不再只随机抽一批。 - 跟随数据源模式:只真实=真实记录、只种子=各种子生成、混播=真实+种子;切模式回第 1 页。 - 种子行标「种子」、真实行标 u{id};配套 app-server /marquee-seeds/real-records 接口。 Co-Authored-By: Claude Opus 4.8 --- src/app/(main)/config/HomeMarqueeSeeds.tsx | 86 ++++++++++++++-------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/src/app/(main)/config/HomeMarqueeSeeds.tsx b/src/app/(main)/config/HomeMarqueeSeeds.tsx index 9155240..9f54e0c 100644 --- a/src/app/(main)/config/HomeMarqueeSeeds.tsx +++ b/src/app/(main)/config/HomeMarqueeSeeds.tsx @@ -42,10 +42,11 @@ interface BulkVals { enabled: boolean; } -interface PreviewItem { +interface RealRecord { masked_user: string; saved_amount_cents: number; - time: string; + created_at: string; + user_id: number; } const yuan = (cents: number) => (cents / 100).toFixed(2); @@ -67,8 +68,12 @@ export default function HomeMarqueeSeeds() { const [bulkOpen, setBulkOpen] = useState(false); const [bulkForm] = Form.useForm(); - const [previewItems, setPreviewItems] = useState([]); - const [previewLoading, setPreviewLoading] = useState(false); + // 「可展示的真实记录」分页浏览(替代原随机预览):翻遍所有 success+省>0 的真实记录 + const REC_PAGE_SIZE = 8; + const [recItems, setRecItems] = useState([]); + const [recTotal, setRecTotal] = useState(0); + const [recPage, setRecPage] = useState(0); // 0-based + const [recLoading, setRecLoading] = useState(false); const load = async () => { setLoading(true); @@ -94,6 +99,7 @@ export default function HomeMarqueeSeeds() { const changeMode = async (m: string) => { const prev = mode; setMode(m); + setRecPage(0); // 切模式回第 1 页(不同模式条数不同,避免停在越界页) setModeSaving(true); try { await api.patch('/admin/api/marquee-seeds/mode', { mode: m }); @@ -168,27 +174,29 @@ export default function HomeMarqueeSeeds() { } }; - // ===== 预览实际 feed(常驻内联,跟随数据源模式实时刷新)===== - // 显式把当前选中的 mode 传给后端预览:不依赖 PATCH 落库时序 —— 拨动开关(乐观更新 mode)即刻预览 - // 对应模式;切换失败回滚 mode 时预览也随之回滚。种子随机抽样,故也可点「换一批」重随机。 - const fetchPreview = async (m: string = mode) => { - setPreviewLoading(true); + // ===== 可展示的记录:按「当前模式」分页浏览全部(不去重)===== + // 只真实=真实记录;只种子=各启用种子按生成逻辑各出一行;混播=真实+种子。与 app 同口径洗牌+去连簇, + // 后端固定种子 → 翻页稳定、能翻遍全部。 + const fetchRecords = async (page: number, m: string) => { + setRecLoading(true); try { - const { data } = await api.get<{ items: PreviewItem[] }>('/admin/api/marquee-seeds/preview', { - params: { limit: 8, mode: m }, - }); - setPreviewItems(data.items); + const { data } = await api.get<{ items: RealRecord[]; total: number }>( + '/admin/api/marquee-seeds/real-records', + { params: { offset: page * REC_PAGE_SIZE, limit: REC_PAGE_SIZE, mode: m } }, + ); + setRecItems(data.items); + setRecTotal(data.total); } catch (e) { message.error(errMsg(e)); } finally { - setPreviewLoading(false); + setRecLoading(false); } }; - // 模式变化(初次拉到持久化模式 / 拨动开关 / 切换失败回滚)→ 重拉预览,保证「所见=当前模式」。 + // 页码或模式变化都重拉(切模式时 changeMode 会把页码重置到 0)。 useEffect(() => { - fetchPreview(mode); + fetchRecords(recPage, mode); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [mode]); + }, [recPage, mode]); const toggle = async (s: Seed, enabled: boolean) => { try { @@ -306,7 +314,8 @@ export default function HomeMarqueeSeeds() { - {/* 预览:常驻内联,跟随上方「数据源」模式实时刷新(所见=客户端实际效果)。 */} + {/* 可展示的真实记录:分页浏览全部(success+省>0,不去重、稳定倒序);app 轮播即从这些记录 + 随机打乱、同一用户去连簇后展示。翻页可看全所有真实用户的展示信息。 */}
- 预览 · {MODE_LABEL[mode] ?? mode} + 可展示的记录 · {MODE_LABEL[mode] ?? mode} · 共 {recTotal} 条 - 客户端实际会看到的效果,随上方数据源实时刷新;种子随机抽取、金额/用户名每次都不同 + 当前模式下 app 轮播能露出的全部记录(不去重):只真实=真实、只种子=各种子生成、混播=真实+种子; + 已按 app 口径洗牌+去连簇,顺序固定便于翻页看全 - + + + + 第 {recTotal === 0 ? 0 : recPage + 1}/{Math.max(1, Math.ceil(recTotal / REC_PAGE_SIZE))} 页 + + +
- +
- {previewItems.length === 0 && !previewLoading ? ( + {recItems.length === 0 && !recLoading ? (
- {mode === 'real' - ? '当前无真实比价记录 ——「只真实」模式不补种子,故为空' - : '暂无数据'} + 当前模式暂无可展示的记录
) : ( - previewItems.map((it, i) => ( + recItems.map((it, i) => (
{it.masked_user} 比价后节省{' '} {yuan(it.saved_amount_cents)} 元 + + {it.user_id > 0 ? `u${it.user_id}` : '种子'} + - {it.time} + {it.created_at}
)) )}