This commit is contained in:
zhangjianjun 2026-03-19 16:36:29 +08:00
parent 5cab4c00eb
commit 4ca125387e
26 changed files with 205 additions and 119 deletions

View File

Before

Width:  |  Height:  |  Size: 670 B

After

Width:  |  Height:  |  Size: 670 B

View File

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 680 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="92" height="55" viewBox="0 0 92 55"><defs><pattern x="0" y="0" width="92" height="55" patternUnits="userSpaceOnUse" id="master_svg0_94_11479"><image x="0" y="0" width="92" height="55" xlink:href="data:image/png;base64,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"/></pattern></defs><rect x="0" y="0" width="92" height="55" rx="0" fill="url(#master_svg0_94_11479)" fill-opacity="1"/></svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -138,3 +138,7 @@ body {
}
}
}
.logo-dark {
filter: brightness(0) saturate(100%) invert(16%) sepia(25%) saturate(4500%) hue-rotate(223deg) brightness(80%) contrast(85%);
}

View File

@ -17,9 +17,9 @@ function App() {
const locale = useStore((s) => s.locale);
const appConfig = useStore((s) => s.appConfig);
const initState = useCallback((data: Record<string, unknown>) => {
const company = data?.company as { config?: { favicon?: string; shortName?: string } } | undefined;
const { favicon, shortName } = company?.config || {};
const initState = useCallback((data: any) => {
const company = data?.__global__.company;
const { favicon, shortName } = company || {};
if (favicon) {
const favor: any = document.querySelector("link[rel*='icon']") || document.createElement('link');
favor.type = 'image/x-icon';

View File

@ -94,7 +94,7 @@ export default function YearPicker({
{value != null ? `${value}` : placeholder}
</span>
<div className={styles.icons}>
<img className={`${styles.arrow} ${open ? styles.arrowOpen : ""}`} src="/images/icon-arrow-down.png" alt="arrow-down" style={{ width: "24px", height: "24px" }} />
<img className={`${styles.arrow} ${open ? styles.arrowOpen : ""}`} src="/images/icons/icon-arrow-down.png" alt="arrow-down" style={{ width: "24px", height: "24px" }} />
</div>
</div>

View File

@ -33,8 +33,7 @@ export default function Banner({
backgroundImage,
}: Props) {
const appConfig = useStore((s) => s.appConfig);
const header = appConfig?.header;
const navItems = header?.navItems ?? [];
const navItems = appConfig?.navItems ?? [];
const location = useLocation();
const images = Array.isArray(backgroundImage) ? backgroundImage : [backgroundImage];
@ -61,7 +60,7 @@ export default function Banner({
if (child) return child.label;
}
const last = path.split("/").pop() ?? path;
return last;
return title;
};
const items = paths.map((path) => ({
label: getLabelByPath(path),

View File

@ -13,7 +13,7 @@ export default function Article({ data }: { data: Data }) {
<div className={styles.article}>
<div className={styles.articleHeaderLine}>
<div className={styles.articleHeaderLineBack} onClick={() => window.history.back()}>
<img src="/images/icon-arrowleft.png" alt="arrowleft" style={{ width: "20px", height: "20px" }} />
<img src="/images/icons/icon-arrowleft.png" alt="arrowleft" style={{ width: "20px", height: "20px" }} />
<span></span>
</div>
</div>

View File

@ -18,7 +18,7 @@ export default function JobPage({ data }: { data: Data }) {
<div className={styles.jobPage}>
<div className={styles.jobPageHeaderLine}>
<div className={styles.jobPageHeaderLineBack} onClick={() => window.history.back()}>
<img src="/images/icon-arrowleft.png" alt="arrowleft" style={{ width: "20px", height: "20px" }} />
<img src="/images/icons/icon-arrowleft.png" alt="arrowleft" style={{ width: "20px", height: "20px" }} />
<span></span>
</div>
</div>

View File

@ -61,7 +61,7 @@ export default function RowAccordion({ data, placement='bottom' }: Props) {
useEffect(() => {
if (isInView && containerRef.current) {
const rect = containerRef.current.getBoundingClientRect();
smoothScrollTo(window.scrollY + rect.top, 1200);
smoothScrollTo(window.scrollY + rect.top, 800);
}
}, [isInView]);
@ -99,7 +99,7 @@ export default function RowAccordion({ data, placement='bottom' }: Props) {
variants={contentItemVariants}
transition={{
duration: 0.6,
delay: 0.5 + index * 0.12,
delay: 0.3 + index * 0.12,
ease: [0.25, 0.46, 0.45, 0.94],
}}
>

View File

@ -1,10 +1,11 @@
import { useCallback, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import type { Swiper as SwiperType } from "swiper";
import "swiper/css";
import SectionTitle from "../SectionTitle";
import styles from "./index.module.css";
import { RightOutlined, LeftOutlined } from "@ant-design/icons";
import { useLocation } from "react-router-dom";
type Data = {
title: string;
cardItems: {
@ -18,15 +19,30 @@ type Data = {
}
export default function SwiperCardSection({ data }: { data: Data }) {
const location = useLocation();
const hash = location.hash;
const id = decodeURIComponent(hash.replace('#', ''));
const [swiperRef, setSwiperRef] = useState<SwiperType | null>(null);
const [activeIndex, setActiveIndex] = useState(0);
const onSwiperChange = useCallback((e: any) => {
setActiveIndex(e.activeIndex);
}, [])
useEffect(() => {
if (id && data.cardItems && swiperRef) {
const index = data.cardItems.findIndex((item) => item.title === id);
if (index !== -1) {
setTimeout(() => {
swiperRef.slideTo(index);
}, 500);
}
}
}, [id, data.cardItems, swiperRef])
return (
<section className={styles.swiperCardSection}>
<section className={styles.swiperCardSection} id={id}>
<SectionTitle title={data.title} />
<div className={styles.carouselWrapper}>
<div className={styles.carouselWrapper} >
{activeIndex > 0 && (
<button
type="button"

View File

@ -1,6 +1,7 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import styles from './index.module.css';
import TopTabs from './TopTabs';
import { useLocation } from 'react-router-dom';
type Data = {
tabItems: {
@ -19,9 +20,24 @@ type Data = {
}
export default function TopTabsSection({ data, className }: { data: Data, className?: string }) {
const location = useLocation();
const hash = location.hash;
const id = decodeURIComponent(hash.replace('#', ''));
const [activeIndex, setActiveIndex] = useState(0);
useEffect(() => {
if (id && data.tabItems) {
setTimeout(() => {
const index = data.tabItems.findIndex((item) => item.tabName === id);
console.log('index', index, id, data.tabItems)
if (index !== -1) {
setActiveIndex(index);
}
}, 300)
}
}, [id, data.tabItems])
return (
<section className={`${styles.topTabsSection} ${className}`} style={{ backgroundImage: `url(${data.backgroundImage})` }}>
<section id={id} className={`${styles.topTabsSection} ${className}`} style={{ backgroundImage: `url(${data.backgroundImage})` }}>
<TopTabs data={data} activeIndex={activeIndex} setActiveIndex={setActiveIndex} />
<div className={styles.topTabsContent}>
<div className={styles.topTabsContentLeft}>

View File

@ -6,8 +6,20 @@ const useHashScroll = () => {
useEffect(() => {
if (location.hash) {
const element = document.querySelector(location.hash);
element?.scrollIntoView({ behavior: "smooth" });
setTimeout(() => {
const element = document.querySelector(decodeURIComponent(location.hash));
if (element) {
const header = document.querySelector("header");
const headerHeight = header?.getBoundingClientRect().height ?? 7.5 * 16;
const elementTop = element.getBoundingClientRect().top + window.scrollY;
const offsetPosition = elementTop - headerHeight;
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
});
}
})
} else {
window.scrollTo({
top: 0,

View File

@ -42,11 +42,13 @@
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
gap: 40px;
position: absolute;
right: 3.75rem;
}
.footerLogo {
font-size: 1.25rem;
font-weight: 600;

View File

@ -5,15 +5,17 @@ import type { NavItem, NavChild } from "@/type";
export default function Footer() {
const appConfig = useStore((s) => s.appConfig);
const footer = appConfig?.footer;
const header = appConfig?.header;
const footer = appConfig?.__global__?.footer;
const footerColumns = header?.navItems?.filter((item: NavItem) => item.path !== "/") ?? [];
const lowerLinks = footer?.lowerLinks ?? [];
const socialIcons = footer?.socialIcons ?? [];
const copyright = footer?.copyright ?? "版权声明©2001-{year} | 中国银泰投资有限公司";
const footerColumns = appConfig?.navItems?.filter((item: NavItem) => item.path !== "/") ?? [];
const lowerLinks = footer?.lowerLinks?.items ?? [];
const socialIcons = footer?.socialIcons?.items ?? [];
const copyright = footer?.copyright ?? "版权声明©2001-{year}";
const companyName = appConfig?.__global__.company?.companyName;
const icpNumber = footer?.icpNumber ?? "京ICP备05026114号-1";
const logo = appConfig?.__global__.company?.logo;
return (
<footer className={`layout-footer ${styles.footer}`}>
<div className={styles.footerUpper}>
@ -34,14 +36,21 @@ export default function Footer() {
</div>
))}
<div className={styles.footerRight}>
{socialIcons.map((icon: { src: string; alt: string }) => (
{socialIcons.filter((item:any) => item.show).map((icon: any) => (
<Link to={icon.link} target="_blank" key={icon.alt}>
<img
key={icon.alt}
src={icon.src}
alt={icon.alt}
style={{ width: "26px", height: "26px" }}
/>
</Link>
))}
<img
src={logo}
alt="logo"
style={{ width: "92px", height: "56px" }}
className="logo-dark"
/>
</div>
</div>
</div>
@ -49,6 +58,7 @@ export default function Footer() {
<FooterLower
lowerLinks={lowerLinks}
copyright={copyright.replace("{year}", String(new Date().getFullYear()))}
companyName={companyName}
icpNumber={icpNumber}
/>
</footer>
@ -58,17 +68,19 @@ export default function Footer() {
function FooterLower({
lowerLinks,
copyright,
companyName,
icpNumber,
}: {
lowerLinks: { path: string; label: string }[];
copyright: string;
companyName: string;
icpNumber: string;
}) {
return (
<div className={styles.footerLower}>
<div className={`header-row ${styles.footerLowerInner}`}>
<div style={{ display: "flex", flexDirection: "row", gap: "50px" }}>
<span>{copyright}</span>
<span>{`${copyright} | ${companyName}`}</span>
<span>{icpNumber}</span>
</div>
<div className={styles.footerLowerLinks}>

View File

@ -14,22 +14,41 @@
font-style: normal;
text-transform: none;
transition: background 0.3s ease;
/* transition: all 0.7s ease-in-out;
transition-delay: 0.3s; */
}
.header::before {
content: '';
display: block;
position: absolute;
top: 0;
width: 100%;
height: 0%;
background: #fff;
transition: height 0.7s ease-in-out;
}
.showDropPanel.header::before {
height: 350%;
}
.whiteMode.header::before {
height: 100%;
}
.whiteMode.header {
background: #fff;
/* background: rgba(255, 255, 255, 1); */
box-shadow: 0 0 10px 0 rgba(255, 255, 255, 0.1);
border-bottom: 1px solid #eee;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
transition-delay: none;
}
.whiteMode .navLink {
.whiteMode .navLink, .showDropPanel .navLink {
color: #222222;
}
.whiteMode {
.whiteMode, .showDropPanel {
.searchBtn {
color: #222222;
}
@ -49,6 +68,7 @@
}
.headerInner {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
@ -58,14 +78,35 @@
.headerInner::after {
position: absolute;
bottom: 0;
left: 3.75rem;
top: 100%;
left: 0;
right: 0;
content: '';
display: block;
width: calc(100% - 7.5rem);
width: 95%;
margin: 0 auto;
box-sizing: border-box;
height: 1px;
background: #FFFFFF;
transform: scaleX(0);
transform-origin: 90% 0; /* 交点:左侧 85%,右侧 15%,从此点向左右展开 */
transition: transform 1.5s ease-in-out;
}
.animate {
&.headerInner::after {
transform: scaleX(1);
}
.crossYline {
height: 100%;
}
}
.whiteMode, .showDropPanel {
.headerInner::after {
transform: scaleX(0);
}
.crossYline {
height: 0%;
}
}
.logo {
@ -121,9 +162,11 @@
.crossYline {
width: 1px;
height: 100%;
height: 0%;
background: #FFFFFF;
transition: height 0.3s ease-in-out;
align-self: flex-end; /* 交点在最底部,从此点向上展开 */
transform-origin: center bottom; /* 缩放从底部中心点展开 */
transition: height 1s ease-in-out;
}
.langTrigger {
@ -154,15 +197,16 @@
left: 0;
width: 100%;
height: 0;
background: rgba(255, 255, 255, 0.9);
/* background: rgba(255, 255, 255, 0.9); */
/* box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); */
padding: 0;
z-index: 1000;
transition: height 0.9s ease-in-out;
overflow: hidden;
transition: height 0.5s ease-in-out, padding-top 0.5s ease-in-out;
&.visible {
height: 23.75rem;
padding: 1.25rem;
padding-top: 1.25rem;
}
}

View File

@ -4,7 +4,7 @@ import styles from "./Header.module.css";
import { useEffect, useMemo, useRef, useState } from "react";
import { useStore } from "@/store";
import type { NavChild, NavItem, LocaleKey, SupportLocale } from "@/type";
import ScrollReveal from "@/components/ScrollReveal";
const DEFAULT_NAV_ITEMS: { path: string; label: string; children?: NavChild[] }[] = [];
@ -15,9 +15,9 @@ export default function Header() {
const setLocale = useStore((s) => s.setLocale);
const supportLocales = useStore((s) => s.supportLocales);
const navItems = appConfig?.header?.navItems?.filter((item: NavItem) => item.path !== "/") ?? DEFAULT_NAV_ITEMS;
const navItems = appConfig?.navItems?.filter((item: NavItem) => item.path !== "/") ?? DEFAULT_NAV_ITEMS;
const langMenuItems: SupportLocale[] = supportLocales || [];
const logo = appConfig?.company?.logo ?? "/images/logo.png";
const logo = appConfig?.__global__.company?.logo;
const [activeNav, setActiveNav] = useState("");
const [showDropPanel, setShowDropPanel] = useState(false);
@ -57,13 +57,26 @@ export default function Header() {
return () => window.removeEventListener("scroll", handleScroll);
}, []);
// 动画
const [animateHeader, setAnimateHeader] = useState(false);
useEffect(() => {
setTimeout(() => {
setAnimateHeader(true)
}, 500);
}, [])
return (
<header className={`${styles.header} ${(showDropPanel || showWhiteMode) ? styles.whiteMode : ""}`}
<header className={`${styles.header}
${showWhiteMode && styles.whiteMode}
${showDropPanel && styles.showDropPanel}
`}
onMouseLeave={() => setShowDropPanel(false)}
>
<div className={`header-row ${styles.headerInner}`}>
<div className={`header-row ${styles.headerInner} ${animateHeader ? styles.animate : ""}`}>
<Link to="/" className={styles.logo}>
<img src={logo} alt="logo" style={{ width: "5.75rem", height: "3.4375rem" }} />
<img src={logo} alt="logo" style={{ width: "5.75rem", height: "3.4375rem" }}
className={(showDropPanel || showWhiteMode) ? "logo-dark" : ""}
/>
</Link>
<div className={styles.headerRight}>
<nav>
@ -125,7 +138,6 @@ function DropPanel({ items, left, onLinkClick, show }: {
clearTimeout(timeout);
}
}, [show]);
if (!visible) return null;
return (
<div id="drop-panel" className={`${styles.dropPanel} ${visible ? styles.visible : ""}`} style={{ paddingLeft: left}}>
<div className={styles.dropPanelContent}>

View File

@ -2,8 +2,9 @@ import { Outlet, useLocation } from "react-router-dom";
import { useEffect } from "react";
import Header from "./Header";
import Footer from "./Footer";
import useHashScroll from "@/hooks/useHashScroll";
export default function MainLayout() {
useHashScroll()
const { pathname } = useLocation();
useEffect(() => {

View File

@ -71,15 +71,13 @@ export default function AboutFounder() {
{section3Data && (
<Section title={section3Data?.title} titleColor="#fff" background={section3Data?.backgroundImage}>
<div className={styles.section3Content}>
{Array.from({
length: Math.max(0, ...(section3Data?.columns?.map((c: { title?: string }[]) => c.length) ?? [0])),
}).flatMap((_, rowIndex) =>
(section3Data?.columns ?? []).map((colItems: { title?: string }[], colIndex: number) => (
<div key={`${rowIndex}-${colIndex}`} className={styles.section3Item}>
{colItems[rowIndex] ? <li>{colItems[rowIndex].title}</li> : null}
{
section3Data?.items.map((item: { title?: string }, index: number) => (
<div key={index} className={styles.section3Item}>
{item.title ? <li>{item.title}</li> : null}
</div>
))
)}
}
</div>
</Section>
)}

View File

@ -29,7 +29,7 @@ export default function InvestGroup() {
{section1Data && <ParagraphSection data={section1Data} />}
{section2Data && (
<section className={styles.investGroup}>
<section className={styles.investGroup} id={section2Data.title}>
<SectionTitle title={section2Data.title} color="#fff" />
<div className={styles.investGroupContent}>
<div className={styles.investGroupContentItems}>
@ -45,7 +45,7 @@ export default function InvestGroup() {
)}
{section3Data && (
<section className={styles.equityInvestment}>
<section className={styles.equityInvestment} id={section3Data.title}>
<SectionTitle title={section3Data.title} />
<div className={styles.equityInvestmentItems}>
{section3Data.items?.map((item: { logo: string; title: string }, index: number) => (
@ -63,6 +63,7 @@ export default function InvestGroup() {
)}
{section4Data && (
<div id={section4Data.title}>
<Section
background={section4Data.backgroundImage}
maskBackground="rgba(20,53,92,0.1)"
@ -73,6 +74,7 @@ export default function InvestGroup() {
<div className={styles.industryFosterMaskContent}>{section4Data.content}</div>
</div>
</Section>
</div>
)}
</div>
);

View File

@ -354,7 +354,7 @@
color: #666;
margin: 0 0 0.5rem;
line-height: 1.6;
height: 75px;
height: 70px;
display: -webkit-box;
-webkit-line-clamp: 2;

View File

@ -101,7 +101,7 @@ function News() {
const handleVideoPause = () => {
if (videoRef.current) {
videoRef.current.pause();
videoRef.current.currentTime = 0;
// videoRef.current.currentTime = 0;
}
};
@ -160,7 +160,7 @@ function News() {
}
<p className={styles.newsFeaturedCaption}>
{localNewsData[activeNewsIndex]?.title}
</p>
</div>
</div>
@ -172,7 +172,7 @@ function News() {
<h3 className={styles.newsItemTitle}>
{item.title}
</h3>
<p className={styles.newsItemSnippet}>{item.snippet}</p>
<p className={styles.newsItemSnippet} dangerouslySetInnerHTML={{ __html: item.snippet }} ></p>
<div className={styles.newsItemDateWrap}>
<span className={styles.newsItemDate}>{item.date}</span>
<ArrowRightOutlined className={styles.newsItemArrowIcon} style={{ fontSize: '12px' }} />

View File

@ -25,7 +25,7 @@ export default function CampusDetail() {
content: item.description,
requirement: item.requirement,
lang: item.lang,
contact: item.contact,
contact: item.contract_info,
}
});
setJobDetail(items);

View File

@ -47,7 +47,7 @@ export default function SiteMap() {
<div className={styles.siteMapItemChildChildren}>
{child.children?.map((childChild) => (
<Link
to={childChild.path}
to={childChild.path.replace('{id}', childChild.label )}
className={styles.siteMapItemChildChild}
key={childChild.label}
>

View File

@ -52,7 +52,7 @@ function resolveKeyPath(
if (page === "/") {
if (tags === "menu") return "home";
if (name === "全局配置") return "__global__";
if (tags === "global") return "__global__";
return null;
}
@ -123,34 +123,6 @@ function buildNavItems(
});
}
const DEFAULT_FOOTER_ZH = {
lowerLinks: [
{ path: "/contact-us", label: "联系我们" },
{ path: "/site-map", label: "网站地图" },
{ path: "/terms-of-use", label: "使用条款" },
{ path: "/privacy-policy", label: "隐私保护" },
{ path: "/audit-report", label: "审计举报" },
],
socialIcons: [
{ src: "/images/icon-weixin.png", alt: "weixin" },
{ src: "/images/icon-weibo.png", alt: "weibo" },
{ src: "/images/logo.png", alt: "logo" },
],
copyright: "版权声明©2001-{year} | 中国银泰投资有限公司",
icpNumber: "京ICP备05026114号-1",
};
const DEFAULT_FOOTER_EN = {
...DEFAULT_FOOTER_ZH,
lowerLinks: [
{ path: "/contact-us", label: "Contact" },
{ path: "/site-map", label: "Site Map" },
{ path: "/terms-of-use", label: "Terms of Use" },
{ path: "/privacy-policy", label: "Privacy Policy" },
{ path: "/audit-report", label: "Audit Report" },
],
copyright: "Copyright ©2001-{year} | China Yintai Investment Co., Ltd.",
};
/**
* Restructure global config to match the expected layout:
@ -193,6 +165,7 @@ export function parsePageConfig(items: RawPageItem[]): {
const zhNavItems = buildNavItems(menuItems, "ZH", parsedContentMap);
const enNavItems = buildNavItems(menuItems, "EN", parsedContentMap);
const zhConfig: Record<string, any> = {};
const enConfig: Record<string, any> = {};
@ -220,12 +193,8 @@ export function parsePageConfig(items: RawPageItem[]): {
}
}
zhConfig.header = { navItems: zhNavItems };
zhConfig.footer = { ...DEFAULT_FOOTER_ZH };
enConfig.header = { navItems: enNavItems };
enConfig.footer = { ...DEFAULT_FOOTER_EN };
zhConfig.navItems = zhNavItems;
enConfig.navItems = enNavItems;
deepFallback(enConfig, zhConfig);
return { "zh-CN": zhConfig, "en-US": enConfig };