This commit is contained in:
zhangjianjun 2026-03-24 16:44:41 +08:00
parent b527ad343b
commit 22a98cd23a
22 changed files with 316 additions and 110 deletions

View File

@ -59,6 +59,7 @@
"react": "^19.1.0",
"react-activation": "^0.13.4",
"react-app-polyfill": "^3.0.0",
"react-countup": "^6.5.3",
"react-dev-utils": "^12.0.1",
"react-dom": "^19.1.0",
"react-refresh": "^0.11.0",

View File

@ -252,11 +252,7 @@ const routes = createBrowserRouter([
{
path: "join/campus/detail/:id",
element: (
<KeepAlive id="join-campus-detail">
<Suspense fallback={null}>
<JoinCampusDetail />
</Suspense>
</KeepAlive>
),
},
// 其它

View File

@ -28,7 +28,7 @@ export default function ScrollReveal({
once = true,
amount = 0.5,
delay = 0,
duration = 0.7,
duration = 0.9,
as: Component = "div",
}: ScrollRevealProps) {
const variant = ANIMATION_VARIANTS[preset];

View File

@ -1,4 +1,4 @@
import { useState } from "react";
import { useLayoutEffect, useRef, useState } from "react";
import styles from "./index.module.css";
type TabItems = {
@ -7,14 +7,60 @@ type TabItems = {
}[]
export default function BottomTabs({ tabItems, activeIndex, setActiveIndex }: { tabItems: TabItems, activeIndex: number, setActiveIndex: (index: number) => void }) {
const tabsRef = useRef<HTMLDivElement>(null);
const tabItemRefs = useRef<(HTMLDivElement | null)[]>([]);
const [tabIndicator, setTabIndicator] = useState({ x: 0, width: 0 });
useLayoutEffect(() => {
if (!tabItems?.length) return;
const root = tabsRef.current;
if (!root) return;
const updateIndicator = () => {
const tab = tabItemRefs.current[activeIndex];
if (!tab) return;
const rootRect = root.getBoundingClientRect();
const tabRect = tab.getBoundingClientRect();
setTabIndicator({
x: tabRect.left - rootRect.left,
width: tabRect.width,
});
};
updateIndicator();
const ro = new ResizeObserver(updateIndicator);
ro.observe(root);
window.addEventListener("resize", updateIndicator);
return () => {
ro.disconnect();
window.removeEventListener("resize", updateIndicator);
};
}, [activeIndex, tabItems]);
return (
<div ref={tabsRef} className={styles.bottomTabsSectionTabsWrap}>
<div
className={styles.bottomTabsSectionTabIndicator}
style={{
transform: `translateX(${tabIndicator.x}px)`,
width: tabIndicator.width,
opacity: tabIndicator.width > 0 ? 1 : 0,
}}
/>
<div className={styles.bottomTabsSectionContentTabs}>
{tabItems.map((item, i) => (
<div key={i} className={`${styles.bottomTabsSectionContentTab} ${activeIndex === i ? styles.active : ''}`} onClick={() => setActiveIndex(i)}>
<div
key={i}
ref={(el) => {
tabItemRefs.current[i] = el;
}}
className={styles.bottomTabsSectionContentTab}
onClick={() => setActiveIndex(i)}
>
<span>{item.tabName}</span>
</div>
))}
</div>
</div>
)
}

View File

@ -1,8 +1,10 @@
.bottomTabsSection {
position: relative;
overflow: hidden;
width: 100%;
/* height: 1080px; */
height: 100vh;
padding: 100px auto;
padding: 100px 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
@ -10,8 +12,26 @@
box-sizing: border-box;
}
.bottomTabsSectionBg {
position: absolute;
inset: 0;
z-index: -1;
}
.bottomTabsSectionBgLayer {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
transition: opacity 0.5s ease;
}
/* Features Section */
.bottomTabsSectionContent {
position: relative;
z-index: 1;
width: calc(100% - 520px);
margin: 0 auto;
height: 500px;
@ -40,16 +60,30 @@
}
.bottomTabsSectionContentTabs {
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
justify-content: space-evenly;
gap: auto;
border-top: 1px solid rgba(255,255,255,0.5);
padding: 0 auto;
}
.bottomTabsSectionTabsWrap {
position: relative;
}
.bottomTabsSectionTabIndicator {
position: absolute;
top: 0;
left: 0;
height: 2px;
background-color: #fff;
transition: transform 0.3s ease, width 0.3s ease, opacity 0.3s ease;
pointer-events: none;
}
.bottomTabsSectionContentTab {
flex: 1;
font-weight: 500;
font-size: 20px;
color: #FFFFFF;
@ -63,6 +97,3 @@
height: 60px;
}
}
.bottomTabsSectionContentTab.active span {
border-top: 2px solid #FFFFFF;
}

View File

@ -1,7 +1,7 @@
import styles from './index.module.css';
import SectionTitle from '../SectionTitle';
import { useState } from 'react';
import BottomTabs from './BottomTabs';
import { useLayoutEffect, useRef, useState } from 'react';
import ScrollReveal from '@/components/ScrollReveal';
type Data = {
title: string;
@ -9,25 +9,129 @@ type Data = {
tabName: string;
contentTitle: string;
contentText: string;
/** 以 mockData 为准 */
content?: string;
backgroundImage?: string;
image?: string;
}[]
}
const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)";
export default function BottomTabsSection({ data }: { data: Data }) {
const [activeIndex, setActiveIndex] = useState(0);
const bgImg = data.tabItems[activeIndex]?.backgroundImage ?? data.tabItems[activeIndex]?.image ?? "";
const tabsRef = useRef<HTMLDivElement>(null);
const tabItemRefs = useRef<(HTMLDivElement | null)[]>([]);
const [tabIndicator, setTabIndicator] = useState({ x: 0, width: 0 });
const firstBg = data.tabItems?.[0]?.backgroundImage ?? data.tabItems?.[0]?.image ?? "";
const [bgState, setBgState] = useState({
a: firstBg,
b: firstBg,
showA: true,
});
useLayoutEffect(() => {
if (!data.tabItems?.length) return;
const next = data.tabItems[activeIndex]?.backgroundImage ?? data.tabItems[activeIndex]?.image ?? "";
setBgState((prev) => {
const visible = prev.showA ? prev.a : prev.b;
if (next === visible) return prev;
if (!visible && next) {
return { a: next, b: next, showA: true };
}
if (prev.showA) {
return { ...prev, b: next, showA: false };
}
return { ...prev, a: next, showA: true };
});
}, [activeIndex, data.tabItems]);
useLayoutEffect(() => {
if (!data.tabItems?.length) return;
const root = tabsRef.current;
if (!root) return;
const updateIndicator = () => {
const tab = tabItemRefs.current[activeIndex];
if (!tab) return;
const rootRect = root.getBoundingClientRect();
const tabRect = tab.getBoundingClientRect();
setTabIndicator({
x: tabRect.left - rootRect.left,
width: tabRect.width,
});
};
updateIndicator();
const ro = new ResizeObserver(updateIndicator);
ro.observe(root);
window.addEventListener("resize", updateIndicator);
return () => {
ro.disconnect();
window.removeEventListener("resize", updateIndicator);
};
}, [activeIndex, data.tabItems]);
return (
<div className={styles.bottomTabsSection} style={{ backgroundImage: bgImg ? `url(${bgImg})` : undefined }}>
<div className={styles.bottomTabsSection}>
<div className={styles.bottomTabsSectionBg} aria-hidden>
<div
className={styles.bottomTabsSectionBgLayer}
style={{
zIndex: bgState.showA ? 2 : 1,
opacity: bgState.showA ? 1 : 0,
backgroundImage: `url(${bgState.a}), ${FALLBACK_GRADIENT}`,
}}
/>
<div
className={styles.bottomTabsSectionBgLayer}
style={{
zIndex: bgState.showA ? 1 : 2,
opacity: bgState.showA ? 0 : 1,
backgroundImage: `url(${bgState.b}), ${FALLBACK_GRADIENT}`,
}}
/>
</div>
<SectionTitle title={data.title} color="#fff" />
<div className={styles.bottomTabsSectionContent}>
<div className={styles.bottomTabsSectionContentContent}>
<div className={styles.contentTitle}>{data.tabItems[activeIndex].contentTitle}</div>
<div className={styles.contentText}>{data.tabItems[activeIndex].contentText}</div>
<ScrollReveal preset="slideUp" amount={0.2} delay={0.5}>
<div className={styles.contentTitle}>{
data.tabItems[activeIndex].contentTitle ||
data.tabItems[activeIndex].tabName
}</div>
</ScrollReveal>
<ScrollReveal preset="slideUp" amount={0.2} delay={0.7}>
<div className={styles.contentText}>{
data.tabItems[activeIndex].contentText
|| (data.tabItems[activeIndex]?.content)
}</div>
</ScrollReveal>
</div>
<div ref={tabsRef} className={styles.bottomTabsSectionTabsWrap}>
<div
className={styles.bottomTabsSectionTabIndicator}
style={{
transform: `translateX(${tabIndicator.x}px)`,
width: tabIndicator.width,
opacity: tabIndicator.width > 0 ? 1 : 0,
}}
/>
<div className={styles.bottomTabsSectionContentTabs}>
{data.tabItems.map((item, i) => (
<div
key={i}
ref={(el) => {
tabItemRefs.current[i] = el;
}}
className={styles.bottomTabsSectionContentTab}
onClick={() => setActiveIndex(i)}
>
<span>{item.tabName}</span>
</div>
))}
</div>
</div>
<BottomTabs tabItems={data.tabItems} activeIndex={activeIndex} setActiveIndex={setActiveIndex} />
</div>
</div>
)

View File

@ -1,3 +1,4 @@
import ScrollReveal from "@/components/ScrollReveal";
import styles from "./index.module.css";
type Props = {
@ -12,6 +13,7 @@ export default function ColumnXGrids({ items }: Props) {
return (
<div className={styles.columnXGrids}>
{items.map((item, index) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={(index % 3) * 0.5}>
<div key={index} className={styles.columnXGridsItem}>
<div className={styles.bg} style={{ backgroundImage: `url(${item.backgroundImage})` }} />
<div className={styles.mask}></div>
@ -20,6 +22,7 @@ export default function ColumnXGrids({ items }: Props) {
<div className={styles.columnXGridsItemContent}>{item.content}</div>
</div>
</div>
</ScrollReveal>
))}
</div>
)

View File

@ -1,3 +1,4 @@
import ScrollReveal from '@/components/ScrollReveal';
import styles from './index.module.css';
type Data = {
@ -13,7 +14,8 @@ export default function HonorGrids({ data }: { data: Data }) {
<div className={styles.honorGridsTitle}>{data.title}</div>
<div className={styles.honorGridsItems}>
{data.items.map((item) => (
{data.items.map((item, index) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.2}>
<div className={styles.honorGridsItem} key={item.title}>
<div className={styles.honorGridsItemBgleft}
style={{ backgroundImage: "url(/images/icons/honor-left.png)" }}
@ -24,6 +26,7 @@ export default function HonorGrids({ data }: { data: Data }) {
style={{ backgroundImage: "url(/images/icons/honor-right.png)" }}
></div>
</div>
</ScrollReveal>
))}
</div>
</section>

View File

@ -65,5 +65,6 @@
text-align: left;
font-style: normal;
text-transform: none;
white-space: pre-line;
}
}

View File

@ -1,5 +1,5 @@
import styles from "./StatsRow.module.css";
import CountUp from "react-countup";
type Data = {
num: string;
label: string;
@ -22,7 +22,24 @@ export default function StatsRow({ data, color }: Props) {
<div key={i} className={styles.statItem}>
<div>
<span className={`${styles.statNum} font-num`}>
{item.num.split(' ')[0] + ' '}
{(() => {
const numberPart = item.num.split(" ")[0] ?? "";
const parsed = Number(numberPart.replace(/,/g, ""));
if (Number.isNaN(parsed)) return `${numberPart} `;
return (
<CountUp
end={parsed}
duration={2}
separator=","
decimals={Number.isInteger(parsed) ? 0 : 2}
preserveValue={false}
enableScrollSpy
scrollSpyOnce
/>
);
})()}
{" "}
</span>
<span className={`${styles.statNumDesc}`}>
{item.num.split(' ')[1]}

View File

@ -8,6 +8,7 @@ import Section from "@/components/layout/Section";
import TopTabs from "@/components/layout/TopTabsSection/TopTabs";
import SectionTitle from "@/components/layout/SectionTitle";
import ScrollReveal from "@/components/ScrollReveal";
import BottomTabsSection from "@/components/layout/BottomTabsSection";
const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)";
@ -127,61 +128,8 @@ export default function BusinessCommercialGroup() {
</div>
</Section>
<section
className={styles.featuresHero}
>
<div className={styles.featuresHeroBg} aria-hidden>
<div
className={styles.featuresHeroBgLayer}
style={{
zIndex: featuresBg.showA ? 2 : 1,
opacity: featuresBg.showA ? 1 : 0,
backgroundImage: `url(${featuresBg.a}), ${FALLBACK_GRADIENT}`,
}}
/>
<div
className={styles.featuresHeroBgLayer}
style={{
zIndex: featuresBg.showA ? 1 : 2,
opacity: featuresBg.showA ? 0 : 1,
backgroundImage: `url(${featuresBg.b}), ${FALLBACK_GRADIENT}`,
}}
/>
</div>
<SectionTitle color="#fff" title={section3Data.title} subcontent={section3Data.content} />
<div className={styles.featuresHeroContent}>
<ScrollReveal preset="slideUp" >
<div className={styles.featuresHeroContentTitle}>{section3Data.tabItems[activeFeaturesTabIndex]?.tabName}</div>
</ScrollReveal>
<ScrollReveal preset="slideUp" >
<div className={styles.featuresHeroContentDesc}>{section3Data.tabItems[activeFeaturesTabIndex]?.content}</div>
</ScrollReveal>
</div>
<div ref={featuresHeroTabsRef} className={styles.featuresHeroTabs}>
<div
className={styles.featuresHeroTabIndicator}
style={{
transform: `translateX(${featuresTabIndicator.x}px)`,
width: featuresTabIndicator.width,
opacity: featuresTabIndicator.width > 0 ? 1 : 0,
}}
/>
<div className={styles.featuresHeroTabRow}>
{section3Data.tabItems.map((item: { tabName: string }, i: number) => (
<div
key={i}
ref={(el) => {
featuresTabItemRefs.current[i] = el;
}}
className={styles.featuresHeroTab}
onClick={() => setActiveFeaturesTabIndex(i)}
>
<span>{item.tabName}</span>
</div>
))}
</div>
</div>
</section>
{section3Data && <BottomTabsSection data={section3Data} />}
<section
className={`${styles.twoColSection} ${styles.propertyServices}`}

View File

@ -4,6 +4,7 @@ import SectionTitle from "@/components/layout/SectionTitle";
import Section from "@/components/layout/Section";
import { useStore } from "@/store";
import styles from "./InvestGroup.module.css";
import ScrollReveal from "@/components/ScrollReveal";
export default function InvestGroup() {
const appConfig = useStore((s) => s.appConfig);
@ -34,10 +35,12 @@ export default function InvestGroup() {
<div className={styles.investGroupContent}>
<div className={styles.investGroupContentItems}>
{section2Data.items?.map((item: { title: string; content: string }, index: number) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5}>
<div className={styles.investGroupContentItem} key={index}>
<div className={styles.investGroupContentItemTitle}>{item.title}</div>
<div className={styles.investGroupContentItemContent}>{item.content}</div>
</div>
</ScrollReveal>
))}
</div>
</div>
@ -49,6 +52,7 @@ export default function InvestGroup() {
<SectionTitle title={section3Data.title} />
<div className={styles.equityInvestmentItems}>
{section3Data.items?.map((item: { logo: string; title: string }, index: number) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5}>
<div className={styles.equityInvestmentItem} key={index}>
<img
src={item.logo}
@ -57,6 +61,7 @@ export default function InvestGroup() {
/>
<div className={styles.equityInvestmentItemTitle}>{item.title}</div>
</div>
</ScrollReveal>
))}
</div>
</section>
@ -70,10 +75,12 @@ export default function InvestGroup() {
className={styles.industryFoster}
height="100vh"
>
<ScrollReveal preset="slideUp" amount={0.2}>
<div className={styles.industryFosterMask}>
<div className={styles.industryFosterMaskTitle}>{section4Data.title}</div>
<div className={styles.industryFosterMaskContent}>{section4Data.content}</div>
</div>
</ScrollReveal>
</Section>
</div>
)}

View File

@ -6,6 +6,7 @@ import Section from "@/components/layout/Section";
import StatsRow from "@/components/layout/StatsRow/StatsRow";
import { useStore } from "@/store";
import styles from "./RuijingGroup.module.css";
import ScrollReveal from "@/components/ScrollReveal";
export default function RuijingGroup() {
const appConfig = useStore((s) => s.appConfig);
@ -50,7 +51,9 @@ export default function RuijingGroup() {
background="/images/bg-overview.png"
maskBackground="rgba(2,17,48,0.5)"
>
<ScrollReveal preset="slideUp" amount={0.2} delay={0.5}>
<div className={styles.businessFeatureContent}>{section3Data.content}</div>
</ScrollReveal>
{section3Data.statsData && (
<StatsRow data={section3Data.statsData} color="#fff" />
)}

View File

@ -40,7 +40,7 @@ export default function JoinCampus() {
const [businessPlateOptions, setBusinessPlateOptions] = useState<SelectOption[]>([]);
const [page, setPage] = useState(1);
const [size] = useState(2 * supportLocales.length);
const [size] = useState(5 * supportLocales.length);
const [total, setTotal] = useState(1000);
@ -79,9 +79,9 @@ export default function JoinCampus() {
categoryList?.filter((item: any) => item.type === 'job_area').map((item: any) => ({ label: item.name, value: String(item.id) })) ?? [];
const businessPlateOptions: SelectOption[] =
categoryList?.filter((item: any) => item.type === 'job_unit').map((item: any) => ({ label: item.name, value: String(item.id) })) ?? [];
setJobTypeOptions(jobTypeOptions);
setBusinessAreaOptions(businessAreaOptions);
setBusinessPlateOptions(businessPlateOptions);
setJobTypeOptions([{ label: '全部', value: '' }, ...jobTypeOptions]);
setBusinessAreaOptions([{ label: '全部', value: '' }, ...businessAreaOptions]);
setBusinessPlateOptions([{ label: '全部', value: '' }, ...businessPlateOptions]);
}, [categoryList]);
useEffect(() => {
@ -140,7 +140,7 @@ export default function JoinCampus() {
<div key={index} className={styles.jobItemLabel}>&nbsp;&nbsp;&nbsp;{label}</div>
))}
</div>
<div className={styles.jobItemContent}>{item.content}</div>
<div className={styles.jobItemContent}>{item.content}</div>
</div></Link>
))}
</div>

View File

@ -36,7 +36,7 @@ export default function CampusDetail() {
getJobDetail()
}, [])
return (
<div>
<div style={{ minHeight: '100vh' }}>
{
localJobDetail &&
<JobPage data={localJobDetail} />

View File

@ -1,6 +1,7 @@
import styles from "./Culture.module.css";
import Banner, { type BannerConfig } from "@/components/Banner";
import Section from "@/components/layout/Section";
import ScrollReveal from "@/components/ScrollReveal";
import { useStore } from "@/store";
export default function Culture() {
@ -30,6 +31,7 @@ export default function Culture() {
>
<div className={styles.cultureItems}>
{section1Data.items?.map((item: any, index: number) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5} key={index} className={styles.cultureItem}>
<div
key={index}
className={styles.cultureItem}
@ -41,6 +43,7 @@ export default function Culture() {
<div className={styles.cultureItemContent}>{item.content}</div>
</div>
</div>
</ScrollReveal>
))}
</div>
</Section>
@ -54,6 +57,7 @@ export default function Culture() {
>
<div className={styles.valuesItems}>
{section2Data.items?.map((item: { title: string; content?: string; icon?: string }, index: number) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5} key={index} className={styles.cultureItem}>
<div key={index} className={styles.valuesItem}>
<div
className={styles.valuesItemIcon}
@ -62,6 +66,7 @@ export default function Culture() {
<div className={styles.valuesItemTitle}>{item.title}</div>
<div className={styles.valuesItemContent}>{item.content}</div>
</div>
</ScrollReveal>
))}
</div>
</Section>

View File

@ -1,6 +1,7 @@
import styles from "./Media.module.css";
import Banner, { type BannerConfig } from "@/components/Banner";
import Section from "@/components/layout/Section";
import ScrollReveal from "@/components/ScrollReveal";
import { useStore } from "@/store";
export default function Media() {
@ -25,10 +26,10 @@ export default function Media() {
<Section background="/images/bg-overview.png" maskBackground="rgba(1,11,72,0.8)">
<div className={styles.mediaItems}>
{items.map((item: { title: string; content?: string }, index: number) => (
<div key={index} className={styles.mediaItem}>
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5} key={index} className={styles.mediaItem}>
<div className={styles.mediaItemTitle}>{item.title}</div>
<div className={styles.mediaItemContent}>{item.content}</div>
</div>
</ScrollReveal>
))}
</div>
</Section>

View File

@ -7,6 +7,7 @@ import Pagination from "@/components/Pagination";
import { Link } from "react-router-dom";
import { useStore } from "@/store";
import appApi from "@/api/app";
import ScrollReveal from "@/components/ScrollReveal";
type NewsItem = {
id: number;
@ -90,6 +91,7 @@ export default function NewsPublic() {
<div className={styles.newList}>
{localNewsList.map((item, index) => (
<ScrollReveal preset="slideUp" delay={(index % 3) * 0.5} key={index}>
<Link
key={index}
to={`/news/detail/${item.id}`}
@ -121,6 +123,7 @@ export default function NewsPublic() {
<div className={styles.newItemCreateTime}>{item.createTime}</div>
</div>
</Link>
</ScrollReveal>
))}
</div>

View File

@ -22,7 +22,8 @@
/* 信息公开 */
.informationPublicDataContent {
min-height: 500px;
min-height: 450px;
overflow: auto;
display: flex;
flex-direction: column;
justify-content: space-between;

View File

@ -1,5 +1,5 @@
import Banner, { type BannerConfig } from "@/components/Banner";
import { useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import ParagraphSection from "@/components/layout/ParagraphSection";
import Section from "@/components/layout/Section";
import AnimateTopCard from "@/components/layout/AnimateTopCard";
@ -8,6 +8,7 @@ import { useStore } from "@/store";
import styles from "./Foundation.module.css";
import TopTabsSection from "@/components/layout/TopTabsSection";
import appApi from "@/api/app";
import ScrollReveal from "@/components/ScrollReveal";
export default function Foundation() {
const appConfig = useStore((s) => s.appConfig);
const data = appConfig?.social?.foundation;
@ -26,16 +27,16 @@ export default function Foundation() {
const localNewsList = useMemo(() => {
return newsList.filter((item: any) => item.lang.toLowerCase() === locale.split('-')[0]);
}, [newsList, locale])
useEffect(() => {
const getNewsList = useCallback(() => {
appApi.getNewsList({ page: 1, size: 1000, sort: "create_time DESC",
category_id: String(categoryList?.find((item: any) => item.name.includes('【可持续发展】社会责任案例集'))?.id ?? ''),
category_id: String(categoryList?.find((item: any) => item.name.includes('【银泰公益基金会】公益传播'))?.id ?? ''),
}).then((res:any) => {
setNewsList(res.data.items.map((item:any) => {
return {
id: item.id,
title: item.title,
content: item.content,
path: item.path,
path: '/news/detail/' + item.id,
image: item.covers_show === 'image' ? item.covers.image[0] : '',
video: item.covers_show === 'video' ? item.covers.video[0] : '',
lang: item.lang,
@ -45,6 +46,27 @@ export default function Foundation() {
});
}, [])
const [fileList, setFileList] = useState<any[]>([]);
const localFileList = useMemo(() => {
return fileList.filter((item: any) => item.lang.toLowerCase() === locale.split('-')[0]);
}, [fileList, locale])
const getFileList = useCallback(async () => {
const res = await appApi.getDocList({
page: 1,
size: 1000,
// category_id: String(categoryList?.find((item: any) => item.name.includes('社会责任报告'))?.id ?? '')
})
const items = res.data.items.filter((item:any) => item.category_name.includes("信息公开"))
console.log("------items-----", items)
setFileList(items)
}, [])
useEffect(() => {
getNewsList()
getFileList()
}, [])
return (
<div>
<Banner
@ -68,31 +90,36 @@ export default function Foundation() {
>
<div className={styles.publicWelfareDataItems}>
{localNewsList?.map((item: any, index: number) => (
<div
<ScrollReveal preset="slideUp" amount={0.2} delay={(index % 2) * 0.5}
key={index}
className={styles.publicWelfareDataItem}
>
<AnimateTopCard data={item} />
</div>
</ScrollReveal>
))}
</div>
<div style={{ marginBottom: "50px" }} />
</Section>
)}
{section4Data && (
{section3Data && (
<Section
title={section4Data.title}
title={section3Data.title}
titleColor="#fff"
background={section3Data.backgroundImage ?? "/images/bg-overview.png"}
maskBackground="rgba(255,255,255,0.1)"
height="760px"
>
<div className={styles.informationPublicDataContent}>
<div className={styles.informationPublicDataItems}>
{section3Data.tabItems?.[activeIndex]?.fileItems?.map((item: any, index: number) => (
{localFileList
.filter((item:any) => item.category_name.includes(
section3Data.tabItems?.[activeIndex]?.tabName ?? ''
))
.map((item: any, index: number) => (
<div key={index} className={styles.informationPublicDataItem}>
<li>
<span>{item.fileName}</span>
<li onClick={() => window.open(item.path, '_blank')}>
<span>{item.name}</span>
</li>
</div>
))}
@ -110,9 +137,11 @@ export default function Foundation() {
<Section title={section4Data.title} background="" maskBackground="#F7FBFF">
<div className={styles.partnerItems}>
{section4Data.items?.map((item: any, index: number) => (
<ScrollReveal preset="slideUp" amount={0.2} delay={index * 0.5} key={index}>
<div key={index} className={styles.partnerItem}>
<img src={item.logo} alt="logo" />
</div>
</ScrollReveal>
))}
</div>
</Section>

View File

@ -7,6 +7,7 @@ import AnimateTopCard from "@/components/layout/AnimateTopCard";
import { useStore } from "@/store";
import styles from "./Sustainability.module.css";
import appApi from "@/api/app";
import ScrollReveal from "@/components/ScrollReveal";
type NewsItem = {
id: number;
@ -135,12 +136,13 @@ export default function Sustainability() {
</p>
<div className={styles.socialResponsibilityCaseDataItems}>
{localNewsItems?.map((item: any, index: number) => (
<div
<ScrollReveal preset="slideUp" amount={0.2} delay={(index % 2) * 0.5}
key={index}
className={styles.socialResponsibilityCaseDataItem}
>
<AnimateTopCard data={item} />
</div>
</ScrollReveal>
))}
</div>
</Section>
@ -154,7 +156,7 @@ export default function Sustainability() {
>
<div className={styles.socialResponsibilityReportData}>
{localReportItems?.map((item: any, index: number) => (
<div
<ScrollReveal preset="slideUp" amount={0.2} delay={(index % 4) * 0.5}
key={index}
className={styles.socialResponsibilityReportItem}
>
@ -168,7 +170,7 @@ export default function Sustainability() {
<div className={styles.socialResponsibilityReportItemTitle}>
{item.name}
</div>
</div>
</ScrollReveal>
))}
</div>
<div

View File

@ -122,6 +122,11 @@ instance.interceptors.response.use(
}
}
}
if(response.data.code === -1) {
Toast('系统发生异常', "error");
throw Error(response.data.message);
}
}
return response.data;
},