diff --git a/public/images/bg-in.png b/public/images/bg-in.png
new file mode 100644
index 0000000..f6d7f81
Binary files /dev/null and b/public/images/bg-in.png differ
diff --git a/public/ttf/D-DIN-PRO-400-Regular.otf b/public/ttf/D-DIN-PRO-400-Regular.otf
new file mode 100644
index 0000000..74dd61a
Binary files /dev/null and b/public/ttf/D-DIN-PRO-400-Regular.otf differ
diff --git a/public/ttf/SourceHanSansCN-Normal.otf b/public/ttf/SourceHanSansCN-Normal.otf
new file mode 100644
index 0000000..091f56d
Binary files /dev/null and b/public/ttf/SourceHanSansCN-Normal.otf differ
diff --git a/src/App.css b/src/App.css
index e164f52..6df83cf 100644
--- a/src/App.css
+++ b/src/App.css
@@ -66,13 +66,30 @@ ul, li {
display: flex;
}
+/* 数字字体 */
+.font-num {
+ font-family: D-DIN-PRO, D-DIN-PRO;
+}
+
.header-row {
width: 100%;
margin: 0 auto;
- padding: 0 60px;
+ padding: 0 3.75rem;
box-sizing: border-box;
}
+@media (max-width: 1024px) {
+ .header-row {
+ padding: 0 1.5rem;
+ }
+}
+
+@media (max-width: 768px) {
+ .header-row {
+ padding: 0 1rem;
+ }
+}
+
body {
overflow-x: hidden;
background: #f0f2f4;
@@ -92,30 +109,17 @@ body {
.container {
flex: 1;
- overflow: auto;
+ /* overflow: auto; */
}
.layout-footer {
flex-shrink: 0;
}
-
-
-/* html {
- font-size: 16px;
-}
-@media screen and (max-width: 1920px) {
- html {
- font-size: 16px;
- }
-}
-@media screen and (max-width: 1440px) {
- html {
- font-size: 14px;
- }
-}
-@media screen and (max-width: 1024px) {
- html {
- font-size: 12px;
- }
-} */
\ No newline at end of file
+.normal-p p {
+ font-weight: 400;
+ font-size: 18px;
+ color: #222222;
+ line-height: 34px;
+ margin-bottom: 20px;
+}
\ No newline at end of file
diff --git a/src/Routes.tsx b/src/Routes.tsx
index 57714fc..f4fb037 100644
--- a/src/Routes.tsx
+++ b/src/Routes.tsx
@@ -7,6 +7,7 @@ import AboutHistory from "@/pages/About/History";
import AboutFounder from "@/pages/About/Founder";
import Business from "@/pages/Business/index";
import BusinessCommercialGroup from "@/pages/Business/CommercialGroup";
+import BusinessCommercialGroupDetail from "@/pages/Business/CommercialGroupDetail";
import BusinessBaseGroup from "@/pages/Business/BaseGroup";
import BusinessRealtyGroup from "@/pages/Business/RealtyGroup";
import BusinessInvestGroup from "@/pages/Business/InvestGroup";
@@ -20,6 +21,7 @@ import NewsMedia from "@/pages/News/Media";
import Join from "@/pages/Join/index";
import JoinCulture from "@/pages/Join/Culture";
import JoinCampus from "@/pages/Join/Campus";
+import PropertyService from "@/pages/PropertyService/index";
const routes: RouteObject[] = [
{
@@ -34,6 +36,7 @@ const routes: RouteObject[] = [
// 集团业务
{ path: "business", element: },
{ path: "business/commercial-group", element: },
+ { path: "business/commercial-group/:detailType", element: },
{ path: "business/base-group", element: },
{ path: "business/realty-group", element: },
{ path: "business/invest-group", element: },
@@ -50,6 +53,9 @@ const routes: RouteObject[] = [
{ path: "join", element: },
{ path: "join/culture", element: },
{ path: "join/campus", element: },
+
+ // 物业服务
+ { path: "property-service", element: },
],
},
{
diff --git a/src/components/Banner.module.css b/src/components/Banner.module.css
index 3fe7328..b7545a1 100644
--- a/src/components/Banner.module.css
+++ b/src/components/Banner.module.css
@@ -4,7 +4,7 @@
min-height: 100vh;
background-size: cover;
background-position: center;
- padding-bottom: 50px;
+ padding-bottom: 3.125rem;
display: flex;
flex-direction: column;
justify-content: flex-end;
@@ -24,8 +24,7 @@
.heroContent {
position: relative;
z-index: 1;
- padding: 0 24px;
- /* padding-top: 400px; */
+ padding: 0 1.5rem;
padding-left: 13.5%;
display: flex;
flex-direction: column;
@@ -33,31 +32,33 @@
}
.heroTitle {
- font-size: 60px;
+ font-size: 3.75rem;
font-weight: 700;
color: #fff;
- /* margin: 0 0 50px; */
letter-spacing: 0.05em;
}
+.heroTitleMedium {
+ font-size: 2.5rem;
+}
+
.heroSubtitle {
- font-size: 40px;
+ font-size: 2.5rem;
font-weight: 700;
color: #fff;
- /* margin: 0 0 16px; */
letter-spacing: 0.05em;
}
.heroDesc {
- max-width: 900px;
- font-size: 20px;
+ max-width: 56.25rem;
+ font-size: 1.25rem;
color: rgba(255, 255, 255, 0.95);
margin: 0;
letter-spacing: 0.02em;
}
.heroLargeDesc {
- font-size: 34px;
+ font-size: 2.125rem;
color: rgba(255, 255, 255, 0.95);
margin: 0;
letter-spacing: 0.02em;
@@ -66,10 +67,10 @@
.breadcrumb {
display: flex;
flex-direction: row;
- gap: 5px;
+ gap: 0.3125rem;
color: #fff;
text-decoration: none;
- font-size: 16px;
- margin-top: 100px;
+ font-size: 1rem;
+ margin-top: 6.25rem;
}
diff --git a/src/components/YearPicker/YearPicker.module.css b/src/components/YearPicker/YearPicker.module.css
index 1582b45..6d9036f 100644
--- a/src/components/YearPicker/YearPicker.module.css
+++ b/src/components/YearPicker/YearPicker.module.css
@@ -1,19 +1,19 @@
.wrapper {
position: relative;
display: inline-block;
- min-width: 140px;
+ min-width: 8.75rem;
}
.trigger {
display: flex;
align-items: center;
justify-content: space-between;
- gap: 8px;
- padding: 8px 11px;
+ gap: 0.5rem;
+ padding: 0.5rem 0.6875rem;
background: #14355C;
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.25);
- border-radius: 6px;
+ border-radius: 0.375rem;
cursor: pointer;
user-select: none;
}
@@ -55,13 +55,13 @@
display: flex;
align-items: center;
justify-content: center;
- width: 16px;
- height: 16px;
+ width: 1rem;
+ height: 1rem;
color: rgba(255, 255, 255, 0.85);
- font-size: 14px;
+ font-size: 0.875rem;
line-height: 1;
cursor: pointer;
- border-radius: 2px;
+ border-radius: 0.125rem;
}
.clear:hover {
@@ -80,38 +80,38 @@
.panel {
position: absolute;
- top: calc(100% + 4px);
+ top: calc(100% + 0.25rem);
left: 0;
z-index: 1050;
- min-width: 220px;
- padding: 12px;
+ min-width: 13.75rem;
+ padding: 0.75rem;
background: #14355C;
border: 1px solid rgba(255, 255, 255, 0.25);
- border-radius: 8px;
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
+ border-radius: 0.5rem;
+ box-shadow: 0 0.375rem 1rem rgba(0, 0, 0, 0.3);
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
- margin-bottom: 12px;
- padding: 0 4px;
+ margin-bottom: 0.75rem;
+ padding: 0 0.25rem;
}
.navBtn {
display: flex;
align-items: center;
justify-content: center;
- width: 28px;
- height: 28px;
+ width: 1.75rem;
+ height: 1.75rem;
padding: 0;
background: transparent;
color: #fff;
border: none;
- border-radius: 4px;
+ border-radius: 0.25rem;
cursor: pointer;
- font-size: 12px;
+ font-size: 0.75rem;
}
.navBtn:hover:not(:disabled) {
@@ -125,26 +125,26 @@
.decadeLabel {
color: #fff;
- font-size: 14px;
+ font-size: 0.875rem;
font-weight: 500;
}
.yearGrid {
display: grid;
grid-template-columns: repeat(3, 1fr);
- gap: 4px;
+ gap: 0.25rem;
}
.yearCell {
- min-width: 56px;
- height: 32px;
+ min-width: 3.5rem;
+ height: 2rem;
padding: 0;
background: transparent;
color: #fff;
border: none;
- border-radius: 4px;
+ border-radius: 0.25rem;
cursor: pointer;
- font-size: 14px;
+ font-size: 0.875rem;
transition: background 0.2s;
}
diff --git a/src/components/banner.tsx b/src/components/banner.tsx
index c4d8034..e57b862 100644
--- a/src/components/banner.tsx
+++ b/src/components/banner.tsx
@@ -2,15 +2,19 @@ import { Link } from "react-router-dom";
import styles from "./Banner.module.css";
const FALLBACK_GRADIENT = "linear-gradient(135deg, #1a2a4a 0%, #2d4a7c 100%)";
+type BreadcrumbItem = { label: string; to: string };
+
type Props = {
title: string;
subtitle?: string;
desc?: string;
largedesc?: string;
showBreadcrumb?: boolean;
+ breadcrumbItems?: BreadcrumbItem[];
+ titleSize?: "large" | "medium";
backgroundImage: string;
}
-export default function Banner({ title, subtitle, desc, largedesc, showBreadcrumb, backgroundImage }: Props) {
+export default function Banner({ title, subtitle, desc, largedesc, showBreadcrumb, breadcrumbItems, titleSize = "large", backgroundImage }: Props) {
return (
-
{title}
+
{title}
{subtitle &&
{subtitle}
}
{desc &&
{desc}
}
{largedesc &&
{largedesc}
}
- {showBreadcrumb && (
-
- 首页
- {'>'}
- 关于银泰
-
- )}
+
+ {showBreadcrumb && (breadcrumbItems ?? []).map((item, i) => (
+
+ {i > 0 && {' > '}}
+ {item.to ? {item.label} : {item.label}}
+
+ ))}
+
)
diff --git a/src/components/layout/SectionTitle/index.module.css b/src/components/layout/SectionTitle/index.module.css
new file mode 100644
index 0000000..20e1a49
--- /dev/null
+++ b/src/components/layout/SectionTitle/index.module.css
@@ -0,0 +1,8 @@
+.sectionTitle {
+ font-weight: 700;
+ font-size: 40px;
+ color: #222222;
+ line-height: 50px;
+ text-align: center;
+ margin-bottom: 100px;
+}
\ No newline at end of file
diff --git a/src/components/layout/SectionTitle/index.tsx b/src/components/layout/SectionTitle/index.tsx
new file mode 100644
index 0000000..6816d8c
--- /dev/null
+++ b/src/components/layout/SectionTitle/index.tsx
@@ -0,0 +1,9 @@
+import styles from "./index.module.css";
+
+export default function SectionTitle({ title }: { title: string }) {
+ return (
+
+ {title}
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/layout/StatsRow/StatsRow.module.css b/src/components/layout/StatsRow/StatsRow.module.css
new file mode 100644
index 0000000..d30f5e4
--- /dev/null
+++ b/src/components/layout/StatsRow/StatsRow.module.css
@@ -0,0 +1,37 @@
+.statsRow {
+ margin-top: 9.375rem;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0;
+ align-items: flex-start;
+ justify-content: center;
+ flex-wrap: nowrap;
+}
+
+.statItem {
+ width: 17rem;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: .625rem;
+}
+
+.statItem:not(:last-child) {
+ border-right: 1px solid #222222;
+}
+
+.statNum {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: #222;
+ line-height: 1.2;
+}
+
+.statNumDesc {
+ font-size: 1.875rem;
+}
+
+.statLabel {
+ font-size: 1rem;
+ color: #666;
+}
\ No newline at end of file
diff --git a/src/components/layout/StatsRow/StatsRow.tsx b/src/components/layout/StatsRow/StatsRow.tsx
new file mode 100644
index 0000000..22c0f55
--- /dev/null
+++ b/src/components/layout/StatsRow/StatsRow.tsx
@@ -0,0 +1,26 @@
+import styles from "./StatsRow.module.css";
+
+type StatsData = {
+ num: string;
+ label: string;
+}
+
+export default function StatsRow({ statsData }: { statsData: StatsData[] }) {
+ return (
+
+ {statsData.map((item, i) => (
+
+
+
+ {item.num.split(' ')[0] + ' '}
+
+
+ {item.num.split(' ')[1]}
+
+
+
{item.label}
+
+ ))}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/layout/SwiperCardSection/index.module.css b/src/components/layout/SwiperCardSection/index.module.css
new file mode 100644
index 0000000..0d4961d
--- /dev/null
+++ b/src/components/layout/SwiperCardSection/index.module.css
@@ -0,0 +1,57 @@
+.swiperCardSection {
+ min-height: 100vh;
+ padding: 100px 260px;
+ background: #D8D8D8;
+}
+
+
+.swiperCardList {
+ display: flex;
+ flex-direction: row;
+ gap: 15px;
+ .swiperCardItem {
+ position: relative;
+ width: 100%;
+ aspect-ratio: 457 / 630;
+ img {
+ width: 100%;
+ aspect-ratio: 457 / 630;
+ object-fit: cover;
+ }
+ .swiperMask {
+ width: 100%;
+ aspect-ratio: 457 / 630;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ .swiperContent {
+ color: #fff;
+ position: absolute;
+ top: 80%;
+ left: 0;
+ width: 100%;
+ height: 100%;
+
+ .swiperTitle {
+ font-weight: 500;
+ font-size: 24px;
+ color: #FFFFFF;
+ line-height: 80px;
+ height: 80px;
+ margin: 0 30px;
+ text-align: center;
+ border-bottom: 1px solid rgba(255,255,255,0.3);
+
+ span {
+ display: inline-block;
+ line-height: 80px;
+ height: 80px;
+ border-bottom: 3px solid #14355C;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/layout/SwiperCardSection/index.tsx b/src/components/layout/SwiperCardSection/index.tsx
new file mode 100644
index 0000000..bbe0b09
--- /dev/null
+++ b/src/components/layout/SwiperCardSection/index.tsx
@@ -0,0 +1,33 @@
+import SectionTitle from "../SectionTitle";
+import styles from "./index.module.css";
+
+type Data = {
+ title: string;
+ cardItems: {
+ title: string;
+ desc: string;
+ image: string;
+ }[];
+}
+
+export default function SwiperCardSection({ data }: { data: Data }) {
+ return (
+
+
+
+ {data.cardItems.map((item) => (
+
+

+
+
+
+ {item.title}
+
+ {/*
{item.desc}
*/}
+
+
+ ))}
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index a30c8c8..fb7e8b9 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,38 @@
+/* rem 基准:以 16px 为设计稿基准 */
+html {
+ font-size: 16px;
+}
+
+@media screen and (max-width: 1920px) {
+ html {
+ font-size: 16px;
+ }
+}
+
+@media screen and (max-width: 1440px) {
+ html {
+ font-size: 14px;
+ }
+}
+
+@media screen and (max-width: 1024px) {
+ html {
+ font-size: 12px;
+ }
+}
+
+@media screen and (max-width: 768px) {
+ html {
+ font-size: 12px;
+ }
+}
+
+@media screen and (max-width: 480px) {
+ html {
+ font-size: 12px;
+ }
+}
+
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
@@ -13,6 +48,10 @@ code {
}
@font-face {
- font-family: 'Alimama ShuHeiTi';
- src: url('https://cdn.batiao8.com/static/ttf/%E9%98%BF%E9%87%8C%E5%A6%88%E5%A6%88%E6%95%B0%E9%BB%91%E4%BD%93.ttf');
+ font-family: 'D-DIN-PRO';
+ src: url('/public/ttf/D-DIN-PRO-400-Regular.otf');
+}
+@font-face {
+ font-family: 'Source Han Sans';
+ src: url('/public/ttf/SourceHanSansCN-Normal.otf');
}
\ No newline at end of file
diff --git a/src/layouts/Footer.module.css b/src/layouts/Footer.module.css
index 2f59c4a..4ed245d 100644
--- a/src/layouts/Footer.module.css
+++ b/src/layouts/Footer.module.css
@@ -4,32 +4,32 @@
}
.footerUpper {
- padding: 60px;
+ padding: 3.75rem;
}
.footerGrid {
display: grid;
grid-template-columns: repeat(7, 1fr) auto;
- gap: 24px;
+ gap: 1.5rem;
align-items: start;
}
.footerColumn {
display: flex;
flex-direction: column;
- gap: 12px;
+ gap: 0.75rem;
}
.footerTitle {
- font-size: 14px;
+ font-size: 0.875rem;
font-weight: 600;
color: #333;
- margin-bottom: 4px;
+ margin-bottom: 0.25rem;
}
.footerLink {
- font-size: 13px;
+ font-size: 0.8125rem;
color: #666;
text-decoration: none;
}
@@ -42,25 +42,25 @@
display: flex;
flex-direction: row;
align-items: center;
- gap: 16px;
+ gap: 1rem;
position: absolute;
- right: 60px;
+ right: 3.75rem;
}
.footerLogo {
- font-size: 20px;
+ font-size: 1.25rem;
font-weight: 600;
color: #999;
}
.socialIcons {
display: flex;
- gap: 12px;
+ gap: 0.75rem;
}
.socialIcon {
- width: 28px;
- height: 28px;
+ width: 1.75rem;
+ height: 1.75rem;
border-radius: 50%;
background: #ddd;
display: flex;
@@ -68,13 +68,13 @@
justify-content: center;
color: #666;
text-decoration: none;
- font-size: 12px;
+ font-size: 0.75rem;
}
.footerLower {
background: #031229;
color: #fff;
- height: 60px;
+ height: 3.75rem;
display: flex;
align-items: center;
justify-content: center;
@@ -84,12 +84,12 @@
display: flex;
align-items: center;
justify-content: space-between;
- font-size: 14px;
+ font-size: 0.875rem;
}
.footerLowerLinks {
display: flex;
- gap: 20px;
+ gap: 1.25rem;
}
.footerLowerLink {
@@ -100,3 +100,44 @@
.footerLowerLink:hover {
color: #fff;
}
+
+@media (max-width: 1024px) {
+ .footerUpper {
+ padding: 2rem;
+ }
+
+ .footerGrid {
+ grid-template-columns: repeat(4, 1fr);
+ gap: 1.25rem;
+ }
+
+ .footerRight {
+ right: 2rem;
+ }
+}
+
+@media (max-width: 768px) {
+ .footerUpper {
+ padding: 1.5rem;
+ }
+
+ .footerGrid {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1rem;
+ }
+
+ .footerRight {
+ position: static;
+ margin-top: 1rem;
+ }
+
+ .footerLower {
+ height: auto;
+ padding: 1rem;
+ }
+
+ .footerLowerInner {
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+}
diff --git a/src/layouts/Header.module.css b/src/layouts/Header.module.css
index bad39de..bb2ea9a 100644
--- a/src/layouts/Header.module.css
+++ b/src/layouts/Header.module.css
@@ -3,13 +3,13 @@
top: 0;
left: 0;
z-index: 1000;
- height: 120px;
+ height: 7.5rem;
width: 100%;
font-family: Source Han Sans, Source Han Sans;
font-weight: 700;
- font-size: 18px;
- line-height: 26px;
+ font-size: 1.125rem;
+ line-height: 1.625rem;
text-align: left;
font-style: normal;
text-transform: none;
@@ -37,10 +37,10 @@
.headerInner::after {
position: absolute;
bottom: 0;
- left: 60px;
+ left: 3.75rem;
content: '';
display: block;
- width: calc(100% - 120px);
+ width: calc(100% - 7.5rem);
box-sizing: border-box;
height: 1px;
background: #FFFFFF;
@@ -56,7 +56,7 @@
.headerRight {
display: flex;
align-items: center;
- gap: 30px;
+ gap: 1.875rem;
}
.nav {
@@ -66,11 +66,11 @@
list-style: none;
margin: 0;
padding: 0;
- margin-right: 30px;
+ margin-right: 1.875rem;
}
.navItem {
- padding: 0 30px;
+ padding: 0 1.875rem;
}
.navLink {
@@ -90,14 +90,14 @@
.actions {
display: flex;
align-items: center;
- gap: 16px;
- margin-left: 30px;
+ gap: 1rem;
+ margin-left: 1.875rem;
}
.langTrigger {
display: flex;
align-items: center;
- gap: 4px;
+ gap: 0.25rem;
color: #fff;
background: transparent;
border: none;
@@ -109,7 +109,7 @@
background: transparent;
border: none;
cursor: pointer;
- padding: 4px;
+ padding: 0.25rem;
display: flex;
align-items: center;
justify-content: center;
@@ -121,10 +121,10 @@
top: 100%;
left: 0;
width: 100%;
- height: 380px;
+ height: 23.75rem;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
- padding: 20px;
+ padding: 1.25rem;
z-index: 1000;
}
@@ -136,8 +136,71 @@
.dropPanelLink {
font-weight: 400;
- font-size: 18px;
- line-height: 50px;
+ font-size: 1.125rem;
+ line-height: 3.125rem;
color: #222222;
text-decoration: none;
+}
+
+@media (max-width: 1024px) {
+ .header {
+ height: 5.5rem;
+ }
+
+ .headerInner::after {
+ left: 1.5rem;
+ width: calc(100% - 3rem);
+ }
+
+ .navItem {
+ padding: 0 1rem;
+ }
+
+ .headerRight {
+ gap: 1rem;
+ }
+
+ .nav {
+ margin-right: 1rem;
+ }
+
+ .actions {
+ margin-left: 1rem;
+ }
+}
+
+@media (max-width: 768px) {
+ .header {
+ height: 4rem;
+ }
+
+ .headerInner::after {
+ left: 1rem;
+ width: calc(100% - 2rem);
+ }
+
+ .navItem {
+ padding: 0 0.5rem;
+ }
+
+ .headerRight {
+ gap: 0.5rem;
+ }
+
+ .nav {
+ margin-right: 0.5rem;
+ }
+
+ .actions {
+ margin-left: 0.5rem;
+ }
+
+ .dropPanel {
+ height: auto;
+ padding: 1rem;
+ }
+
+ .dropPanelLink {
+ line-height: 2.5rem;
+ }
}
\ No newline at end of file
diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx
index e68a276..ad3867a 100644
--- a/src/layouts/Header.tsx
+++ b/src/layouts/Header.tsx
@@ -80,7 +80,7 @@ export default function Header() {
>
-

+