增加banneer占位图
This commit is contained in:
@@ -57,6 +57,7 @@ export default defineAppConfig({
|
|||||||
"ntrp-evaluate/index", // NTRP评估页
|
"ntrp-evaluate/index", // NTRP评估页
|
||||||
"enable_notification/index", // 开启消息通知
|
"enable_notification/index", // 开启消息通知
|
||||||
"emptyState/index", // 空状态页面
|
"emptyState/index", // 空状态页面
|
||||||
|
"bannerDetail/index", // Banner 图片详情页
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import ListCard from "@/components/ListCard";
|
|||||||
import ListLoadError from "@/components/ListLoadError";
|
import ListLoadError from "@/components/ListLoadError";
|
||||||
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
||||||
import { useReachBottom } from "@tarojs/taro";
|
import { useReachBottom } from "@tarojs/taro";
|
||||||
|
import Taro from "@tarojs/taro";
|
||||||
import { useUserInfo, useUserActions, useLastTestResult } from "@/store/userStore";
|
import { useUserInfo, useUserActions, useLastTestResult } from "@/store/userStore";
|
||||||
import { NTRPTestEntryCard } from "@/components";
|
import { NTRPTestEntryCard } from "@/components";
|
||||||
import { EvaluateScene } from "@/store/evaluateStore";
|
import { EvaluateScene } from "@/store/evaluateStore";
|
||||||
@@ -158,6 +159,35 @@ const ListContainer = (props) => {
|
|||||||
[evaluateFlag, data, hasTestInLastMonth, showNumber]
|
[evaluateFlag, data, hasTestInLastMonth, showNumber]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 渲染 banner 卡片
|
||||||
|
const renderBanner = (item, index) => {
|
||||||
|
if (!item?.banner_image_url) return null;
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
key={item.id || `banner-${index}`}
|
||||||
|
style={{
|
||||||
|
maxHeight: "122px",
|
||||||
|
overflow: "hidden",
|
||||||
|
borderRadius: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={item.banner_image_url}
|
||||||
|
mode="widthFix"
|
||||||
|
style={{ width: "100%", display: "block", maxHeight: "122px" }}
|
||||||
|
onClick={() => {
|
||||||
|
const target = item.banner_detail_url;
|
||||||
|
if (target) {
|
||||||
|
(Taro as any).navigateTo({
|
||||||
|
url: `/other_pages/bannerDetail/index?img=${encodeURIComponent(target)}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染列表
|
// 渲染列表
|
||||||
const renderList = () => {
|
const renderList = () => {
|
||||||
// 请求数据为空
|
// 请求数据为空
|
||||||
@@ -181,6 +211,9 @@ const ListContainer = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{memoizedList.map((match, index) => {
|
{memoizedList.map((match, index) => {
|
||||||
|
if (match.type === "banner") {
|
||||||
|
return renderBanner(match, index);
|
||||||
|
}
|
||||||
if (match.type === "evaluateCard") {
|
if (match.type === "evaluateCard") {
|
||||||
return (
|
return (
|
||||||
<NTRPTestEntryCard key="evaluate" type={EvaluateScene.list} />
|
<NTRPTestEntryCard key="evaluate" type={EvaluateScene.list} />
|
||||||
|
|||||||
8
src/other_pages/bannerDetail/index.config.ts
Normal file
8
src/other_pages/bannerDetail/index.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
navigationBarBackgroundColor: '#FFFFFF',
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
16
src/other_pages/bannerDetail/index.scss
Normal file
16
src/other_pages/bannerDetail/index.scss
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.banner_detail_page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner_detail_content {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner_detail_image {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
36
src/other_pages/bannerDetail/index.tsx
Normal file
36
src/other_pages/bannerDetail/index.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { View, Image } from '@tarojs/components';
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import { GeneralNavbar } from '@/components';
|
||||||
|
import './index.scss';
|
||||||
|
|
||||||
|
function Index() {
|
||||||
|
const [imgUrl, setImgUrl] = useState<string>('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const instance = (Taro as any).getCurrentInstance?.();
|
||||||
|
const params = instance?.router?.params || {};
|
||||||
|
const url = params?.img ? decodeURIComponent(params.img) : '';
|
||||||
|
setImgUrl(url);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="banner_detail_page">
|
||||||
|
<GeneralNavbar title="" showBack={true} />
|
||||||
|
<View className="banner_detail_content">
|
||||||
|
{imgUrl ? (
|
||||||
|
<Image
|
||||||
|
className="banner_detail_image"
|
||||||
|
src={imgUrl}
|
||||||
|
mode="widthFix"
|
||||||
|
showMenuByLongpress
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Index;
|
||||||
|
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
getCityQrCode,
|
getCityQrCode,
|
||||||
getDistricts,
|
getDistricts,
|
||||||
} from "../services/listApi";
|
} from "../services/listApi";
|
||||||
|
import commonApi from "../services/commonApi";
|
||||||
import {
|
import {
|
||||||
ListActions,
|
ListActions,
|
||||||
IFilterOptions,
|
IFilterOptions,
|
||||||
@@ -18,6 +19,27 @@ import {
|
|||||||
IPayload,
|
IPayload,
|
||||||
} from "../../types/list/types";
|
} from "../../types/list/types";
|
||||||
|
|
||||||
|
// 将 banner 按索引插入到 rows 的工具方法
|
||||||
|
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;
|
||||||
|
// 固定采用 0 基索引
|
||||||
|
const parsed = parseInt(indexRaw, 10);
|
||||||
|
const normalized = Number.isFinite(parsed) ? parsed : 0;
|
||||||
|
const resultRows = [...rows];
|
||||||
|
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;
|
||||||
@@ -296,7 +318,31 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resData = (await fetchFn(reqParams)) || {};
|
// 并发请求:列表接口 + 字典接口(仅第一页且非追加时插入 Banner)
|
||||||
|
const shouldInsertBanner = (currentPageState?.pageOption?.page || 1) === 1 && !isAppend;
|
||||||
|
const keys = "bannerListImage,bannerDetailImage,bannerListIndex";
|
||||||
|
let resData: any = {};
|
||||||
|
let dictData: any = null;
|
||||||
|
|
||||||
|
if (shouldInsertBanner) {
|
||||||
|
const [listResult, dictResult] = await Promise.allSettled([
|
||||||
|
fetchFn(reqParams),
|
||||||
|
commonApi.getDictionaryManyKey(keys),
|
||||||
|
]);
|
||||||
|
// 列表接口请求成功
|
||||||
|
if (listResult.status === "fulfilled") {
|
||||||
|
resData = listResult.value || {};
|
||||||
|
} else {
|
||||||
|
throw listResult.reason || new Error("获取数据失败");
|
||||||
|
}
|
||||||
|
// 字典接口请求成功
|
||||||
|
if (dictResult.status === "fulfilled" && (dictResult.value as any)?.code === 0) {
|
||||||
|
dictData = (dictResult.value as any)?.data || null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resData = (await fetchFn(reqParams)) || {};
|
||||||
|
}
|
||||||
|
|
||||||
const { data = {}, code } = resData;
|
const { data = {}, code } = resData;
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
setListData({
|
setListData({
|
||||||
@@ -308,7 +354,14 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
});
|
});
|
||||||
return Promise.reject(new Error('获取数据失败'));
|
return Promise.reject(new Error('获取数据失败'));
|
||||||
}
|
}
|
||||||
const { count, rows } = data;
|
const { count } = data;
|
||||||
|
let { rows } = data as any;
|
||||||
|
|
||||||
|
// 将 banner 插入到指定位置(仅第一页且非追加)
|
||||||
|
if (shouldInsertBanner && Array.isArray(rows) && dictData) {
|
||||||
|
rows = insertBannersToRows(rows, dictData);
|
||||||
|
}
|
||||||
|
|
||||||
setListData({
|
setListData({
|
||||||
error: '',
|
error: '',
|
||||||
data: rows || [],
|
data: rows || [],
|
||||||
@@ -344,24 +397,30 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const searchParams = getSearchParams() || {};
|
const searchParams = getSearchParams() || {};
|
||||||
|
const keys = "bannerListImage,bannerDetailImage,bannerListIndex";
|
||||||
|
|
||||||
// 调用常规列表接口
|
// 并发请求:常规列表、智能排序列表、字典
|
||||||
const listParams = {
|
const [listResSettled, integrateResSettled, dictSettled] = await Promise.allSettled([
|
||||||
...searchParams,
|
getGamesList({
|
||||||
order: searchParams.order || "distance",
|
...searchParams,
|
||||||
};
|
order: searchParams.order || "distance",
|
||||||
const listRes = await getGamesList(listParams);
|
}),
|
||||||
|
getGamesIntegrateList({
|
||||||
// 调用智能排序列表接口
|
...searchParams,
|
||||||
const integrateParams = {
|
order: "",
|
||||||
...searchParams,
|
seachOption: {
|
||||||
order: "",
|
...searchParams.seachOption,
|
||||||
seachOption: {
|
isRefresh: true,
|
||||||
...searchParams.seachOption,
|
},
|
||||||
isRefresh: true,
|
}),
|
||||||
},
|
commonApi.getDictionaryManyKey(keys),
|
||||||
};
|
]);
|
||||||
const integrateRes = await getGamesIntegrateList(integrateParams);
|
|
||||||
|
const listRes = listResSettled.status === "fulfilled" ? listResSettled.value : null;
|
||||||
|
const integrateRes = integrateResSettled.status === "fulfilled" ? integrateResSettled.value : null;
|
||||||
|
const dictData = dictSettled.status === "fulfilled" && (dictSettled.value as any)?.code === 0
|
||||||
|
? (dictSettled.value as any)?.data
|
||||||
|
: null;
|
||||||
|
|
||||||
// 根据当前排序方式更新对应的数据
|
// 根据当前排序方式更新对应的数据
|
||||||
const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState;
|
const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState;
|
||||||
@@ -369,7 +428,12 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
const isIntegrate = distanceQuickFilter?.order === "0";
|
const isIntegrate = distanceQuickFilter?.order === "0";
|
||||||
|
|
||||||
if (listRes?.code === 0 && listRes?.data) {
|
if (listRes?.code === 0 && listRes?.data) {
|
||||||
const { count, rows } = listRes.data;
|
const { count } = listRes.data;
|
||||||
|
let { rows } = listRes.data as any;
|
||||||
|
// 插入 banner(当为第一页时)
|
||||||
|
if ((currentPageState?.pageOption?.page || 1) === 1 && Array.isArray(rows) && dictData) {
|
||||||
|
rows = insertBannersToRows(rows, dictData);
|
||||||
|
}
|
||||||
if (!isIntegrate) {
|
if (!isIntegrate) {
|
||||||
// 如果当前是常规排序,更新常规列表数据
|
// 如果当前是常规排序,更新常规列表数据
|
||||||
setListData({
|
setListData({
|
||||||
@@ -383,7 +447,12 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (integrateRes?.code === 0 && integrateRes?.data) {
|
if (integrateRes?.code === 0 && integrateRes?.data) {
|
||||||
const { count, rows, recommendList } = integrateRes.data;
|
const { count } = integrateRes.data;
|
||||||
|
let { rows, recommendList } = integrateRes.data as any;
|
||||||
|
// 插入 banner(当为第一页时)
|
||||||
|
if ((currentPageState?.pageOption?.page || 1) === 1 && Array.isArray(rows) && dictData) {
|
||||||
|
rows = insertBannersToRows(rows, dictData);
|
||||||
|
}
|
||||||
if (isIntegrate) {
|
if (isIntegrate) {
|
||||||
// 如果当前是智能排序,更新智能排序列表数据
|
// 如果当前是智能排序,更新智能排序列表数据
|
||||||
setListData({
|
setListData({
|
||||||
|
|||||||
Reference in New Issue
Block a user