diff --git a/public/images/about/founder/banner1.png b/public/images/about/founder/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/founder/banner1.png differ diff --git a/public/images/about/founder/section1-bg.png b/public/images/about/founder/section1-bg.png new file mode 100644 index 0000000..d4b09c8 Binary files /dev/null and b/public/images/about/founder/section1-bg.png differ diff --git a/public/images/about/founder/section2-bg.png b/public/images/about/founder/section2-bg.png new file mode 100644 index 0000000..d4b09c8 Binary files /dev/null and b/public/images/about/founder/section2-bg.png differ diff --git a/public/images/about/founder/section3-bg.png b/public/images/about/founder/section3-bg.png new file mode 100644 index 0000000..e8e863a Binary files /dev/null and b/public/images/about/founder/section3-bg.png differ diff --git a/public/images/about/founder/section4-bg.png b/public/images/about/founder/section4-bg.png new file mode 100644 index 0000000..f3883bb Binary files /dev/null and b/public/images/about/founder/section4-bg.png differ diff --git a/public/images/about/history/banner1.png b/public/images/about/history/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/history/banner1.png differ diff --git a/public/images/about/overview/banner1.png b/public/images/about/overview/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/banner1.png differ diff --git a/public/images/about/overview/section1-bg.png b/public/images/about/overview/section1-bg.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/section1-bg.png differ diff --git a/public/images/about/overview/section2-bg.png b/public/images/about/overview/section2-bg.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/section2-bg.png differ diff --git a/public/images/about/overview/section3-bg.png b/public/images/about/overview/section3-bg.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/section3-bg.png differ diff --git a/public/images/about/overview/section4-bg.png b/public/images/about/overview/section4-bg.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/section4-bg.png differ diff --git a/public/images/about/overview/section5-bg.png b/public/images/about/overview/section5-bg.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/about/overview/section5-bg.png differ diff --git a/public/images/business/commercial-group/banner1.png b/public/images/business/commercial-group/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/business/commercial-group/banner1.png differ diff --git a/public/images/business/commercial-group/detail/banner1.png b/public/images/business/commercial-group/detail/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/business/commercial-group/detail/banner1.png differ diff --git a/public/images/business/commercial-group/detail/section1-bg.png b/public/images/business/commercial-group/detail/section1-bg.png new file mode 100644 index 0000000..6e0449b Binary files /dev/null and b/public/images/business/commercial-group/detail/section1-bg.png differ diff --git a/public/images/business/commercial-group/detail/section2-bg.png b/public/images/business/commercial-group/detail/section2-bg.png new file mode 100644 index 0000000..db768ab Binary files /dev/null and b/public/images/business/commercial-group/detail/section2-bg.png differ diff --git a/public/images/business/commercial-group/section1-bg.png b/public/images/business/commercial-group/section1-bg.png new file mode 100644 index 0000000..6b6891d Binary files /dev/null and b/public/images/business/commercial-group/section1-bg.png differ diff --git a/public/images/business/commercial-group/section2-bg.png b/public/images/business/commercial-group/section2-bg.png new file mode 100644 index 0000000..f6d7f81 Binary files /dev/null and b/public/images/business/commercial-group/section2-bg.png differ diff --git a/public/images/business/commercial-group/section3-bg.png b/public/images/business/commercial-group/section3-bg.png new file mode 100644 index 0000000..6b6891d Binary files /dev/null and b/public/images/business/commercial-group/section3-bg.png differ diff --git a/public/images/business/commercial-group/section4-bg.png b/public/images/business/commercial-group/section4-bg.png new file mode 100644 index 0000000..f6d7f81 Binary files /dev/null and b/public/images/business/commercial-group/section4-bg.png differ diff --git a/public/images/home/banner1.png b/public/images/home/banner1.png new file mode 100644 index 0000000..34baec0 Binary files /dev/null and b/public/images/home/banner1.png differ diff --git a/public/images/home/section1-1.png b/public/images/home/section1-1.png new file mode 100644 index 0000000..9882a06 Binary files /dev/null and b/public/images/home/section1-1.png differ diff --git a/public/images/home/section1-2.png b/public/images/home/section1-2.png new file mode 100644 index 0000000..24d8fa4 Binary files /dev/null and b/public/images/home/section1-2.png differ diff --git a/public/images/home/section1-3.png b/public/images/home/section1-3.png new file mode 100644 index 0000000..795fefb Binary files /dev/null and b/public/images/home/section1-3.png differ diff --git a/public/images/home/section1-4.png b/public/images/home/section1-4.png new file mode 100644 index 0000000..3638014 Binary files /dev/null and b/public/images/home/section1-4.png differ diff --git a/public/images/home/section1-5.png b/public/images/home/section1-5.png new file mode 100644 index 0000000..acfbbc5 Binary files /dev/null and b/public/images/home/section1-5.png differ diff --git a/public/images/home/section2-bg.png b/public/images/home/section2-bg.png new file mode 100644 index 0000000..ef9babe Binary files /dev/null and b/public/images/home/section2-bg.png differ diff --git a/public/images/home/section2-bg1.png b/public/images/home/section2-bg1.png new file mode 100644 index 0000000..7e1c955 Binary files /dev/null and b/public/images/home/section2-bg1.png differ diff --git a/public/images/home/section2-bg2.png b/public/images/home/section2-bg2.png new file mode 100644 index 0000000..31272bd Binary files /dev/null and b/public/images/home/section2-bg2.png differ diff --git a/public/images/icons/logo.svg b/public/images/icons/logo.svg new file mode 100644 index 0000000..ed314ee --- /dev/null +++ b/public/images/icons/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/weibo.svg b/public/images/icons/weibo.svg new file mode 100644 index 0000000..2d4d9ec --- /dev/null +++ b/public/images/icons/weibo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/weixin.svg b/public/images/icons/weixin.svg new file mode 100644 index 0000000..cbf2f39 --- /dev/null +++ b/public/images/icons/weixin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/open-screen/logo-left.png b/public/images/open-screen/logo-left.png new file mode 100644 index 0000000..5329b8f Binary files /dev/null and b/public/images/open-screen/logo-left.png differ diff --git a/public/images/open-screen/logo-right.png b/public/images/open-screen/logo-right.png new file mode 100644 index 0000000..9c868f0 Binary files /dev/null and b/public/images/open-screen/logo-right.png differ diff --git a/public/images/others/search/banner.png b/public/images/others/search/banner.png new file mode 100644 index 0000000..8fb33e5 Binary files /dev/null and b/public/images/others/search/banner.png differ diff --git a/public/images/svg/logo.svg b/public/images/svg/logo.svg new file mode 100644 index 0000000..ed314ee --- /dev/null +++ b/public/images/svg/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.css b/src/App.css index db8ad34..f2c22a5 100644 --- a/src/App.css +++ b/src/App.css @@ -124,4 +124,17 @@ body { color: #222222; line-height: 34px; margin-bottom: 20px; +} + +/* hover缩放 */ +.hover-scale { + .hover-scale-bg { + transition: transform 0.8s ease; + } + + &:hover { + .hover-scale-bg { + transform: scale(1.05); + } + } } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 8af0149..c5398bd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import routes from "@/Routes"; import { useCallback, useEffect, useState } from "react"; import appApi from "@/api/app"; import { useStore } from "@/store"; +import { parsePageConfig } from "@/utils/parsePageConfig"; import type { I18nData, SupportLocale } from "@/type"; function AppRoutes() { @@ -20,7 +21,6 @@ function App() { const company = data?.company as { config?: { favicon?: string; shortName?: string } } | undefined; const { favicon, shortName } = company?.config || {}; if (favicon) { - // 替换网页图标 const favor: any = document.querySelector("link[rel*='icon']") || document.createElement('link'); favor.type = 'image/x-icon'; favor.rel = 'shortcut icon'; @@ -34,10 +34,10 @@ function App() { const getAppConfig = useCallback(async () => { try { const res = await appApi.getAppConfig(); - const data = res.data as I18nData; + const data = parsePageConfig(res.data.items) as I18nData; useStore.getState().setAppConfig(data); - const locale = useStore.getState().locale; - const config = data[locale] ?? data["zh-CN"]; + const currentLocale = useStore.getState().locale; + const config = data[currentLocale] ?? data["zh-CN"]; const supportLocales: SupportLocale[] = [ { key: "zh-CN", label: "中文" }, { key: "en-US", label: "English" }, diff --git a/src/Routes.tsx b/src/Routes.tsx index 105f96a..6e6d035 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -54,11 +54,11 @@ const routes: RouteObject[] = [ { path: "join/culture", element: }, { path: "join/campus", element: }, { path: "join/campus/detail/:id", element: }, + // 其它 // 物业服务 { path: "/property-service", element: }, // 搜索 { path: "/search", element: }, - // 其它 // 使用条款 隐私保护 审计举报 网站地图 { path: "/terms-of-use", element: }, { path: "/privacy-policy", element: }, diff --git a/src/api/app.ts b/src/api/app.ts index ef69637..92d1d65 100644 --- a/src/api/app.ts +++ b/src/api/app.ts @@ -1,23 +1,74 @@ import requests from "@/utils/request"; -import mockData from "./mockData" + +type Params = {page:number, size:number, sort?:string} const app = { getAppConfig() { - // return requests({ - // url: "/api/config", - // method: "get", - // }); - return Promise.resolve({data: mockData}); - }, - getJobList(params: any) { return requests({ - url: "/api/job", + url: "/yt/api/page", + method: "get", + params: { + page: 1, + size: 1000, + } + }); + }, + // 分类 + getCategoryList(type:string) { + return requests({ + url: "/yt/api/category", + method: "get", + params: { + page: 1, + size: 1000, + type + } + }); + }, + getDocList() { + return requests({ + url: "/yt/api/doc", + method: "get", + params: { + page: 1, + size: 1000, + } + }); + }, + // 历程列表 + getProcessList() { + return requests({ + url: "/yt/api/process", + method: "get", + params: { + page: 1, + size: 1000, + } + }); + }, + // 新闻列表 + getNewsList(params: Params & { title?: string, category_id?: string }) { + return requests({ + url: "/yt/api/news", + method: "get", + params + }); + }, + getNewsDetail(id: number | string) { + return requests({ + url: `/yt/api/news/${id}`, + method: "get", + }); + }, + getJobList(params: Params & { title?: string, job_type?: string, business_area?: string, business_plate?: string }) { + return requests({ + url: "/yt/api/job", method: "get", params }); }, getJobDetail(id: number | string) { return requests({ - url: `/api/job/${id}`, + url: `/yt/api/job/${id}`, method: "get", }); }, diff --git a/src/api/mockData.ts b/src/api/mockData.ts deleted file mode 100644 index d88d4e3..0000000 --- a/src/api/mockData.ts +++ /dev/null @@ -1,1067 +0,0 @@ -/** - * 接口返回数据结构 - * mockData: { - * "zh-CN": {...}, - * "en-US": {...} - * } - */ - -import type { NavChild, NavItem } from "@/type"; - -const zhCN = { - companyName: "银泰", - logo: "/images/logo.png", - company: { - config: { - favicon: "/favicon.ico", - shortName: "银泰", - }, - }, - - header: { - navItems: [ - { - label: "首页", - path: "/", - index: true, - }, - { - label: "关于银泰", - path: "/about", - children: [ - { path: "/about/overview", label: "集团概览" }, - { path: "/about/history", label: "发展历程" }, - { path: "/about/founder", label: "创始人介绍" }, - ], - }, - { - label: "集团业务", - path: "/business", - children: [ - { path: "/business/commercial-group", label: "银泰商业集团" }, - { path: "/business/base-group", label: "银泰基业集团" }, - { path: "/business/realty-group", label: "银泰置地集团" }, - { path: "/business/invest-group", label: "银泰投资集团" }, - { path: "/business/ruijing-group", label: "瑞京集团" }, - ], - }, - { - label: "社会责任", - path: "/social", - children: [ - { path: "/social/sustainability", label: "可持续发展" }, - { path: "/social/foundation", label: "银泰公益基金会" }, - ], - }, - { - label: "新闻中心", - path: "/news", - children: [ - { path: "/news/public", label: "集团发布" }, - { path: "/news/media", label: "媒体垂询" }, - ], - }, - { - label: "加入银泰", - path: "/join", - children: [ - { path: "/join/culture", label: "企业文化" }, - { path: "/join/campus", label: "招贤纳士" }, - ], - }, - ] as NavItem[], - }, - - footer: { - // columns复用header的navItems,并应用到footer - 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", - }, - - // === 2. 各页面模块 === - - home: { - banner: { - title: "银泰集团", - content: "中国现代新商业典范", - showBreadcrumb: false, - backgroundImage: ["/images/bg-overview.png", "/images/bg-base-group.png"], - }, - section1Data: { - items: [ - { - title: "银泰商业集团", - content: "涵盖地标型高端商业综合体in77、景观地标型商业综合体inPARK区域型品质商业生活中心银泰城等品牌的大型商业集团,是一家持续推动传统零售业创新与互联网转型融合的典范性企业。", - backgroundImage: "/images/bg-commercial-group.png", - links: [ - { text: "in77", path: "/in77" }, - { text: "inPARK", path: "/inPARK" }, - { text: "银泰城购物中心", path: "/shopping-center" }, - ], - }, - { - title: "银泰基业集团", - content: "银泰基业集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-base-group.png", - links: [ - { text: "in77", path: "/in77" }, - { text: "inPARK", path: "/inPARK" }, - { text: "银泰城购物中心", path: "/shopping-center" }, - ], - }, - { - title: "银泰置地集团", - content: "银泰置地集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-realty-group.png", - links: [ - { text: "in77", path: "/in77" }, - { text: "inPARK", path: "/inPARK" }, - { text: "银泰城购物中心", path: "/shopping-center" }, - ], - }, - { - title: "银泰投资集团", - content: "银泰投资集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-invest-group.png", - links: [ - { text: "in77", path: "/in77" }, - { text: "inPARK", path: "/inPARK" }, - { text: "银泰城购物中心", path: "/shopping-center" }, - ], - }, - { - title: "瑞京资产", - content: "瑞京集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-ruijing-group.png", - links: [ - { text: "in77", path: "/in77" }, - { text: "inPARK", path: "/inPARK" }, - { text: "银泰城购物中心", path: "/shopping-center" }, - ], - }, - ], - }, - section2Data: [ - { - title: "可持续发展", - content: "银泰集团积极践行绿色发展理念,将可持续发展融入企业战略与日常运营,致力于构建人与自然和谐共生的美好未来。", - backgroundImage: "/images/sustainable-cranes.png", - }, - { - title: "银泰公益基金会", - content: "银泰集团积极践行绿色发展理念,将可持续发展融入企业战略与日常运营,致力于构建人与自然和谐共生的美好未来。", - backgroundImage: "/images/welfare-check.png", - }, - ], - newsData: [ - { - title: "银泰百货×敦煌研究院联名新品限量首发", - snippet: "10月28日,在杭州余杭区委城市工作会议暨城市新中心中轴线创新发展大会上,银泰集团正式宣布银泰杭州新中心项目定名为「杭州银泰中心」", - date: "2024-01-15", - path: "/news/1", - }, - { - title: "银泰中国区总裁陈晓:我们是长期主义者", - snippet: "10月28日,在杭州余杭区委城市工作会议暨城市新中心中轴线创新发展大会上,银泰集团正式宣布银泰杭州新中心项目定名为「杭州银泰中心」", - date: "2024-01-10", - path: "/news/2", - }, - { - title: "中国青年发展基金会 | 银泰公益基金会合作签约", - snippet: "10月28日,在杭州余杭区委城市工作会议暨城市新中心中轴线创新发展大会上,银泰集团正式宣布银泰杭州新中心项目定名为「杭州银泰中心」", - date: "2023-11-20", - path: "/news/3", - }, - ], - }, - - about: { - overview: { - banner: { - title: "集团概览", - content: '银泰集团(全称"中国银泰投资有限公司")由沈国军先生于1997年创立,立足实业发展与产业投资,业务涵盖商业零售、商业地产运营与开发、股权投资等领域,在境内外拥有多家控股、参股公司,已发展成为一家主业突出、多元发展的现代企业集团。', - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: [ - { - title: "银泰商业集团", - content: "涵盖地标型高端商业综合体in77、景观地标型商业综合体inPARK区域型品质商业生活中心银泰城等品牌的大型商业集团,是一家持续推动传统零售业创新与互联网转型融合的典范性企业。", - backgroundImage: "/images/bg-commercial-group.png", - links: [ - { label: "in77", to: "/business/commercial-group/in77" }, - { label: "inPARK", to: "/inPARK" }, - { label: "银泰城购物中心", to: "/shopping-center" }, - ], - }, - { - title: "银泰基业集团", - content: "银泰基业集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-base-group.png", - links: [ - { label: "in77", to: "/in77" }, - { label: "inPARK", to: "/inPARK" }, - { label: "银泰城购物中心", to: "/shopping-center" }, - ], - }, - { - title: "银泰置地集团", - content: "银泰置地集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-realty-group.png", - links: [ - { label: "in77", to: "/in77" }, - { label: "inPARK", to: "/inPARK" }, - { label: "银泰城购物中心", to: "/shopping-center" }, - ], - }, - { - title: "银泰投资集团", - content: "银泰投资集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-invest-group.png", - links: [ - { label: "in77", to: "/in77" }, - { label: "inPARK", to: "/inPARK" }, - { label: "银泰城购物中心", to: "/shopping-center" }, - ], - }, - { - title: "瑞京集团", - content: "瑞京集团是银泰集团旗下核心业务板块,深耕商业地产与零售领域多年,致力于打造高品质商业空间,引领现代消费体验。集团旗下拥有银泰百货、银泰城等多个知名商业品牌,在全国多个核心城市布局,持续为消费者创造美好生活。", - backgroundImage: "/images/bg-ruijing-group.png", - links: [ - { label: "in77", to: "/in77" }, - { label: "inPARK", to: "/inPARK" }, - { label: "银泰城购物中心", to: "/shopping-center" }, - ], - }, - ], - }, - history: { - banner: { - title: "发展历程", - content: "银泰集团的发展历程", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: [ - { year: 2025, content: "银泰集团持续深化战略布局,推动高质量发展。" }, - { year: 2024, content: "银泰集团创新发展模式,拓展业务新领域。" }, - { year: 2023, content: "银泰集团核心业务稳健增长,品牌影响力持续提升。" }, - { year: 2022, content: "银泰集团深化数字化转型,提升运营效率。" }, - { year: 2018, content: "银泰集团推进战略转型升级,开启新篇章。" }, - { year: 2016, content: "银泰集团拓展多元化业务,夯实发展基础。" }, - { year: 2015, content: "银泰集团完善产业布局,增强核心竞争力。" }, - { year: 2014, content: "银泰集团加速全国化扩张,品牌影响力扩大。" }, - { year: 2013, content: "银泰集团稳健发展,主营业务持续向好。" }, - { year: 2010, content: "银泰集团抓住市场机遇,实现跨越式发展。" }, - { year: 2009, content: "银泰集团应对金融危机,保持稳健经营。" }, - { year: 2008, content: "银泰集团完善管理体系,提升运营水平。" }, - { year: 2007, content: "银泰集团上市,开启资本化发展新征程。" }, - { year: 1998, content: "银泰集团快速成长,确立行业领先地位。" }, - { year: 1997, content: "银泰集团成立,迈出创业第一步。" }, - ], - }, - founder: { - banner: { - title: "创始人介绍", - subtitle: "银泰集团创始人、董事长——沈国军", - content: "卓越的变革践行者、产业推动者及社会公民", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - title: "沈国军", - content: '汉族,博士,高级经济师。中国人民政治协商会议第十一届、十三届全国委员会委员、中国人民政治协商会议第十三届全国委员会提案委员会委员、中国致公党第十四届、十五届、十六届中央委员会常委、第一届浙商(全球)总会执行会长、第一届甬商(全球)总会会长。\n\n 银泰集团(全称"中国银泰投资有限公司")创始人兼董事长、银泰公益基金会创始人及荣誉理事长、桃花源生态保护基金会董事局执行主席。', - items: [ - { - title: "商业领域", - backgroundImage: "/images/bg-invest-group.png", - content: "银泰集团在商业领域有着丰富的经验和深厚的实力,致力于打造高品质的商业空间,引领现代消费体验。", - }, - { - title: "社会责任", - backgroundImage: "/images/bg-invest-group.png", - content: "银泰集团在社会责任方面有着丰富的经验和深厚的实力,致力于打造高品质的商业空间,引领现代消费体验。", - }, - ] - }, - section2Data: { - title: "企业家精神", - subtitle: "一个优秀的企业家,要传承、弘扬传统优秀的商道,继续开创新的商业文明。创新与变革、勤奋与进取、分享与合作、诚信与责任是沈国军所倡导的企业家精神。", - backgroundImage: '', - sideImage: "/images/bg-invest-group.png", - content: "银泰集团在社会责任方面有着丰富的经验和深厚的实力,致力于打造高品质的商业空间,引领现代消费体验。", - }, - section3Data: { - title: "社会职务", - backgroundImage: '/images/bg-overview.png', - columns: [ - [ // 第 1 列 - { title: '第十一、十三届全国政协委员' }, - { title: '第十三届全国政协提案委员会委员' }, - { title: '第十四、十五、十六届中国致公党中央常委' }, - { title: '第一届浙商总会执行会长' }, - ], - [ // 第 2 列 - { title: '第一届甬商总会会长' }, - { title: '北京浙江企业商会终身名誉会长' }, - { title: '西安市人民政府经济顾问' }, - { title: '中国企业家俱乐部理事' }, - ], - [ // 第 3 列 - { title: '桃花源生态保护基金会执行主席' }, - { title: '银泰公益基金会创始人兼荣誉理事长' }, - { title: '中国宋庆龄基金会第六届理事会理事' }, - { title: '爱佑慈善基金会发起理事' }, - { title: '致福慈善基金会副理事长' }, - ], - ] - }, - section4Data: { - title: "荣誉奖项", - backgroundImage: '', - items: [ - { year: '2026年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2025年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2024年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2023年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2022年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2021年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2020年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2019年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2018年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2017年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2016年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2015年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2014年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2013年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2012年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2011年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - { year: '2010年', children: ["2015年度“影响·2015中国公益100人”", "2015年度“中国社会十大推动者”"]}, - ], - }, - }, - }, - - business: { - commercialGroup: { - section1Data: { - title: "银泰商业集团", - content: '作为一家大型商业集团,品牌涵盖地标型高端商业综合体in77、景观地标型商业综合体inPARK、区域型品质商业生活中心银泰城等,是一家持续推动传统零售业创新与互联网转型融合的典范性企业。其中,in77系列购物中心位于核心商业圈和国家示范步行街,是时尚零售业和新消费领域的标杆;inPARK系列购物中心致力于打造"街区+shopping mall + 微景观"的公园商业新形态,通过创新营销催化人气聚集,构建新年轻生活方式;银泰城购物中心融合购物、餐饮、休闲、娱乐、社交等多元业态于一体,充分满足一站式消费需求。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - { num: "350 亿元", label: "销售额每年" }, - { num: "5000 +", label: "合作品牌" }, - ], - }, - section2Data: { - tabItems: [ - { tabName: "in77", content: "in77 内容", sideImage: "/images/bg-overview.png", path: "/business/commercial-group/in77" }, - { tabName: "inPARK", content: "inPARK 内容", sideImage: "/images/bg-overview.png", path: "/business/commercial-group/inPARK" }, - { tabName: "银泰城购物中心", content: "银泰城 内容", sideImage: "/images/bg-overview.png", path: "/business/commercial-group/shopping-center" }, - ], - backgroundImage: '/images/bg-in.png' - }, - section3Data: { - tabItems: [ - { tabName: "深耕运营", content: "全域营销 内容", backgroundImage: "/images/bg-overview.png" }, - { tabName: "行业领先", content: "数字化运营 内容", backgroundImage: "/images/bg-overview.png" }, - { tabName: "创新变革", content: "全球品牌合作 内容", backgroundImage: "/images/bg-overview.png" }, - { tabName: "数字生态", content: "全球品牌合作 内容", backgroundImage: "/images/bg-overview.png" }, - ], - }, - banner: { - title: "银泰商业集团", - content: "传统零售业的推动者和典范", - titleSize: "medium", - showBreadcrumb: true, - backgroundImage: "/images/bg-commercial-group.png", - }, - }, - commercialGroupDetail: { - items: [ - { - pathname: "in77", - banner: { - title: "in77", - largeContent: "地标型高端商业综合体", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - backgroundImage: "", - title: "in77", - content: "作为高端商业品牌,汲取了银泰集团优质的商业资源及运营管理能力,旗下项目均位于核心商业圈或国家示范步行街,成为时尚零售业和新消费领域的标杆。目前有北京银泰中心in01、杭州湖滨银泰in77、北京王府井银泰in88、合肥银泰in77及成都银泰中心in99等项目。每个项目都融入“唤醒真正的自我”的理念,同时亦不乏各自特色与个性。", - }, - section2Data: { - backgroundImage: "/images/bg-in.png", - titleDirection: "column", - tabItems: [ - { tabName: "北京银泰中心in01", icon: '/images/bg-overview.png', contentTitle: "银泰中心1", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "杭州湖滨银泰in77", icon: '/images/bg-overview.png', contentTitle: "银泰中心2", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "北京王府井银泰in88", icon: '/images/bg-overview.png', contentTitle: "银泰中心3", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "成都银泰中心in99", icon: '/images/bg-overview.png', contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "成都银泰中心in99", icon: '/images/bg-overview.png', contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "成都银泰中心in99", icon: '/images/bg-overview.png', contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "成都银泰中心in99", icon: '/images/bg-overview.png', contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "成都银泰中心in99", icon: '/images/bg-overview.png', contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - ], - } - } - ] - }, - baseGroup: { - section1Data: { - title: "银泰基业集团", - content: '管理有限公司是一家集品质物业服务、资产托管运营、智慧物联管理、科技平台创新运维为一体的专业化物业服务企业,致力于商办类物业运营管理、打造资产全周期生态服务。\n\n 凭借银泰集团多年城市商业地产运营经验不断深化创新,银泰智享积极拓展业务深度与广度,做强基础物业服务,深耕客户卓越服务体验,创造企业多元化价值。核心业务涵盖资产全托管服务、资产顾问服务、资产设施服务、物业品牌合作等,着力实现服务体系化、标准化、精细化、智慧化"四化合一",打造国内一流的物业管理品牌。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - { num: "350 亿元", label: "销售额每年" }, - { num: "5000 +", label: "合作品牌" }, - ], - }, - section2Data: { - title: "四大区域", - cardItems: [ - { title: "服务业态1", content: "服务业态1", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态2", content: "服务业态2", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态3", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态4", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态5", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section3Data: { - title: "标杆项目", - items: [ - { - title: "北京", - subtitle: "北京银泰中心", - backgroundImage: "/images/bg-overview.png", - links: [ - { text: "in01", path: "" }, - { text: "超甲级写字楼", path: "" }, - { text: "北京柏悦酒店", path: "" }, - { text: "柏悦府", path: "" }, - { text: "柏悦居", path: "" }, - ], - }, - { title: "四川", subtitle: "成都银泰中心", backgroundImage: "/images/bg-overview.png" }, - { title: "浙江", subtitle: "杭州湖滨银泰in77", backgroundImage: "/images/bg-overview.png" }, - { title: "上海", subtitle: "上海中骏广场", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section4Data: { - title: "企业价值", - items: [ - { title: "荣誉资质1" }, - { title: "荣誉资质2" }, - { title: "荣誉资质3" }, - { title: "荣誉资质4" }, - { title: "荣誉资质5" }, - { title: "荣誉资质6" }, - { title: "荣誉资质7" }, - { title: "荣誉资质8" }, - ], - }, - section5Data: { - title: "业务特色", - tabItems: [ - { tabName: "精细化运营", contentTitle: "精细化运营——运筹帷幄·精于心", contentText: "通过精细化管理赋能运营,稳步提升商业资产价值。关注租金的成长性和租户的良性表现,实现产品逐步升级,服务稳健提升,实现商业资产整体增值。", backgroundImage: "/images/bg-overview.png" }, - { tabName: "数智化管理", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - { tabName: "生态化发展", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - { tabName: "品牌化升级", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - ], - }, - banner: { - title: "银泰基业集团", - content: "商业物业资产运营与管理先锋", - titleSize: "medium", - showBreadcrumb: false, - backgroundImage: "/images/bg-overview.png", - }, - }, - investGroup: { - section1Data: { - title: "银泰投资集团", - content: '银泰集团坚持价值投资理念,积极拓展产业投资,在互联网科技、大消费、智慧物流、新能源、生物制药、医养服务、金融服务等新兴产业积极布局,围绕产业链形成协同效应,做头部资产的发现者、稀缺资源的整合者、企业成长的赋能者,助力技术创新与产业变革,促进中国实体经济高质量发展。\n\n成立银柏投资、之江投资两大投资平台。投资规模超200亿,累计管理规模超700亿元,其中有15家公司已经成长为估值10亿美金以上的"独角兽",18家已完成上市。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - { num: "350 亿元", label: "销售额每年" }, - { num: "5000 +", label: "合作品牌" }, - ], - }, - section2Data: { - title: "发起设立", - items: [ - { - title: "菜鸟", - content: "银泰集团与阿里巴巴集团等各方共同组建的菜鸟智慧物流网络有限公司于2013年5月正式成立。菜鸟网络扎根在物流产业,以科技创新为核心,搭建了领先的全球化物流网络,为消费者和商家提供普惠优质服务,为实体经济降本增效,保障民生流通,稳就业促增收,是一家客户价值驱动的全球化产业互联网公司。", - }, - { - title: "网商银行", - content: "2015年6月,网商银行正式开业,它是由银泰集团、阿里巴巴集团等企业共同发起的中国第一家将核心系统架构在金融云上的银行,是中国首批试点的民营银行之一。网商银行旨在成为网商必选的金融服务商、互联网银行的探索者和普惠金融的实践者,为小微企业、大众消费者、农村经营者与农户、中小金融机构提供服务。", - }, - ], - }, - section3Data: { - title: "股权投资", - items: Array(15).fill(null).map(() => ({ logo: "/images/bg-overview.png", title: "字节跳动" })), - }, - section4Data: { - title: "产业孵化", - content: "银泰集团创立和培育了银泰黄金股份有限公司(000975.SZ)。银泰黄金是以黄金为主的高质量矿山投资运营商,致力于贵金属和有色金属矿采选及金属贸易,拥有全国储量最大、单体银品位最高的银多金属矿和品质较高的黄金矿,已发展成为国内贵金属行业具有领先优势及影响力的上市公司之一。", - backgroundImage: "/images/bg-overview.png", - }, - banner: { - title: "银泰投资集团", - content: "探索价值投资,协同产业发展", - titleSize: "medium", - showBreadcrumb: false, - backgroundImage: "/images/bg-overview.png", - }, - }, - realtyGroup: { - section1Data: { - title: "银泰置地集团", - content: '专注于大型综合性商业地产项目和小镇开发,涵盖高端购物中心、酒店、公寓、超甲级写字楼等业态,旗下囊括"银泰中心""银泰城""柏悦府""柏悦居"等产品线。公司秉承绿色建筑理念和楼宇智慧运营管理,成为中国高端商业地产的领军企业。目前,银泰置地集团在全国拥有100余个建成及在建项目,遍布北京、杭州、成都等七十多个城市,总开发面积近二千万平方米。\n\n近年来,银泰置地集团紧密结合国家产业政策,控制开发规模,探索"租售并举+轻资产运作"的商业模式,成为商业地产领域创新变革与健康良性发展的代表性企业。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - { num: "350 亿元", label: "销售额每年" }, - { num: "5000 +", label: "合作品牌" }, - ], - }, - section2Data: { - tabItems: [ - { tabName: "银泰中心", contentTitle: "银泰中心1", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", backgroundImage: "/images/bg-overview.png" }, - { tabName: "银泰城", contentTitle: "银泰中心2", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", backgroundImage: "/images/bg-overview.png" }, - { tabName: "高级酒店与公寓", contentTitle: "银泰中心3", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", backgroundImage: "/images/bg-overview.png" }, - { tabName: "文旅小镇", contentTitle: "银泰中心", contentSubtitle: "城市封面地标", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section3Data: { - title: "标杆项目", - items: [ - { title: "杭州银泰中心", content: '位于杭州未来科技城地块,与余杭区政府合作开发建设,规划投资数十亿元,建设总建筑面积约60万方的高端TOD城市综合体,推动区域向"国际化消费中心"转型,打造百亿级商圈。', backgroundImage: "/images/bg-overview.png" }, - { title: "丽水银泰城", content: '位于杭州未来科技城地块,与余杭区政府合作开发建设,规划投资数十亿元,建设总建筑面积约60万方的高端TOD城市综合体,推动区域向"国际化消费中心"转型,打造百亿级商圈。', backgroundImage: "/images/bg-overview.png" }, - { title: "杭州银泰喜来登大酒店", content: '位于杭州未来科技城地块,与余杭区政府合作开发建设,规划投资数十亿元,建设总建筑面积约60万方的高端TOD城市综合体,推动区域向"国际化消费中心"转型,打造百亿级商圈。', backgroundImage: "/images/bg-overview.png" }, - { title: "杭州银泰仙女湖小镇", content: '位于杭州未来科技城地块,与余杭区政府合作开发建设,规划投资数十亿元,建设总建筑面积约60万方的高端TOD城市综合体,推动区域向"国际化消费中心"转型,打造百亿级商圈。', backgroundImage: "/images/bg-overview.png" }, - ], - }, - section4Data: { - title: "荣誉奖项", - items: [ - { title: "荣誉资质1" }, - { title: "荣誉资质2" }, - { title: "荣誉资质3" }, - { title: "荣誉资质4" }, - { title: "荣誉资质5" }, - { title: "荣誉资质6" }, - { title: "荣誉资质7" }, - { title: "荣誉资质8" }, - ], - }, - section5Data: { - title: "业务特色", - tabItems: [ - { tabName: "精细化运营", contentTitle: "精细化运营——运筹帷幄·精于心", contentText: "通过精细化管理赋能运营,稳步提升商业资产价值。关注租金的成长性和租户的良性表现,实现产品逐步升级,服务稳健提升,实现商业资产整体增值。", backgroundImage: "/images/bg-overview.png" }, - { tabName: "数智化管理", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - { tabName: "生态化发展", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - { tabName: "品牌化升级", contentTitle: "内容标题2", contentText: "内容文本2", backgroundImage: "/images/bg-overview.png" }, - ], - }, - banner: { - title: "银泰置地集团", - content: "商业地产的高品质代表", - titleSize: "medium", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - ruijingGroup: { - section1Data: { - title: "瑞京资产", - content: '(全称"江西瑞京金融资产管理有限公司") 成立于2018年1月,公司是经江西省人民政府批准设立、中国银行保险监督管理委员会备案通过,由银泰集团、赣州发展集团联合发起设立的江西省第二家、赣州市唯一一家地方资产管理公司(AMC),实缴注册资本金15亿元人民币。\n\n瑞京资产秉承服务实体经济的战略定位,以不良资产的收购和处置为核心业务,通过主动式资产管理,纾困问题企业,协助地方政府有效化解金融风险,助力实体企业健康发展。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - ], - }, - section2Data: { - title: "业务架构", - cardItems: [ - { title: "不良债权收购", content: "服务业态1", backgroundImage: "/images/bg-overview.png" }, - { title: "债务重组", content: "服务业态2", backgroundImage: "/images/bg-overview.png" }, - { title: "投资管理", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - { title: "金融服务", content: "服务业态4", backgroundImage: "/images/bg-overview.png" }, - { title: "个贷不良", content: "服务业态5", backgroundImage: "/images/bg-overview.png" }, - { title: "企业纾困", content: "服务业态5", backgroundImage: "/images/bg-overview.png" }, - { title: "问题企业流动性支持", content: "服务业态5", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section3Data: { - title: "业务特色", - subtitle: "发展个贷业务,支持青年重返信用体系", - content: '2024年,瑞京资产成功竞得捷信264.64亿元资产包,成为个人贷款批转业务史上规模最大的单次资产交易。此次交易标志着瑞京资产在个人贷款批转业务管理规模上突破300亿本金,排名行业前三甲。深入挖掘资产背后"人"的价值,支持全国特殊青年群体修复征信,重返社会信用体系,使更多青年赶上共同富裕的浪潮。', - statsData: [ - { num: "260 万+户", label: "减免债务惠及人群" }, - { num: "4 万+笔", label: "累计处置债务纠纷" }, - ], - }, - section4Data: { - title: "荣誉奖项", - items: [ - { title: "荣誉资质1" }, - { title: "荣誉资质2" }, - { title: "荣誉资质3" }, - { title: "荣誉资质4" }, - { title: "荣誉资质5" }, - { title: "荣誉资质6" }, - { title: "荣誉资质7" }, - { title: "荣誉资质8" }, - ], - }, - banner: { - title: "瑞京资产", - content: "助力实体经济健康发展", - titleSize: "medium", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - propertyService: { - section1Data: { - title: "银泰智享物业", - content: '管理有限公司是一家集品质物业服务、资产托管运营、智慧物联管理、科技平台创新运维为一体的专业化物业服务企业,致力于商办类物业运营管理、打造资产全周期生态服务。\n\n 凭借银泰集团多年城市商业地产运营经验不断深化创新,银泰智享积极拓展业务深度与广度,做强基础物业服务,深耕客户卓越服务体验,创造企业多元化价值。核心业务涵盖资产全托管服务、资产顾问服务、资产设施服务、物业品牌合作等,着力实现服务体系化、标准化、精细化、智慧化"四化合一",打造国内一流的物业管理品牌。', - statsData: [ - { num: "32 个", label: "全国在管项目" }, - { num: "475 万平方", label: "总建筑面积" }, - { num: "3 亿人次", label: "客流每年超" }, - { num: "350 亿元", label: "销售额每年" }, - { num: "5000 +", label: "合作品牌" }, - ], - }, - section2Data: { - title: "服务业态", - cardItems: [ - { title: "服务业态1", content: "服务业态1", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态2", content: "服务业态2", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态3", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态4", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - { title: "服务业态5", content: "服务业态3", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section3Data: { - title: "标杆项目", - items: [ - { title: "北京银泰中心", backgroundImage: "/images/bg-overview.png" }, - { title: "北京银泰吉祥大厦", backgroundImage: "/images/bg-overview.png" }, - { title: "杭州城西银泰城", backgroundImage: "/images/bg-overview.png" }, - { title: "杭州千岛湖银泰城", backgroundImage: "/images/bg-overview.png" }, - { title: "桐庐银泰城", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section4Data: { - title: "企业价值", - items: [ - { title: "荣誉资质1" }, - { title: "荣誉资质2" }, - { title: "荣誉资质3" }, - { title: "荣誉资质4" }, - { title: "荣誉资质5" }, - { title: "荣誉资质6" }, - { title: "荣誉资质7" }, - { title: "荣誉资质8" }, - ], - }, - banner: { - title: "物业服务", - content: "国内一流物业服务品牌", - titleSize: "medium", - showBreadcrumb: false, - backgroundImage: "/images/bg-overview.png", - }, - }, - }, - - news: { - media: { - banner: { - title: "媒体垂询", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - items: [ - { title: "新闻、采访拍摄", content: "如希望对银泰集团领导或具体项目进行采访、拍摄,请拟写采访申请并附上采访提纲后,提前10个工作日发送至 yintai.brand@china-yintai.com.cn" }, - { title: "联系我们", content: "综合类事项需求,请联系:(86-10) 8540 5700\n有采访类需求,请联系:(86-10) 8540 5757" }, - ], - }, - }, - public: { - banner: { - title: "集团发布", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - detail: { - banner: { - title: "汇聚立法智慧,培育立法人才", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - title: "汇聚立法智慧,培育立法人才", - createTime: "2026-03-03", - readTimes: "100", - content: "国以才立,政以才治,业以才兴,做好新形势下立法工作,保障立法质量,人才队伍是关键。自2020年起,在银泰公益基金会的支持下,浙江立法研究院、浙江大学立法研究院联合浙江大学光华法学院致力于助推立法学科建设,经过一年多时间的不懈努力,获批增设立法学二级学科,并面向全国招收立法学专业硕士、博士研究生,旨在积极响应新时代下国家对立法学理论研究和人才培养的需求,践行依法护航经济社会发展的理念,不断开展探索,助推立法工作更好地为中国特色社会主义法治建设服务。", - }, - }, - }, - - social: { - sustainability: { - section1Data: { - title: "银泰集团", - content: '始终秉持"创造价值,服务社会"的使命,将社会责任融入企业发展的各个环节,形成了以合规治理、实业报国、经典品质、人才发展、绿色低碳、公益向善为核心的六大责任方向。银泰积极践行新发展理念,深度融入国家发展大局,持续投身乡村振兴、儿童关爱、社区共建等公益事业,以实际行动诠释企业担当,为实现人与自然、社会和谐共生的美好未来贡献力量', - }, - section2Data: [ - { title: "合规治理", content: "银泰集团夯实治理基础,持续提升数字化、智慧化管理水平。坚守合规经营,加强风险管理,以良好的企业治理作为公司健康、稳定、持续发展的基石。", backgroundImage: "/images/bg-overview.png" }, - { title: "实业报国", content: "银泰集团坚定实业报国,积极投身国家重大战略和重点领域。通过优化产业布局,强化创新驱动,提升核心竞争力,为国家经济发展贡献力量。", backgroundImage: "/images/bg-overview.png" }, - { title: "经典品质", content: "银泰集团夯实治理基础,持续提升数字化、智慧化管理水平。坚守合规经营,加强风险管理,以良好的企业治理作为公司健康、稳定、持续发展的基石。", backgroundImage: "/images/bg-overview.png" }, - { title: "人才发展", content: "银泰集团夯实治理基础,持续提升数字化、智慧化管理水平。坚守合规经营,加强风险管理,以良好的企业治理作为公司健康、稳定、持续发展的基石。", backgroundImage: "/images/bg-overview.png" }, - { title: "绿色低碳", content: "银泰集团夯实治理基础,持续提升数字化、智慧化管理水平。坚守合规经营,加强风险管理,以良好的企业治理作为公司健康、稳定、持续发展的基石。", backgroundImage: "/images/bg-overview.png" }, - { title: "公益向善", content: "银泰集团夯实治理基础,持续提升数字化、智慧化管理水平。坚守合规经营,加强风险管理,以良好的企业治理作为公司健康、稳定、持续发展的基石。", backgroundImage: "/images/bg-overview.png" }, - ], - section3Data: { - title: "社会责任案例集", - content: '银泰集团通过挖掘内部员工,外部消费者、品牌方、合作伙伴、受益人等不同利益相关方的案例故事,希望以一个个真实、鲜活的人物为线索,全方位展现银泰的责任担当,让大家感受到"爱@在一起"的温暖和力量。', - items: [ - { title: "案例1向浙江大学教育基金会", content: "2019年,银泰公益基金会向浙江大学教育基金会捐赠资金250万元,专项支持浙江立法研究院的发展建设,助力汇聚立法智慧、培育立法人才、引领智能立法、致力于建成全国性的立法研究高地和人才培养基地。", link: "", backgroundImage: "/images/bg-overview.png" }, - { title: "案例2", content: "不管是从响应国家的绿色战略还是从企业自身长远发展的维度进行考量,提倡节能减排、绿色环保,都势在必行。", link: "", backgroundImage: "/images/bg-overview.png" }, - { title: "案例3", content: "案例3内容", link: "", backgroundImage: "/images/bg-overview.png" }, - { title: "案例4", content: "案例4内容", link: "", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section4Data: { - title: "社会责任报告", - items: Array(8).fill(null).map(() => ({ title: "2024年度报告.pdf", coverImage: "/images/bg-overview.png", link: "" })), - }, - banner: { - title: "可持续发展", - titleSize: "medium", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - foundation: { - section1Data: { - title: "银泰公益基金会", - content: "由银泰集团创始人兼董事长沈国军先生发起,于2014年初在北京成立。银泰集团希望以此为平台,以公益促进社会进步,用创新公益模式,立足生态环保、乡村振兴、应急救灾、公益教育等方向,用实际行动体现银泰人对社会责任的坚守和担当。", - backgroundImage: "/images/Foundation-sectionbg-1.png", - tabItems: [ - { tabName: "生态环保", contentTitle: "生态环保", contentSubtitle: "", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "乡村振兴", contentTitle: "银泰中心", contentSubtitle: "", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "应急救灾", contentTitle: "银泰中心", contentSubtitle: "", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - { tabName: "公益教育", contentTitle: "银泰中心", contentSubtitle: "", contentText: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", sideImage: "/images/bg-overview.png" }, - ], - }, - section2Data: { - title: "公益传播", - items: Array(4).fill(null).map((_, i) => ({ - title: `公益传播${i + 1}`, - content: "北京银泰中心是银泰置地集团在北京的核心项目,是集高端购物中心、酒店、公寓、超甲级写字楼等业态于一体的综合性商业地产项目。", - backgroundImage: "/images/bg-overview.png", - link: "", - })), - }, - section3Data: { - title: "信息公开", - tabItems: [ - { tabName: "规章制度", fileItems: Array(15).fill(null).map(() => ({ fileName: "规章制度1.pdf", link: "" })) }, - { tabName: "工作报告", fileItems: Array(5).fill(null).map(() => ({ fileName: "规章制度1.pdf", link: "" })) }, - { tabName: "审计报告", fileItems: Array(5).fill(null).map(() => ({ fileName: "规章制度1.pdf", link: "" })) }, - { tabName: "资质证书", fileItems: Array(5).fill(null).map(() => ({ fileName: "规章制度1.pdf", link: "" })) }, - { tabName: "组织架构", fileItems: Array(5).fill(null).map(() => ({ fileName: "规章制度1.pdf", link: "" })) }, - ], - backgroundImage: "/images/bg-overview.png", - }, - section4Data: { - title: "公益伙伴", - items: Array(6).fill(null).map(() => ({ logo: "/images/bg-overview.png" })), - }, - banner: { - title: "平台思维,共享价值", - titleSize: "medium", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - }, - - join: { - culture: { - banner: { - title: "企业文化", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - title: "企业文化", - items: [ - { title: "使命", content: "做新商业典范,律正合作共享", backgroundImage: "/images/bg-overview.png" }, - { title: "愿景", content: "成为世界级商业地产集团", backgroundImage: "/images/bg-overview.png" }, - { title: "核心价值观", content: "诚信、合作、创新、共赢", backgroundImage: "/images/bg-overview.png" }, - ], - }, - section2Data: { - title: "价值观", - items: [ - { title: "简单", content: "以心境简单 促问题解决", icon: "/images/bg-overview.png" }, - { title: "担当", content: "以心境简单 促问题解决", icon: "/images/bg-overview.png" }, - { title: "创新", content: "以心境简单 促问题解决", icon: "/images/bg-overview.png" }, - ], - }, - }, - campus: { - banner: { - title: "招贤纳士", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - }, - - others: { - siteMap: { - banner: { - title: "网站地图", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - section1Data: { - title: "网站地图", - items: [ - { - label: "关于银泰", - path: "/about", - children: [ - { path: "/about", label: "集团概览" }, - { path: "/about/history", label: "发展历程" }, - { path: "/about/founder", label: "创始人介绍" }, - ], - }, - { - label: "集团业务", - path: "/business", - children: [ - { - path: "/business/commercial-group", - label: "银泰商业集团", - children: [ - { path: "/business/commercial-group/in77", label: "in77" }, - { path: "/business/commercial-group/inPARK", label: "inPARK" }, - { path: "/business/commercial-group/银泰城购物中心", label: "银泰城购物中心" }, - ], - }, - { - path: "/business/base-group", - label: "银泰基业集团", - children: [ - { path: "/business/base-group#北京", label: "北京" }, - { path: "/business/base-group#上海", label: "上海" }, - { path: "/business/base-group#浙江", label: "浙江" }, - { path: "/business/base-group#四川", label: "四川" }, - ], - }, - { - path: "/business/realty-group", - label: "银泰置地集团", - children: [ - { path: "/business/realty-group#北京", label: "北京" }, - { path: "/business/realty-group#上海", label: "上海" }, - { path: "/business/realty-group#浙江", label: "浙江" }, - { path: "/business/realty-group#四川", label: "四川" }, - ], - }, - { - path: "/business/invest-group", - label: "银泰投资集团", - children: [ - { path: "/business/invest-group#发起设立", label: "发起设立" }, - { path: "/business/invest-group#股权投资", label: "股权投资" }, - { path: "/business/invest-group#产业孵化", label: "产业孵化" }, - ], - }, - { path: "/business/ruijing-group", label: "瑞京集团" }, - ], - }, - { - label: "社会责任", - path: "/social", - children: [ - { path: "/social/sustainability", label: "可持续发展" }, - { path: "/social/foundation", label: "银泰公益基金会" }, - ], - }, - { - label: "新闻中心", - path: "/news", - children: [ - { path: "/news/public", label: "集团发布" }, - { path: "/news/media", label: "媒体垂询" }, - ], - }, - { - label: "其它", - path: "/others", - children: [ - { path: "/join/campus", label: "加入银泰" }, - { path: "/terms-of-use", label: "使用条款" }, - { path: "/privacy-policy", label: "隐私保护" }, - ], - }, - ], - }, - }, - search: { - banner: { - title: "搜索结果", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/search-banner.png", - }, - }, - termsOfUse: { - banner: { - title: "使用条款", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - privacyPolicy: { - banner: { - title: "隐私保护", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - auditReport: { - banner: { - title: "审计举报", - titleSize: "large", - showBreadcrumb: true, - backgroundImage: "/images/bg-overview.png", - }, - }, - }, -}; - -const en: typeof zhCN = { - ...zhCN, - companyName: "Yintai", - company: { config: { favicon: "/favicon.ico", shortName: "Yintai" } }, - header: { - ...zhCN.header, - navItems: [ - { label: "Home", path: "/", index: true }, - { - label: "About Yintai", - path: "/about", - children: [ - { path: "/about/overview", label: "Overview" }, - { path: "/about/history", label: "History" }, - { path: "/about/founder", label: "Founder" }, - ], - }, - { - label: "Business", - path: "/business", - children: [ - { path: "/business/commercial-group", label: "Yintai Commercial" }, - { path: "/business/base-group", label: "Yintai Base" }, - { path: "/business/realty-group", label: "Yintai Realty" }, - { path: "/business/invest-group", label: "Yintai Investment" }, - { path: "/business/ruijing-group", label: "Ruijing Group" }, - ], - }, - { - label: "Social Responsibility", - path: "/social", - children: [ - { path: "/social/sustainability", label: "Sustainability" }, - { path: "/social/foundation", label: "Yintai Foundation" }, - ], - }, - { - label: "News", - path: "/news", - children: [ - { path: "/news/public", label: "Press" }, - { path: "/news/media", label: "Media" }, - ], - }, - { - label: "Join Yintai", - path: "/join", - children: [ - { path: "/join/culture", label: "Culture" }, - { path: "/join/campus", label: "Careers" }, - ], - }, - ] as NavItem[], - }, - footer: { - ...zhCN.footer, - 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.", - }, - home: { - ...zhCN.home, - banner: { - ...zhCN.home.banner, - title: "Yintai Group", - content: "A Model of Modern Commerce in China", - }, - }, -}; - -export type LocaleConfig = typeof zhCN; -const mockData = { "zh-CN": zhCN, "en-US": en }; -export default mockData; diff --git a/src/components/ScreenOpen/index.module.css b/src/components/ScreenOpen/index.module.css new file mode 100644 index 0000000..78bb7cc --- /dev/null +++ b/src/components/ScreenOpen/index.module.css @@ -0,0 +1,37 @@ +.screenOpen { + width: 100%; + height: 100vh; + position: fixed; + top: 0; + left: 0; + z-index: 1000; + background-color: transparent; + display: flex; + align-items: center; + justify-content: center; + + .screenOpenContent { + display: flex; + flex-direction: row; + overflow: hidden; + img { + width: 100px; + } + } + + .screenOpenBackground { + width: 100%; + height: 100vh; + position: absolute; + top: 0; + left: 0; + z-index: -1; + + .screenOpenBackgroundItem { + width: 100%; + height: 33.333%; + background-color: #fff; + } + } + +} \ No newline at end of file diff --git a/src/components/ScreenOpen/index.tsx b/src/components/ScreenOpen/index.tsx new file mode 100644 index 0000000..84db5bc --- /dev/null +++ b/src/components/ScreenOpen/index.tsx @@ -0,0 +1,57 @@ +import styles from "./index.module.css"; +import { motion } from "framer-motion"; +import { useState } from "react"; +import { useAppStore } from '@/store/app' +export default function ScreenOpen() { + const screenOpened = useAppStore((s) => s.screenOpened); + const setScreenOpened = useAppStore((s) => s.setScreenOpened); + const [data] = useState({ + logoParts: ["/images/open-screen/logo-left.png", "/images/open-screen/logo-right.png"], + }) + + if(screenOpened) return null; + + return ( +
+
+ { + data.logoParts.map((part, index) => ( + + logo-part + + )) + } +
+ {/* 3条白色背景 */} +
+ {[0, 1, 2].map((index) => ( + { + setScreenOpened(true); + }} + /> + ))} +
+
+ ) +} \ No newline at end of file diff --git a/src/components/ScrollReveal/animationPresets.ts b/src/components/ScrollReveal/animationPresets.ts new file mode 100644 index 0000000..05a52a5 --- /dev/null +++ b/src/components/ScrollReveal/animationPresets.ts @@ -0,0 +1,38 @@ +/** + * 滚动出现动画预设配置 + * 新增动画效果只需在此处添加配置即可,无需改动 ScrollReveal 组件 + */ +export type AnimationPreset = + | "fadeIn" + | "slideUp" + | "slideDown" + | "slideLeft" + | "slideRight"; + +export type VariantState = { + hidden: Record; + visible: Record; +}; + +export const ANIMATION_VARIANTS: Record = { + fadeIn: { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + }, + slideUp: { + hidden: { opacity: 0, y: 40 }, + visible: { opacity: 1, y: 0 }, + }, + slideDown: { + hidden: { opacity: 0, y: -40 }, + visible: { opacity: 1, y: 0 }, + }, + slideLeft: { + hidden: { opacity: 0, x: 60 }, + visible: { opacity: 1, x: 0 }, + }, + slideRight: { + hidden: { opacity: 0, x: -60 }, + visible: { opacity: 1, x: 0 }, + }, +}; diff --git a/src/components/ScrollReveal/index.tsx b/src/components/ScrollReveal/index.tsx new file mode 100644 index 0000000..15c3e6b --- /dev/null +++ b/src/components/ScrollReveal/index.tsx @@ -0,0 +1,56 @@ +import { motion, Variants } from "motion/react"; +import { + ANIMATION_VARIANTS, + type AnimationPreset, +} from "./animationPresets"; + +export type ScrollRevealProps = { + /** 动画预设:淡入、上/下/左/右滑入 */ + preset?: AnimationPreset; + children: React.ReactNode; + className?: string; + /** 是否只触发一次(进入视口后不再反向动画),默认 true */ + once?: boolean; + /** 元素进入视口的比例阈值 0~1,默认 0.2 表示露出 20% 即触发 */ + amount?: number; + /** 动画延迟(秒) */ + delay?: number; + /** 动画时长(秒),默认 0.6 */ + duration?: number; + /** 作为何种标签渲染,默认 div */ + as?: keyof typeof motion; +}; + +export default function ScrollReveal({ + preset = "fadeIn", + children, + className, + once = true, + amount = 0.5, + delay = 0, + duration = 0.7, + as: Component = "div", +}: ScrollRevealProps) { + const variant = ANIMATION_VARIANTS[preset]; + const MotionEl = motion[Component] as typeof motion.div; + + return ( + + {children} + + ); +} + +export { ANIMATION_VARIANTS }; +export type { AnimationPreset } from "./animationPresets"; diff --git a/src/components/banner.tsx b/src/components/banner.tsx index 961caf5..9933bd6 100644 --- a/src/components/banner.tsx +++ b/src/components/banner.tsx @@ -6,7 +6,8 @@ import "swiper/css/effect-fade"; import styles from "./Banner.module.css"; import { useMemo } from "react"; import { useStore } from "@/store"; -import type { BannerConfig } from "@/type"; +import type { BannerConfig, NavItem, NavChild } from "@/type"; +import ScrollReveal from "@/components/ScrollReveal"; const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)"; @@ -18,7 +19,6 @@ type Props = { desc?: string; content?: string; largedesc?: string; - showBreadcrumb?: boolean; titleSize?: "large" | "medium" | string; backgroundImage: string | string[]; }; @@ -29,7 +29,6 @@ export default function Banner({ desc, content, largedesc, - showBreadcrumb = true, titleSize = "large", backgroundImage, }: Props) { @@ -42,6 +41,8 @@ export default function Banner({ const isCarousel = images.length > 1; const descText = desc ?? content; + + const notShowBreadcrumbPaths = ["/"]; const breadcrumbItems = useMemo(() => { const segments = location.pathname.split("/").filter((s) => s !== ""); if (segments.length === 0) { @@ -52,11 +53,11 @@ export default function Banner({ paths.push((paths[i - 1] ?? "") + "/" + segments[i]); } const getLabelByPath = (path: string): string => { - if (path === "/") return navItems.find((n) => n.index)?.label ?? "首页"; - const top = navItems.find((n) => n.path === path); + if (path === "/") return navItems.find((n: NavItem) => n.path === "/")?.label ?? "首页"; + const top = navItems.find((n: NavItem) => n.path === path); if (top) return top.label; for (const item of navItems) { - const child = item.children?.find((c) => c.path === path); + const child = item.children?.find((c: NavChild) => c.path === path); if (child) return child.label; } const last = path.split("/").pop() ?? path; @@ -67,7 +68,7 @@ export default function Banner({ to: path, })); items.unshift({ - label: navItems.find((n) => n.index)?.label ?? "首页", + label: navItems.find((n: NavItem) => n.path === "/")?.label ?? "首页", to: "/", }); return items; @@ -75,19 +76,29 @@ export default function Banner({ const heroContent = (
-

{title}

- {subtitle &&

{subtitle}

} - {descText &&

{descText}

} - {largedesc &&

{largedesc}

} -
- {showBreadcrumb && - (breadcrumbItems ?? []).map((item, i) => ( - - {i > 0 && {" > "}} - {item.to ? {item.label} : {item.label}} - - ))} -
+ +

{title}

+
+ {subtitle && +

{subtitle}

+
} + {descText && +

{descText}

+
} + {largedesc && +

{largedesc}

+
} + +
+ { !notShowBreadcrumbPaths.includes(location.pathname) && + (breadcrumbItems ?? []).map((item, i) => ( + + {i > 0 && {" > "}} + {item.to ? {item.label} : {item.label}} + + ))} +
+
); return ( diff --git a/src/components/layout/AnimateTopCard/index.tsx b/src/components/layout/AnimateTopCard/index.tsx index b022ca6..e806159 100644 --- a/src/components/layout/AnimateTopCard/index.tsx +++ b/src/components/layout/AnimateTopCard/index.tsx @@ -4,7 +4,8 @@ type Data = { title: string; content: string; backgroundImage: string; - link: string; + path: string; + moreText: string; } export default function AnimateTopCard({ data }: { data: Data }) { @@ -16,7 +17,7 @@ export default function AnimateTopCard({ data }: { data: Data }) {
{data.content}
- 了解更多 + {data.moreText}
diff --git a/src/components/layout/Article/index.tsx b/src/components/layout/Article/index.tsx index 163e283..c50c9e5 100644 --- a/src/components/layout/Article/index.tsx +++ b/src/components/layout/Article/index.tsx @@ -4,7 +4,7 @@ import styles from "./index.module.css"; type Data = { title: string; createTime: string; - readTimes: string; + readTimes: string | number; content: string; } diff --git a/src/components/layout/ColumnXGrids/index.module.css b/src/components/layout/ColumnXGrids/index.module.css index 7bf1a30..1eeaf2c 100644 --- a/src/components/layout/ColumnXGrids/index.module.css +++ b/src/components/layout/ColumnXGrids/index.module.css @@ -1,3 +1,8 @@ +/* 定义 */ +:root { + --duration: 0.8s; +} + .columnXGrids { /* 3列 */ display: grid; @@ -7,12 +12,23 @@ .columnXGridsItem { color: #fff; aspect-ratio: 446/430; - background-size: cover; - background-position: center; - background-repeat: no-repeat; position: relative; overflow: hidden; + .bg { + position: absolute; + inset: 0; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + transition: transform 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94); + will-change: transform; + } + + &:hover .bg { + transform: scale(1.1); + } + .mask { position: absolute; top: 0; @@ -28,7 +44,7 @@ height: 100%; z-index: 2; padding: 60px 40px; - transition: background 0.3s ease; + transition: background var(--duration) ease; &:hover { background: rgba(20,53,92,0.7); @@ -51,7 +67,7 @@ color: #FFFFFF; line-height: 34px; opacity: 0; - transition: opacity 0.3s ease; + transition: opacity var(--duration) ease; } } diff --git a/src/components/layout/ColumnXGrids/index.tsx b/src/components/layout/ColumnXGrids/index.tsx index b92a7e3..38064da 100644 --- a/src/components/layout/ColumnXGrids/index.tsx +++ b/src/components/layout/ColumnXGrids/index.tsx @@ -12,7 +12,8 @@ export default function ColumnXGrids({ items }: Props) { return (
{items.map((item, index) => ( -
+
+
{item.title}
diff --git a/src/components/layout/JobPage/index.module.css b/src/components/layout/JobPage/index.module.css index 8d23e86..570b187 100644 --- a/src/components/layout/JobPage/index.module.css +++ b/src/components/layout/JobPage/index.module.css @@ -44,4 +44,26 @@ font-size: 20px; padding: 0 160px; } + + .jobPageContentTitle { + font-family: Source Han Sans, Source Han Sans; + font-weight: 600; + font-size: 24px; + color: #222222; + line-height: 34px; + text-align: left; + font-style: normal; + text-transform: none; + } + + .jobPageContentText { + font-family: Source Han Sans, Source Han Sans; + font-weight: 400; + font-size: 18px; + color: #333333; + line-height: 26px; + text-align: left; + font-style: normal; + text-transform: none; + } } \ No newline at end of file diff --git a/src/components/layout/JobPage/index.tsx b/src/components/layout/JobPage/index.tsx index 5382adc..5908151 100644 --- a/src/components/layout/JobPage/index.tsx +++ b/src/components/layout/JobPage/index.tsx @@ -9,6 +9,8 @@ type Data = { recruitNumber: string; jobLocation: string; content: string; + requirement: string; + contact: string; } export default function JobPage({ data }: { data: Data }) { @@ -31,7 +33,16 @@ export default function JobPage({ data }: { data: Data }) {
-
+
岗位描述
+

+
+
+
任职需求
+

+
+
+
联系方式
+

{data.contact}

) diff --git a/src/components/layout/RowAccordion/index.module.css b/src/components/layout/RowAccordion/index.module.css index f746635..cd6a12e 100644 --- a/src/components/layout/RowAccordion/index.module.css +++ b/src/components/layout/RowAccordion/index.module.css @@ -12,6 +12,7 @@ position: absolute; inset: 0; z-index: 0; + background-color: #0a0a0a; } .rowAccordionBgLayer { position: absolute; @@ -19,7 +20,8 @@ background-size: cover; background-position: center; background-repeat: no-repeat; - transition: opacity var(--duration) ease; + transition: opacity 1s cubic-bezier(0.4, 0, 0.2, 1); + will-change: opacity; } .rowAccordion .headerRow, .rowAccordion .contentRow { diff --git a/src/components/layout/RowAccordion/index.tsx b/src/components/layout/RowAccordion/index.tsx index e974c49..f2b9c7d 100644 --- a/src/components/layout/RowAccordion/index.tsx +++ b/src/components/layout/RowAccordion/index.tsx @@ -1,10 +1,37 @@ // 横向手风琴组件 -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; +import { motion, useInView, type Variants } from 'motion/react'; import styles from './index.module.css'; import { Link } from 'react-router-dom'; +const contentItemVariants: Variants = { + hidden: { opacity: 0, x: 80 }, + visible: { opacity: 1, x: 0 }, +}; + const FALLBACK_GRADIENT = "linear-gradient(0deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.5) 100%)"; +function smoothScrollTo(targetY: number, duration = 1200) { + const startY = window.scrollY; + const diff = targetY - startY; + if (Math.abs(diff) < 1) return; + let startTime: number | null = null; + + function easeInOutCubic(t: number) { + return t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2; + } + + function step(timestamp: number) { + if (!startTime) startTime = timestamp; + const elapsed = timestamp - startTime; + const progress = Math.min(elapsed / duration, 1); + window.scrollTo(0, startY + diff * easeInOutCubic(progress)); + if (progress < 1) requestAnimationFrame(step); + } + + requestAnimationFrame(step); +} + type Data = { title?: string; items: { @@ -28,8 +55,18 @@ type Props = { export default function RowAccordion({ data, placement='bottom' }: Props) { const [activeIndex, setActiveIndex] = useState(0); + const containerRef = useRef(null); + const isInView = useInView(containerRef, { once: true, margin: "0px 0px -20% 0px" }); + + useEffect(() => { + if (isInView && containerRef.current) { + const rect = containerRef.current.getBoundingClientRect(); + smoothScrollTo(window.scrollY + rect.top, 1200); + } + }, [isInView]); + return ( -
+
{data.items.map((item, index) => (
{data.items.map((item, index) => ( -
setActiveIndex(index)} + initial="hidden" + whileInView="visible" + viewport={{ once: true, amount: 0.2 }} + variants={contentItemVariants} + transition={{ + duration: 0.6, + delay: 0.5 + index * 0.12, + ease: [0.25, 0.46, 0.45, 0.94], + }} >
{item.title}
@@ -75,7 +123,7 @@ export default function RowAccordion({ data, placement='bottom' }: Props) { ) }
-
+ ))}
diff --git a/src/layouts/Footer.tsx b/src/layouts/Footer.tsx index bbf9199..5103120 100644 --- a/src/layouts/Footer.tsx +++ b/src/layouts/Footer.tsx @@ -1,13 +1,14 @@ import { Link } from "react-router-dom"; import styles from "./Footer.module.css"; import { useStore } from "@/store"; +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 footerColumns = header?.navItems?.filter((item) => !item.index) ?? []; + const footerColumns = header?.navItems?.filter((item: NavItem) => item.path !== "/") ?? []; const lowerLinks = footer?.lowerLinks ?? []; const socialIcons = footer?.socialIcons ?? []; const copyright = footer?.copyright ?? "版权声明©2001-{year} | 中国银泰投资有限公司"; @@ -18,10 +19,10 @@ export default function Footer() {
- {footerColumns.map((col) => ( + {footerColumns.map((col: NavItem) => (
{col.label}
- {col.children?.map((link) => ( + {col.children?.map((link: NavChild) => ( ))}
- {socialIcons.map((icon) => ( + {socialIcons.map((icon: { src: string; alt: string }) => ( s.setLocale); const supportLocales = useStore((s) => s.supportLocales); - const navItems = appConfig?.header?.navItems?.filter((item) => !item.index) ?? DEFAULT_NAV_ITEMS; + const navItems = appConfig?.header?.navItems?.filter((item: NavItem) => item.path !== "/") ?? DEFAULT_NAV_ITEMS; const langMenuItems: SupportLocale[] = supportLocales || []; - const logo = appConfig?.logo ?? "/images/logo.png"; + const logo = appConfig?.company?.logo ?? "/images/logo.png"; const [activeNav, setActiveNav] = useState(""); const [showDropPanel, setShowDropPanel] = useState(false); @@ -31,38 +32,33 @@ export default function Header() { } const activePanelItem = useMemo(() => { - return navItems.find((item) => item.path === activeNav)?.children || []; + return navItems.find((item: NavItem) => item.path === activeNav)?.children || []; }, [activeNav]); const [showWhiteMode, setShowWhiteMode] = useState(false); + const isDetailPage = location.pathname.includes("/detail/"); + const isDetailPageRef = useRef(isDetailPage); + isDetailPageRef.current = isDetailPage; useEffect(() => { - const path = location.pathname; - if (path.includes("/detail/")) { + if (isDetailPage) { setShowWhiteMode(true); - } else { - setShowWhiteMode(false); + return; } - }, [location.pathname]); + setShowWhiteMode(window.scrollY > 100); + }, [isDetailPage]); - // 监听滚动 useEffect(() => { const handleScroll = () => { - const scrollTop = window.scrollY; - if (scrollTop > 100) { - setShowWhiteMode(true); - } else { - setShowWhiteMode(false); - } - } - window.addEventListener("scroll", handleScroll); - return () => { - window.removeEventListener("scroll", handleScroll); + if (isDetailPageRef.current) return; + setShowWhiteMode(window.scrollY > 100); }; + window.addEventListener("scroll", handleScroll); + return () => window.removeEventListener("scroll", handleScroll); }, []); return ( -
setShowDropPanel(false)} >
@@ -72,7 +68,7 @@ export default function Header() {
+
@@ -106,14 +103,31 @@ export default function Header() {
- {showDropPanel && activePanelItem.length > 0 && setShowDropPanel(false)} />} + setShowDropPanel(false)} + show={showDropPanel && activePanelItem.length > 0} + />
); } -function DropPanel({ items, left, onLinkClick }: { items: NavChild[]; left: number, onLinkClick: () => void }) { - +function DropPanel({ items, left, onLinkClick, show }: { + items: NavChild[]; + left: number, + onLinkClick: () => void + show: boolean +}) { + const [visible, setVisible] = useState(show); + useEffect(() => { + const timeout = setTimeout(() => { + setVisible(show); + }, 100); + return () => { + clearTimeout(timeout); + } + }, [show]); + if (!visible) return null; return ( -
+
{items.map((item) => (
diff --git a/src/pages/About/Founder.tsx b/src/pages/About/Founder.tsx index ca56d80..f92a217 100644 --- a/src/pages/About/Founder.tsx +++ b/src/pages/About/Founder.tsx @@ -23,14 +23,13 @@ export default function AboutFounder() { title={banner?.title ?? ""} subtitle={banner?.subtitle} desc={banner?.content} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> {section1Data && (
- {section1Data.items?.map((item, index) => ( + {section1Data.items?.map((item: { title: string; content?: string; backgroundImage?: string }, index: number) => (
{item.title}
@@ -73,9 +72,9 @@ export default function AboutFounder() {
{Array.from({ - length: Math.max(0, ...(section3Data?.columns?.map((c) => c.length) ?? [0])), + length: Math.max(0, ...(section3Data?.columns?.map((c: { title?: string }[]) => c.length) ?? [0])), }).flatMap((_, rowIndex) => - (section3Data?.columns ?? []).map((colItems, colIndex) => ( + (section3Data?.columns ?? []).map((colItems: { title?: string }[], colIndex: number) => (
{colItems[rowIndex] ?
  • {colItems[rowIndex].title}
  • : null}
    diff --git a/src/pages/About/History.module.css b/src/pages/About/History.module.css index 09e1b8f..25ba9c6 100644 --- a/src/pages/About/History.module.css +++ b/src/pages/About/History.module.css @@ -49,6 +49,7 @@ align-items: flex-start; min-height: 6rem; margin-bottom: 1rem; + scroll-margin-top: 120px; } .timelineItem .side { @@ -123,6 +124,7 @@ width: 1.25rem; height: 1.25rem; background: #14355C; + transition: all 0.3s ease-in-out; } .dotWrapper.selected::before { @@ -136,6 +138,7 @@ border: 2px solid #14355C; border-radius: 50%; background: transparent; + transition: all 0.3s ease-in-out; } .dotLine { @@ -146,8 +149,10 @@ width: 0.375rem; min-height: 0; background: #14355C; + transition: all 0.9s ease-in-out; } + @media (max-width: 1024px) { .section { padding: 4rem 4rem; diff --git a/src/pages/About/History.tsx b/src/pages/About/History.tsx index 785eca8..52cef3f 100644 --- a/src/pages/About/History.tsx +++ b/src/pages/About/History.tsx @@ -1,19 +1,18 @@ import Banner from "@/components/Banner"; import YearPicker from "@/components/YearPicker"; import styles from "./History.module.css"; -import { useState, useRef, useLayoutEffect } from "react"; +import { useState, useRef, useLayoutEffect, useEffect, useMemo } from "react"; import { useStore } from "@/store"; - -type TimelineItem = { year: number; content: string }; +import appApi from "@/api/app"; +type TimelineItem = { year: number; content: string, lang: string }; export default function AboutHistory() { const appConfig = useStore((s) => s.appConfig); + const locale = useStore((s) => s.locale); + const history = appConfig?.about?.history; const banner = history?.banner; - const section1Data = (history?.section1Data ?? []) as TimelineItem[]; - const [year, setYear] = useState(null); - const handleYearChange = (year: number | null) => { setYear(year); const yearEl = document.querySelector(`#year-${year}`); @@ -22,6 +21,25 @@ export default function AboutHistory() { } }; + const [processList, setProcessList] = useState([]); + const localProcessList = useMemo(() => { + return processList.filter(item => item.lang.toLowerCase() === locale.split('-')[0]); + }, [processList, locale]); + + // 接口数据 + useEffect(() => { + appApi.getProcessList().then((res) => { + const items = res.data.items.map((item:any) => { + return { + year: item.title, + content: item.content, + lang: item.lang, + } + }) + setProcessList(items); + }); + }, []) + if (!history) return null; return ( @@ -29,7 +47,6 @@ export default function AboutHistory() { @@ -38,7 +55,7 @@ export default function AboutHistory() {
    diff --git a/src/pages/About/overview.tsx b/src/pages/About/overview.tsx index 2540145..0087879 100644 --- a/src/pages/About/overview.tsx +++ b/src/pages/About/overview.tsx @@ -2,6 +2,7 @@ import { Link } from "react-router-dom"; import styles from "./About.module.css"; import Banner from "@/components/Banner"; import { useStore } from "@/store"; +import ScrollReveal from "@/components/ScrollReveal"; const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)"; @@ -10,7 +11,7 @@ export default function About() { const overview = appConfig?.about?.overview; const banner = overview?.banner; - const section1Data = overview?.section1Data ?? []; + const section1Data = overview?.section1Data?.items ?? []; if (!overview) return null; @@ -19,11 +20,10 @@ export default function About() { - {section1Data.map((item, index) => ( + {section1Data.map((item: { title: string; content?: string; backgroundImage?: string; links?: { label: string; path: string }[] }, index: number) => (
    -
    -

    {item.title}

    -

    {item.content}

    -
    - {item.links?.map((link) => ( - - {link.label} - - ))} + +
    +

    {item.title}

    +

    {item.content}

    +
    + {item.links?.map((link: { label: string; path: string }) => ( + + {link.label} + + ))} +
    -
    +
    ))} diff --git a/src/pages/Business/BaseGroup.tsx b/src/pages/Business/BaseGroup.tsx index 1c781e8..97d92c5 100644 --- a/src/pages/Business/BaseGroup.tsx +++ b/src/pages/Business/BaseGroup.tsx @@ -43,7 +43,6 @@ export default function BaseGroup() { title={banner?.title ?? ""} desc={banner?.content} titleSize={banner?.titleSize as "medium" | "large" | undefined ?? "medium"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> diff --git a/src/pages/Business/CommercialGroup.tsx b/src/pages/Business/CommercialGroup.tsx index 8d52460..278d5b9 100644 --- a/src/pages/Business/CommercialGroup.tsx +++ b/src/pages/Business/CommercialGroup.tsx @@ -34,7 +34,6 @@ export default function BusinessCommercialGroup() { title={banner?.title ?? ""} desc={banner?.content} titleSize={banner?.titleSize as "medium" | "large" | undefined ?? "medium"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-commercial-group.png"} /> diff --git a/src/pages/Business/CommercialGroupDetail.tsx b/src/pages/Business/CommercialGroupDetail.tsx index dc280bd..d6587b3 100644 --- a/src/pages/Business/CommercialGroupDetail.tsx +++ b/src/pages/Business/CommercialGroupDetail.tsx @@ -20,7 +20,6 @@ export default function BusinessCommercialGroupDetail() { title={banner?.title ?? ""} largedesc={(banner as BannerConfig)?.largeContent} titleSize={(banner as BannerConfig)?.titleSize ?? "large"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-commercial-group.png"} /> diff --git a/src/pages/Business/InvestGroup.tsx b/src/pages/Business/InvestGroup.tsx index 93513bc..79f6828 100644 --- a/src/pages/Business/InvestGroup.tsx +++ b/src/pages/Business/InvestGroup.tsx @@ -23,7 +23,6 @@ export default function InvestGroup() { title={banner?.title ?? ""} desc={banner?.content} titleSize={banner?.titleSize as "medium" | "large" | undefined ?? "medium"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> diff --git a/src/pages/Business/RealtyGroup.tsx b/src/pages/Business/RealtyGroup.tsx index 5697a57..b9d684d 100644 --- a/src/pages/Business/RealtyGroup.tsx +++ b/src/pages/Business/RealtyGroup.tsx @@ -39,7 +39,6 @@ export default function RealtyGroup() { title={banner?.title ?? ""} desc={banner?.content} titleSize={banner?.titleSize as "medium" | "large" | undefined ?? "medium"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> diff --git a/src/pages/Business/RuijingGroup.tsx b/src/pages/Business/RuijingGroup.tsx index 1cfe4fd..c6b583b 100644 --- a/src/pages/Business/RuijingGroup.tsx +++ b/src/pages/Business/RuijingGroup.tsx @@ -36,7 +36,6 @@ export default function RuijingGroup() { title={banner?.title ?? ""} desc={banner?.content} titleSize={banner?.titleSize as "medium" | "large" | undefined ?? "medium"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> diff --git a/src/pages/Home/Home.module.css b/src/pages/Home/Home.module.css index 77d6532..801ac91 100644 --- a/src/pages/Home/Home.module.css +++ b/src/pages/Home/Home.module.css @@ -260,13 +260,13 @@ .newsFeatured { overflow: hidden; + cursor: pointer; } .newsFeaturedImgWrap { width: 59.375rem; aspect-ratio: 950 / 560; background: linear-gradient(135deg, #e8e8e8 0%, #d0d0d0 100%); - background: red; overflow: hidden; position: relative; } @@ -294,6 +294,12 @@ gap: 0.625rem; } +.newsItemDateWrap { + display: flex; + align-items: center; + justify-content: space-between; +} + .newsItem { box-sizing: border-box; padding: 1.5rem 1.875rem 1.25rem 1.875rem; @@ -302,15 +308,36 @@ display: flex; flex-direction: column; justify-content: space-between; + cursor: pointer; + + .newsItemArrowIcon { + transition: transform 0.3s ease; + } + + &.active { + .newsItemTitle { + color: #14355C; + font-weight: 600; + } + .newsItemSnippet { + color: #333; + } + .newsItemArrowIcon { + color: #14355C; + } + } } + + .newsItemTitle { font-size: 1.25rem; font-weight: 500; - color: #333; + color: #222222; margin: 0 0 0.5rem; line-height: 1.4; + transition: color 0.3s ease-in-out; } .newsItemTitle a { @@ -327,6 +354,7 @@ color: #666; margin: 0 0 0.5rem; line-height: 1.6; + height: 75px; display: -webkit-box; -webkit-line-clamp: 2; @@ -339,3 +367,7 @@ font-size: 0.875rem; color: #999; } + + + + diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 658a670..0563e41 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -1,9 +1,18 @@ import { useStore } from "@/store"; +import { Link } from "react-router-dom"; import styles from "./Home.module.css"; import Banner from "@/components/Banner"; import Section from "@/components/layout/Section"; import RowAccordion from "@/components/layout/RowAccordion"; -import { Link } from "react-router-dom"; +import ScreenOpen from "@/components/ScreenOpen"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { motion, type Variants } from "motion/react"; +import { ArrowRightOutlined } from "@ant-design/icons"; +import appApi from "@/api/app"; +const cardVariants: Variants = { + hidden: { opacity: 0, y: 220 }, + visible: { opacity: 1, y: 0 }, +}; export default function Home() { const appConfig = useStore((s) => s.appConfig); @@ -11,76 +20,168 @@ export default function Home() { const banner = home?.banner; const section1Data = home?.section1Data; - const section2Data = home?.section2Data ?? []; - const newsData = home?.newsData ?? []; + const section2Data = home?.section2Data?.items ?? []; if (!home) return null; return (
    + {/* 开屏动画 */} + {/* Hero */} {/* Commercial */} - {section1Data && } + {section1Data && + + } {/* 首页名片 */}
    - {section2Data.map((item, i) => ( -
    -
    -
    -
    -

    {item.title}

    -

    {item.content}

    -
    -
    + {section2Data.map((item: any, i: number) => ( + + +
    +
    +
    +

    {item.title}

    +

    {item.content}

    +
    + + ))}
    - {/* News 动态数据 */} -
    -
    -
    -
    - 新闻配图 { - (e.target as HTMLImageElement).style.display = "none"; - }} - /> -

    - 银泰集团联合钱塘产业集团竞得杭州东部湾新城地块 -

    -
    -
    -
    - {newsData.map((item) => ( -
    -

    - {item.title} -

    -

    {item.snippet}

    - {item.date} -
    - ))} -
    -
    -
    +
    ); } + + +function News() { + const locale = useStore((s) => s.locale); + const [newsData, setNewsData] = useState([]); + const videoRef = useRef(null); + const localNewsData = useMemo(() => { + return newsData.filter((item) => item.lang.toLowerCase() === locale.split('-')[0]); + }, [newsData, locale]); + const [activeNewsIndex, setActiveNewsIndex] = useState(0); + const handleNewsEnter = (index: number) => { + setActiveNewsIndex(index); + }; + + const handleVideoPlay = () => { + if (videoRef.current) { + videoRef.current.play(); + } + }; + + const handleVideoPause = () => { + if (videoRef.current) { + videoRef.current.pause(); + videoRef.current.currentTime = 0; + } + }; + + const handleSearch = useCallback((category_id: any) => { + appApi.getNewsList({ page: 1, size: 6, sort: "create_time DESC", category_id }).then((res) => { + const data = res.data.items.map((item: any) => { + return { + id: item.id, + title: item.title, + date: item.create_time, + image: item.covers_show === 'image' ? item.covers.image[0] : '', + video: item.covers_show === 'video' ? item.covers.video[0] : '', + snippet: item.content, + lang: item.lang, + path: '/news/detail/' + item.id, + } + }) + setNewsData(data); + }); + }, []); + const getCategoryList = useCallback(async () => { + const res = await appApi.getCategoryList('news'); + const category_id = res.data.items.find((item: any) => item.name.includes('新闻资讯'))?.id; + return category_id; + }, []); + + useEffect(() => { + getCategoryList().then((category_id) => { + handleSearch(category_id) + }); + }, []) + return ( +
    +
    +
    +
    + { + localNewsData[activeNewsIndex]?.image ? ( + 新闻配图 { + (e.target as HTMLImageElement).style.display = "none"; + }} + /> + ) : ( + + ) + } + +

    + 银泰集团联合钱塘产业集团竞得杭州东部湾新城地块 +

    +
    +
    +
    + {localNewsData.map((item, index) => ( +
    handleNewsEnter(index)}> + +

    + {item.title} +

    +

    {item.snippet}

    +
    + {item.date} + +
    + +
    + ))} +
    +
    +
    + ); +} \ No newline at end of file diff --git a/src/pages/Join/Campus.tsx b/src/pages/Join/Campus.tsx index 55470c2..818895d 100644 --- a/src/pages/Join/Campus.tsx +++ b/src/pages/Join/Campus.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import styles from "./Campus.module.css"; import Banner, { type BannerConfig } from "@/components/Banner"; import Section from "@/components/layout/Section"; @@ -8,16 +8,20 @@ import { Empty, Select } from "antd"; import Pagination from "@/components/Pagination"; import { Link } from "react-router-dom"; import { debounce } from "@/utils"; +import appApi from "@/api/app"; type JobItem = { id: number; title: string; content: string; labels: string[]; + lang: string } export default function JoinCampus() { const appConfig = useStore((s) => s.appConfig); + const supportLocales = useStore((s) => s.supportLocales); + const locale = useStore((s) => s.locale); const data = appConfig?.join?.campus; const banner = data?.banner; @@ -25,37 +29,69 @@ export default function JoinCampus() { // 职业类别 业务领域 所属板块 const [jobType, setJobType] = useState(''); - const [jobTypeOptions, setJobTypeOptions] = useState([ - { label: "全部", value: "" }, - { label: "职业类别1", value: "1" }, - { label: "职业类别2", value: "2" }, - { label: "职业类别3", value: "3" }, - ]); + const [jobTypeOptions, setJobTypeOptions] = useState([]); const [businessArea, setBusinessArea] = useState(''); const [businessAreaOptions, setBusinessAreaOptions] = useState([]); const [businessPlate, setBusinessPlate] = useState(''); const [businessPlateOptions, setBusinessPlateOptions] = useState([]); const [page, setPage] = useState(1); - const [size] = useState(9); + const [size] = useState(2 * supportLocales.length); const [total, setTotal] = useState(1000); const [jobList, setJobList] = useState([]); + const localJobList = useMemo(() => { + return jobList.filter(item => item.lang.toLowerCase() === locale.split('-')[0]); + }, [jobList, locale]); - const refreshData = useCallback(debounce(() => { - console.log('refreshData2'); - setJobList([ - { id: 1, title: '职位1', content: '工作职责:1、为集团的各类投资项目提供法律支持,包括:组织外部律师进行尽职调查、审阅及起草交易文件、必要时参与法律谈判、提示法律风险等;2、协助完善集团本部的规章制度和合规体系;3、审阅集团各部门提交法务部审阅的日常业务法务部审阅的日常业务法务部审阅的日常业务', labels: ['标签1', '标签2'] }, - { id: 2, title: '职位2', content: '职位2内容', labels: ['标签1', '标签2'] }, - { id: 3, title: '职位3', content: '职位3内容', labels: ['标签1', '标签2'] }, - ]) + // 用 ref 保存最新参数,保证 debounce 使用稳定的函数引用 + const paramsRef = useRef({ searchValue, jobType, businessArea, businessPlate, page, size }); + paramsRef.current = { searchValue, jobType, businessArea, businessPlate, page, size }; + + const refreshData = useMemo(() => debounce(() => { + const { searchValue: sv, jobType: jt, businessArea: ba, businessPlate: bp, page: p, size: s } = paramsRef.current; + appApi.getJobList({ page: p, size: s, sort: "", title: sv, job_type: jt, business_area: ba, business_plate: bp }).then((res) => { + const items = res.data.items.map((item: any) => { + const { job_type_name, job_area_name, job_unit_name } = item.category; + const labels = [job_type_name, job_area_name, job_unit_name]; + return { + id: item.id, + title: item.title, + content: item.description, + labels, + lang: item.lang, + }; + }); + setJobList(items || []); + setTotal(res.data.total); + }); }, 500), []); + const getTypes = useCallback(() => { + ['job_type', 'job_area', 'job_unit'].forEach(type => { + appApi.getCategoryList(type).then((res) => { + const items = res.data.items.map((item:any) => ({ label: item.name, value: item.id })); + items.unshift({ label: "全部", value: "" }); + if (type === 'job_type') { + setJobTypeOptions(items); + } else if (type === 'job_area') { + setBusinessAreaOptions(items); + } else if (type === 'job_unit') { + setBusinessPlateOptions(items); + } + }) + }) + }, []); + useEffect(() => { refreshData(); }, [searchValue, jobType, businessArea, businessPlate, page, size]); + useEffect(() => { + getTypes(); + }, []); + const handleReset = useCallback(() => { setSearchValue(''); setJobType(''); @@ -70,7 +106,6 @@ export default function JoinCampus() { title={banner?.title ?? "招贤纳士"} content={(banner as BannerConfig)?.content} titleSize={(banner as BannerConfig)?.titleSize ?? "large"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> @@ -88,21 +123,21 @@ export default function JoinCampus() {
    {/* 没有数据时显示 */} - {jobList.length === 0 && ( + {localJobList.length === 0 && (
    )} - {jobList.map(item => ( - -
    + {localJobList.map((item, index) => ( + +
    {item.title}
    查看详情
    - {item.labels.map(label => ( -
     •  {label}
    + {item.labels.map((label, index) => ( +
     •  {label}
    ))}
    {item.content}
    diff --git a/src/pages/Join/CampusDetail.tsx b/src/pages/Join/CampusDetail.tsx index 86eb63b..9798d05 100644 --- a/src/pages/Join/CampusDetail.tsx +++ b/src/pages/Join/CampusDetail.tsx @@ -1,18 +1,46 @@ import JobPage from "@/components/layout/JobPage"; - +import { useParams } from "react-router-dom"; +import appApi from "@/api/app"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { useStore } from "@/store"; export default function CampusDetail() { - const data = { - title: "项目营销总监", - jobType: "营销总监", - businessArea: "营销", - businessPlate: "营销", - recruitNumber: "2", - jobLocation: "杭州", - content: "国以才立,政以才治,业以才兴,做好新形势下立法工作,保障立法质量,人才队伍是关键。自2020年起,在银泰公益基金会的支持下,浙江立法研究院、浙江大学立法研究院联合浙江大学光华法学院致力于助推立法学科建设,经过一年多时间的不懈努力,获批增设立法学二级学科,并面向全国招收立法学专业硕士、博士研究生,旨在积极响应新时代下国家对立法学理论研究和人才培养的需求,践行依法护航经济社会发展的理念,不断开展探索,助推立法工作更好地为中国特色社会主义法治建设服务。", - } + const locale = useStore((s) => s.locale); + const params = useParams(); + const id = params.id as string; + const [jobDetail, setJobDetail] = useState(null); + const localJobDetail = useMemo(() => { + return jobDetail?.find((item: any) => item.lang.toLowerCase() === locale.split('-')[0]); + }, [jobDetail, locale]); + + const getJobDetail = useCallback(() => { + appApi.getJobDetail(id).then((res) => { + const items = res.data.map((item:any) => { + return { + title: item.title, + jobType: item.category.job_type_name, + businessArea: item.category.job_area_name, + businessPlate: item.category.job_unit_name, + recruitNumber: item.recruit_count, + jobLocation: item.city, + content: item.description, + requirement: item.requirement, + lang: item.lang, + contact: item.contact, + } + }); + setJobDetail(items); + }) + }, [id]) + + useEffect(() => { + getJobDetail() + }, []) return (
    - + { + localJobDetail && + + }
    ) } \ No newline at end of file diff --git a/src/pages/Join/Culture.tsx b/src/pages/Join/Culture.tsx index 6dd80ad..9c89366 100644 --- a/src/pages/Join/Culture.tsx +++ b/src/pages/Join/Culture.tsx @@ -19,7 +19,6 @@ export default function Culture() { title={banner?.title ?? ""} content={(banner as BannerConfig)?.content} titleSize={(banner as BannerConfig)?.titleSize ?? "large"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> @@ -30,7 +29,7 @@ export default function Culture() { maskBackground="#D8D8D8" >
    - {section1Data.items?.map((item, index) => ( + {section1Data.items?.map((item: any, index: number) => (
    - {section2Data.items?.map((item, index) => ( + {section2Data.items?.map((item: { title: string; content?: string; icon?: string }, index: number) => (
    s.appConfig); - const data = appConfig?.news?.detail; + const locale = useStore((s) => s.locale); + const params = useParams(); + const id = params.id as string; + const [newsDetailList, setNewsDetailList] = useState(); + const newsDetail = useMemo(() => { + return newsDetailList?.find((item) => item.lang.toLowerCase() === locale.split('-')[0]); + }, [newsDetailList, locale]); - if (!data) return null; + useEffect(() => { + appApi.getNewsDetail(id).then((res) => { + const data = res.data.map((item: any) => { + return { + id: item.id, + title: item.title, + createTime: item.create_time, + readTimes: item.count, + content: item.content, + lang: item.lang, + } + }) + setNewsDetailList(data) + }) + }, [id]) - const section1Data = data.section1Data; - - const articleData = section1Data - ? { - title: section1Data.title, - createTime: section1Data.createTime, - readTimes: section1Data.readTimes, - content: section1Data.content, - } - : null; return (
    - {articleData &&
    } + {newsDetail &&
    }
    ); } diff --git a/src/pages/News/Media.tsx b/src/pages/News/Media.tsx index 0f82e81..5d0fce6 100644 --- a/src/pages/News/Media.tsx +++ b/src/pages/News/Media.tsx @@ -19,13 +19,12 @@ export default function Media() { title={banner?.title ?? ""} content={(banner as BannerConfig)?.content} titleSize={(banner as BannerConfig)?.titleSize ?? "large"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} />
    - {items.map((item, index) => ( + {items.map((item: { title: string; content?: string }, index: number) => (
    {item.title}
    {item.content}
    diff --git a/src/pages/News/NewsPublic.module.css b/src/pages/News/NewsPublic.module.css index 7c0e636..b1040f0 100644 --- a/src/pages/News/NewsPublic.module.css +++ b/src/pages/News/NewsPublic.module.css @@ -39,6 +39,7 @@ .newList { /* 3列 */ + min-height: 200px; margin-top: 100px; margin-bottom: 100px; display: grid; @@ -53,12 +54,13 @@ display: flex; flex-direction: column; - img { + img, video { width: 100%; /* height: 300px; */ aspect-ratio: 452 / 300; object-fit: cover; cursor: pointer; + transition: all 0.5s ease; } &:hover { @@ -70,6 +72,10 @@ .newItemCreateTime { color: #fff !important; } + + img { + transform: scale(1.05); + } } .newItemContent { diff --git a/src/pages/News/NewsPublic.tsx b/src/pages/News/NewsPublic.tsx index d0bb414..f8328c6 100644 --- a/src/pages/News/NewsPublic.tsx +++ b/src/pages/News/NewsPublic.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import styles from "./NewsPublic.module.css"; import Banner, { type BannerConfig } from "@/components/Banner"; import Section from "@/components/layout/Section"; @@ -6,27 +6,69 @@ import { SearchOutlined } from "@ant-design/icons"; import Pagination from "@/components/Pagination"; import { Link } from "react-router-dom"; import { useStore } from "@/store"; +import appApi from "@/api/app"; + +type NewsItem = { + id: number; + title: string; + createTime: string; + image: string; + video: string; + lang: "ZH" | "EN" +} export default function NewsPublic() { const appConfig = useStore((s) => s.appConfig); + const locale = useStore((s) => s.locale); + const supportLocales = useStore((s) => s.supportLocales); const data = appConfig?.news?.public; - const [newList] = useState([ - { id: 1, title: "新闻标题", createTime: "2026-03-03", image: "/images/bg-overview.png" }, - { id: 2, title: "新闻标题", createTime: "2026-03-03", image: "/images/bg-overview.png" }, - { id: 3, title: "新闻标题", createTime: "2026-03-03", image: "/images/bg-overview.png" }, - ]); + const [page, setPage] = useState(1); + const [size] = useState(9 * supportLocales.length); + const [total, setTotal] = useState(0); + const categoryIdRef = useRef(''); + + const [newList, setNewList] = useState([]); + const videoRefs = useRef<(HTMLVideoElement | null)[]>([]); const [searchValue, setSearchValue] = useState(""); const handleSearch = useCallback(() => { - console.log("search", searchValue); - }, [searchValue]); + appApi.getNewsList({ page, size, sort: "create_time DESC", title: searchValue, + category_id: categoryIdRef.current ?? '', + }).then((res) => { + const data = res.data.items.map((item:any) => { + return { + id: item.id, + title: item.title, + createTime: item.create_time, + image: item.covers_show === 'image' ? item.covers.image[0] : '', + video: item.covers_show === 'video' ? item.covers.video[0] : '', + lang: item.lang, + } + }) + setNewList(data); + setTotal(res.data.total); + }); + }, [searchValue, page, size]); - const [page, setPage] = useState(1); - const [size] = useState(9); - const [total, setTotal] = useState(1000); + const localNewsList = useMemo(() => { + return newList.filter(item => item.lang.toLowerCase() === locale.split('-')[0]); + }, [newList, locale]); + + const getCategoryList = useCallback(async () => { + const res = await appApi.getCategoryList('news'); + const category_id = res.data.items.find((item: any) => item.name.includes('集团发布'))?.id; + categoryIdRef.current = category_id; + return category_id; + }, []); const banner = data?.banner; + useEffect(() => { + getCategoryList().then(() => { + handleSearch(); + }) + }, [page, size]); + if (!data) return null; return ( @@ -35,7 +77,6 @@ export default function NewsPublic() { title={banner?.title ?? ""} content={(banner as BannerConfig)?.content} titleSize={(banner as BannerConfig)?.titleSize ?? "large"} - showBreadcrumb={banner?.showBreadcrumb ?? false} backgroundImage={banner?.backgroundImage ?? "/images/bg-overview.png"} /> @@ -56,13 +97,33 @@ export default function NewsPublic() {
    - {newList.map((item, index) => ( + {localNewsList.map((item, index) => ( - {item.title} + {item.image ? ( + {item.title} + ) : ( +