Merge branch feat/juguohong/20260206

This commit is contained in:
李瑞
2026-02-07 00:59:44 +08:00
2 changed files with 25 additions and 33 deletions

View File

@@ -10,6 +10,7 @@ import { EvaluateScene } from "@/store/evaluateStore";
import { waitForAuthInit } from "@/utils/authInit"; import { waitForAuthInit } from "@/utils/authInit";
import "./index.scss"; import "./index.scss";
import { useRef, useEffect, useState, useMemo } from "react"; import { useRef, useEffect, useState, useMemo } from "react";
import { useDictionaryStore } from "@/store/dictionaryStore";
const ListContainer = (props) => { const ListContainer = (props) => {
const { const {
@@ -44,7 +45,7 @@ const ListContainer = (props) => {
const { fetchUserInfo, fetchLastTestResult } = useUserActions(); const { fetchUserInfo, fetchLastTestResult } = useUserActions();
// 使用全局状态中的测试结果,避免重复调用接口 // 使用全局状态中的测试结果,避免重复调用接口
const lastTestResult = useLastTestResult(); const lastTestResult = useLastTestResult();
const { bannerListImage, bannerDetailImage, bannerListIndex = 0 } = useDictionaryStore((s) => s.bannerDict) || {};
useReachBottom(() => { useReachBottom(() => {
// 加载更多方法 // 加载更多方法
if (loading) { if (loading) {
@@ -130,6 +131,16 @@ const ListContainer = (props) => {
); );
}; };
// 插入 banner 卡片
function insertBannerCard(list) {
if (!bannerListImage) return list;
return [
...list.slice(0, Number(bannerListIndex)),
{ type: "banner", banner_image_url: bannerListImage, banner_detail_url: bannerDetailImage },
...list.slice(Number(bannerListIndex))
];
}
// 对于没有ntrp等级的用户每个月展示一次, 插在第二个位置后面 // 对于没有ntrp等级的用户每个月展示一次, 插在第二个位置后面
function insertEvaluateCard(list) { function insertEvaluateCard(list) {
if (!evaluateFlag) if (!evaluateFlag)
@@ -146,17 +157,23 @@ const ListContainer = (props) => {
return [...list, { type: "evaluateCard" }]; return [...list, { type: "evaluateCard" }];
} }
const [item1, item2, ...rest] = list; const [item1, item2, ...rest] = list;
return [
let result = [
item1, item1,
item2, item2,
{ type: "evaluateCard" }, { type: "evaluateCard" },
...(showNumber !== undefined ? rest.slice(0, showNumber - 3) : rest), ...(showNumber !== undefined ? rest.slice(0, showNumber - 3) : rest),
]; ];
if (bannerListImage) {
return insertBannerCard(result);
}
return result;
} }
const memoizedList = useMemo( const memoizedList = useMemo(
() => insertEvaluateCard(data), () => insertEvaluateCard(data),
[evaluateFlag, data, hasTestInLastMonth, showNumber] [evaluateFlag, data, hasTestInLastMonth, showNumber, bannerListImage, bannerDetailImage, bannerListIndex]
); );
// 渲染 banner 卡片 // 渲染 banner 卡片
@@ -168,7 +185,7 @@ const ListContainer = (props) => {
<View <View
key={item.id || `banner-${index}`} key={item.id || `banner-${index}`}
style={{ style={{
height: "122px", height: "100px",
overflow: "hidden", overflow: "hidden",
borderRadius: "12px", borderRadius: "12px",
backgroundImage: `url(${item.banner_image_url})`, backgroundImage: `url(${item.banner_image_url})`,
@@ -204,10 +221,10 @@ const ListContainer = (props) => {
return ( return (
<> <>
{memoizedList.map((match, index) => { {memoizedList.map((match, index) => {
if (match.type === "banner") { if (match?.type === "banner") {
return renderBanner(match, index); return renderBanner(match, index);
} }
if (match.type === "evaluateCard") { if (match?.type === "evaluateCard") {
return ( return (
<NTRPTestEntryCard key={`evaluate-${index}`} type={EvaluateScene.list} /> <NTRPTestEntryCard key={`evaluate-${index}`} type={EvaluateScene.list} />
); );

View File

@@ -11,8 +11,6 @@ import {
getCityQrCode, getCityQrCode,
getDistricts, getDistricts,
} from "../services/listApi"; } from "../services/listApi";
// 不再在这里请求 banner 字典,统一由 dictionaryStore 启动时获取
import { useDictionaryStore } from "./dictionaryStore";
import { import {
ListActions, ListActions,
IFilterOptions, IFilterOptions,
@@ -20,26 +18,6 @@ import {
IPayload, IPayload,
} from "../../types/list/types"; } from "../../types/list/types";
// 将 banner 按索引插入到列表的工具方法0基长度不足则插末尾先移除已存在的 banner
function insertBannersToRows(rows: any[], dictData: any) {
if (!Array.isArray(rows) || !dictData) return rows;
const img = (dictData?.bannerListImage || "").trim();
const indexRaw = (dictData?.bannerListIndex || "").toString().trim();
if (!img) return rows;
const parsed = parseInt(indexRaw, 10);
const normalized = Number.isFinite(parsed) ? parsed : 0;
// 先移除已有的 banner确保列表中仅一条 banner
const resultRows = rows?.filter((item) => item?.type !== "banner") || [];
const target = Math.max(0, Math.min(normalized, resultRows.length));
resultRows.splice(target, 0, {
type: "banner",
id: `banner-${target}`,
banner_image_url: img,
banner_detail_url: (dictData?.bannerDetailImage || "").trim(),
} as any);
return resultRows;
}
function translateCityData(dataTree) { function translateCityData(dataTree) {
return dataTree.map((item) => { return dataTree.map((item) => {
const { children, ...rest } = item; const { children, ...rest } = item;
@@ -272,14 +250,11 @@ export const useListStore = create<TennisStore>()((set, get) => ({
const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState; const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState;
const currentData = currentPageState?.data || []; const currentData = currentPageState?.data || [];
const newData = isAppend ? [...currentData, ...(data || [])] : (data || []); const newData = isAppend ? [...currentData, ...(data || [])] : (data || []);
// 从字典缓存获取 banner并将其插入到最终列表指定位置全局索引
const dictData = useDictionaryStore.getState().bannerDict;
const processedData = dictData ? insertBannersToRows(newData, dictData) : newData;
state.updateCurrentPageState({ state.updateCurrentPageState({
data: processedData, data: newData,
isHasMoreData, isHasMoreData,
// 使用插入后的最终数据判断是否显示空状态,避免有 banner 时仍显示空 // 使用插入后的最终数据判断是否显示空状态,避免有 banner 时仍显示空
isShowNoData: processedData?.length === 0, isShowNoData: newData?.length === 0,
}); });
set({ set({