This commit is contained in:
zhangjianjun 2026-03-05 11:04:03 +08:00
parent f32745850e
commit 3afedb162d
8 changed files with 266 additions and 38 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

View File

@ -24,6 +24,7 @@ import TermsOfUse from "@/pages/Others/TermsOfUse";
import PrivacyPolicy from "@/pages/Others/PrivacyPolicy"; import PrivacyPolicy from "@/pages/Others/PrivacyPolicy";
import AuditReport from "@/pages/Others/AuditReport"; import AuditReport from "@/pages/Others/AuditReport";
import SiteMap from "@/pages/Others/SiteMap"; import SiteMap from "@/pages/Others/SiteMap";
import Search from "@/pages/Others/Search";
const routes: RouteObject[] = [ const routes: RouteObject[] = [
{ {
@ -55,6 +56,8 @@ const routes: RouteObject[] = [
{ path: "join/campus/detail/:id", element: <JoinCampusDetail /> }, { path: "join/campus/detail/:id", element: <JoinCampusDetail /> },
// 物业服务 // 物业服务
{ path: "/property-service", element: <PropertyService /> }, { path: "/property-service", element: <PropertyService /> },
// 搜索
{ path: "/search", element: <Search /> },
// 其它 // 其它
// 使用条款 隐私保护 审计举报 网站地图 // 使用条款 隐私保护 审计举报 网站地图
{ path: "/terms-of-use", element: <TermsOfUse /> }, { path: "/terms-of-use", element: <TermsOfUse /> },

View File

@ -1,5 +1,6 @@
const mockData = { const mockData = {
companyName: "银泰" companyName: "银泰",
logo: '/images/logo.png',
} }

View File

@ -125,9 +125,9 @@ export default function Header() {
</ul> </ul>
</nav> </nav>
<div className={styles.actions}> <div className={styles.actions}>
<button className={styles.searchBtn} type="button" aria-label="搜索"> <Link to="/search" className={styles.searchBtn} type="button" aria-label="搜索">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1" width="26" height="26" viewBox="0 0 26 26"><g><path d="M16.739973374999998,17.76985499081421C15.429279375,18.85114099081421,13.749150275,19.50064899081421,11.917317875,19.50064899081421C7.729150975,19.50064899081421,4.333984375,16.105480990814208,4.333984375,11.91731549081421C4.333984375,7.729148590814209,7.729150975,4.333981990814209,11.917317875,4.333981990814209C16.105485375,4.333981990814209,19.500651375,7.729148590814209,19.500651375,11.91731549081421C19.500651375,13.80559489081421,18.810497375,15.532677990814209,17.668674375000002,16.86007799081421L21.741985375,20.93338899081421C21.953518375,21.144921990814208,21.953518375,21.48788599081421,21.741983375,21.69941999081421L21.588777375,21.852625990814207C21.377243375,22.06416099081421,21.034278375,22.06416099081421,20.822744375,21.852625990814207L16.739973374999998,17.76985499081421ZM18.199479375,11.916142890814209C18.199479375,15.38633899081421,15.386343375,18.199475990814207,11.916145775,18.199475990814207C8.445947675,18.199475990814207,5.632812475,15.38633899081421,5.632812475,11.916142890814209C5.632812475,8.44594479081421,8.445947675,5.632810090814209,11.916145775,5.632810090814209C15.386343375,5.632810090814209,18.199479375,8.44594479081421,18.199479375,11.916142890814209Z" fillRule="evenodd" fill="#FFFFFF" fillOpacity="1" /></g></svg> <svg xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1" width="26" height="26" viewBox="0 0 26 26"><g><path d="M16.739973374999998,17.76985499081421C15.429279375,18.85114099081421,13.749150275,19.50064899081421,11.917317875,19.50064899081421C7.729150975,19.50064899081421,4.333984375,16.105480990814208,4.333984375,11.91731549081421C4.333984375,7.729148590814209,7.729150975,4.333981990814209,11.917317875,4.333981990814209C16.105485375,4.333981990814209,19.500651375,7.729148590814209,19.500651375,11.91731549081421C19.500651375,13.80559489081421,18.810497375,15.532677990814209,17.668674375000002,16.86007799081421L21.741985375,20.93338899081421C21.953518375,21.144921990814208,21.953518375,21.48788599081421,21.741983375,21.69941999081421L21.588777375,21.852625990814207C21.377243375,22.06416099081421,21.034278375,22.06416099081421,20.822744375,21.852625990814207L16.739973374999998,17.76985499081421ZM18.199479375,11.916142890814209C18.199479375,15.38633899081421,15.386343375,18.199475990814207,11.916145775,18.199475990814207C8.445947675,18.199475990814207,5.632812475,15.38633899081421,5.632812475,11.916142890814209C5.632812475,8.44594479081421,8.445947675,5.632810090814209,11.916145775,5.632810090814209C15.386343375,5.632810090814209,18.199479375,8.44594479081421,18.199479375,11.916142890814209Z" fillRule="evenodd" fill="#FFFFFF" fillOpacity="1" /></g></svg>
</button> </Link>
<Dropdown <Dropdown
menu={{ items: langMenuItems }} menu={{ items: langMenuItems }}
placement="bottomRight" placement="bottomRight"

View File

@ -3,10 +3,6 @@ import styles from "./Home.module.css";
import Banner from "@/components/Banner"; import Banner from "@/components/Banner";
import Section from "@/components/layout/Section"; import Section from "@/components/layout/Section";
import RowAccordion from "@/components/layout/RowAccordion"; import RowAccordion from "@/components/layout/RowAccordion";
const PUBLIC_URL = process.env.PUBLIC_URL || "";
const HERO_IMG = `${PUBLIC_URL}/images/bg-overview.png`;
const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)";
export default function Home() { export default function Home() {
@ -45,6 +41,20 @@ export default function Home() {
] ]
}) })
// 首页名片数据
const [cardsData] = useState([
{
title: "可持续发展",
content: "银泰集团积极践行绿色发展理念,将可持续发展融入企业战略与日常运营,致力于构建人与自然和谐共生的美好未来。",
backgroundImage: '/images/sustainable-cranes.png',
},
{
title: "银泰公益基金会",
content: "银泰集团积极践行绿色发展理念,将可持续发展融入企业战略与日常运营,致力于构建人与自然和谐共生的美好未来。",
backgroundImage: '/images/welfare-check.png',
},
])
const [newsData] = useState([ const [newsData] = useState([
{ {
title: "银泰百货×敦煌研究院联名新品限量首发", title: "银泰百货×敦煌研究院联名新品限量首发",
@ -74,39 +84,28 @@ export default function Home() {
{/* Commercial */} {/* Commercial */}
<RowAccordion data={commercialData} /> <RowAccordion data={commercialData} />
{/* Cards */} {/* 首页名片 */}
<Section background="/images/bg-mask-card.png"> <Section background="/images/bg-mask-card.png">
<div className={styles.cardsInner}> <div className={styles.cardsInner}>
<div className={`${styles.card} ${styles.cardSustainable}`}> {
<div cardsData.map((item) => (
className={styles.cardBg} <div className={`${styles.card} ${styles.cardSustainable}`}>
style={{ <div
backgroundImage: `url(${PUBLIC_URL}/images/sustainable-cranes.png), ${FALLBACK_GRADIENT}`, className={styles.cardBg}
}} style={{
/> backgroundImage: `url(${item.backgroundImage})`,
<div className={styles.cardOverlay} /> }}
<div className={styles.cardContent}> />
<h3 className={styles.cardTitle}></h3> <div className={styles.cardOverlay} />
<p className={styles.cardDesc}> <div className={styles.cardContent}>
绿 <h3 className={styles.cardTitle}>{item.title}</h3>
</p> <p className={styles.cardDesc}>
</div> {item.content}
</div> </p>
<div className={`${styles.card} ${styles.cardWelfare}`}> </div>
<div </div>
className={styles.cardBg} ))
style={{ }
backgroundImage: `url(${PUBLIC_URL}/images/welfare-check.png), ${FALLBACK_GRADIENT}`,
}}
/>
<div className={styles.cardOverlay} />
<div className={styles.cardContent}>
<h3 className={styles.cardTitle}></h3>
<p className={styles.cardDesc}>
</p>
</div>
</div>
</div> </div>
</Section> </Section>

View File

@ -0,0 +1,110 @@
.searchRow {
width: 100%;
height: 288px;
background: #F0F2F4;
display: flex;
.searchRowInner {
margin: auto;
display: flex;
align-items: center;
gap: 30px;
.searchRowTitle {
font-weight: bold;
font-size: 24px;
color: #222222;
line-height: 34px;
}
.searchInputWrapper {
position: relative;
.searchInput {
width: 600px;
height: 54px;
border: 1px solid #333333;
font-weight: 400;
font-size: 18px;
color: #222222;
line-height: 24px;
outline: none;
padding: 0 20px;
}
.searchKeyword {
position: absolute;
margin-top: 20px;
font-size: 24px;
color: #222222;
.searchKeywordKeyword {
color: #14355C;
}
}
}
.searchBtn {
width: 128px;
height: 54px;
background: #14355C;
border-radius: 0px 0px 0px 0px;
outline: none;
font-weight: 400;
font-size: 24px;
color: #FFFFFF;
cursor: pointer;
}
}
}
.searchItemList {
display: flex;
flex-direction: column;
gap: 50px;
.searchItem {
display: flex;
flex-direction: column;
gap: 20px;
height: 160px;
border-bottom: 1px solid #D8D8D8;
.searchItemTitleRow {
display: flex;
align-items: center;
justify-content: space-between;
.searchItemTitle {
font-size: 24px;
color: #222222;
font-weight: 700;
}
.searchItemCreateTime {
font-weight: 400;
font-size: 16px;
color: #999999;
line-height: 22px;
}
}
.searchItemContent {
font-weight: 400;
font-size: 18px;
color: #333333;
line-height: 30px;
/* 2行文本超出省略 */
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
}

View File

@ -0,0 +1,91 @@
import Banner from "@/components/Banner";
import Section from "@/components/layout/Section";
import styles from "./Search.module.css";
import { useCallback, useState } from "react";
import { dateFormat } from "@/utils";
type SearchData = {
id: number;
title: string;
content: string;
createTime: string;
}
export default function Search() {
const [searched, setSearched] = useState(false);
const [searchKeyword, setSearchKeyword] = useState('');
const [total, setTotal] = useState(0);
const [searchData, setSearchData] = useState<SearchData[]>([]);
const handleSearch = useCallback(() => {
setSearched(true);
setSearchData([
{
id: 1,
title: '中共中央举行新闻发布会解读党的十九届五中全会精神_党建动态',
content: '中国共产党第十九届中央委员会第五次全体会议于2020年10月26日至29日在北京举行。全会审议通过了《中共中央关于制定国民经济和社会发展第十四个五年规划和二三五年远景目标的建议》。',
createTime: '2025-11-25'
},
{
id: 2,
title: '中共中央举行新闻发布会解读党的十九届五中全会精神_党建动态',
content: '中国共产党第十九届中央委员会第五次全体会议于2020年10月26日至29日在北京举行。全会审议通过了《中共中央关于制定国民经济和社会发展第十四个五年规划和二三五年远景目标的建议》。',
createTime: '2025-11-25'
},
])
}, [searchKeyword]);
return (
<div>
<Banner
title="搜索结果"
titleSize="large"
showBreadcrumb={true}
breadcrumbItems={[{ label: '搜索结果', to: '' }]}
backgroundImage={`/images/search-banner.png`}
/>
<section className={styles.searchRow}>
<div className={styles.searchRowInner}>
<span className={styles.searchRowTitle}></span>
<div className={styles.searchInputWrapper}>
<input type="text" placeholder="请输入" className={styles.searchInput}
value={searchKeyword}
onChange={(e) => setSearchKeyword(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSearch();
}
}}
/>
{
searched && (
<div className={styles.searchKeyword}>
<span className={styles.searchKeywordKeyword}>{searchKeyword}&nbsp;</span>
<span>{total}</span>
</div>
)
}
</div>
<button type="button" className={styles.searchBtn} onClick={handleSearch}></button>
</div>
</section>
<Section background="" maskBackground="#fff">
<div className={styles.searchItemList}>
{
searchData.map((item => (
<div className={styles.searchItem}>
<div className={styles.searchItemTitleRow}>
<span className={styles.searchItemTitle}>{item.title}</span>
<span className={styles.searchItemCreateTime}>{dateFormat(item.createTime, 'yyyy年MM月dd日')}</span>
</div>
<div className={styles.searchItemContent}>{item.content}</div>
</div>
)))
}
</div>
</Section>
</div>
);
}

View File

@ -5,4 +5,28 @@ export const debounce = (func: (...args: any[]) => void, delay: number) => {
clearTimeout(timeout); clearTimeout(timeout);
timeout = setTimeout(() => func(...args), delay); timeout = setTimeout(() => func(...args), delay);
}; };
};
/**
*
* @param date 日期字符串:2026-03-05 10:00:00
* @param format yyyy-MM-dd HH:mm:ss yyyy年MM月dd日 yyyy-MM
* @returns
*/
export const dateFormat = (date: Date | string, format: string) => {
const d = typeof date === 'string' ? new Date(date) : date;
if (Number.isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
return format
.replace('yyyy', String(year))
.replace('MM', month)
.replace('dd', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}; };