@@ -596,6 +600,11 @@ export default {
min-height: var(--page-nav-height);
}
+.nav-figma-scale-viewport,
+.nav-figma-scale-stage {
+ width: 100%;
+}
+
.logo-box {
display: flex;
align-items: center;
diff --git a/txw-mhzc-web/src/pages/index/styles/home-figma-variables.less b/txw-mhzc-web/src/pages/index/styles/home-figma-variables.less
index c757c29..2151d26 100644
--- a/txw-mhzc-web/src/pages/index/styles/home-figma-variables.less
+++ b/txw-mhzc-web/src/pages/index/styles/home-figma-variables.less
@@ -266,6 +266,7 @@
@home-cta-head-to-btn-gap: 47px;
@home-footer-top: 4867px;
+@home-cta-design-height: (@home-footer-top - @home-cta-top);
@home-footer-height: 212px;
@home-footer-info-height: 148px;
@home-footer-bar-height: 64px;
@@ -543,6 +544,495 @@
--home-title-bar-height: @home-section-title-deco-height;
}
+// -----------------------------------------------------------------------------
+// Figma 整页等比缩放(设计画布 1440 × 5079,随视口宽度 scale)
+// -----------------------------------------------------------------------------
+.home-figma-scale-page() {
+ .home-figma-scale-viewport {
+ width: 100%;
+ }
+
+ .home-figma-scale-stage {
+ width: 100%;
+ }
+
+ html.portal-figma-scale-active & {
+ .home-figma-scale-viewport {
+ width: 100%;
+ height: var(--home-figma-visual-height, auto);
+ overflow: hidden;
+ }
+
+ .home-figma-scale-stage {
+ width: @home-design-width;
+ margin-left: auto;
+ margin-right: auto;
+ transform: scale(var(--home-figma-scale, 1));
+ transform-origin: top center;
+ margin-bottom: var(--home-figma-stage-margin-bottom, 0);
+ }
+
+ .container {
+ width: @home-design-width;
+ max-width: none;
+ }
+
+ /* 各区块高度由 JS 注入 --home-figma-*-design-height,至少填满一屏 */
+ --home-section-min-h: var(--home-figma-section-design-height, @home-core-height);
+ --home-news-section-min-h: var(--home-figma-news-section-design-height, @home-news-height);
+ --home-cta-section-min-h: var(--home-figma-cta-design-height, @home-cta-design-height);
+
+ #section-hero.top-box {
+ min-height: var(--home-figma-hero-design-height, @home-hero-height);
+ height: var(--home-figma-hero-design-height, @home-hero-height);
+ }
+
+ .core-section {
+ min-height: var(--home-figma-section-design-height, @home-core-height);
+ }
+
+ .capability-section {
+ min-height: var(--home-figma-section-design-height, @home-ability-height);
+ }
+
+ .overseas2-section {
+ min-height: var(--home-figma-section-design-height, @home-export-height);
+ }
+
+ .news-section {
+ min-height: var(--home-figma-news-section-design-height, @home-news-height);
+ }
+
+ .partner-section {
+ min-height: var(--home-figma-partner-section-design-height, @home-partner-height);
+ }
+
+ .bottom-box {
+ height: var(--home-figma-cta-design-height, @home-cta-design-height);
+ min-height: var(--home-figma-cta-design-height, @home-cta-design-height);
+ }
+
+ .home-shelf--hero {
+ flex: 1;
+ min-height: var(--home-figma-hero-design-height, @home-hero-height);
+ height: 100%;
+ padding: @home-hero-content-padding-top 0 @home-space-64;
+ gap: 0;
+ }
+
+ .home-hero-content {
+ flex: 0 1 auto;
+ width: 100%;
+ max-width: @home-content-width;
+ margin-top: auto;
+ gap: @home-hero-content-gap;
+ }
+
+ .top-hero-actions {
+ gap: @home-space-32;
+ margin-top: 0;
+ }
+
+ .top-title-text {
+ font-size: @home-font-size-56;
+ }
+
+ .top-title-desc {
+ font-size: @home-font-size-28;
+ }
+
+ .hero-cards {
+ gap: @home-feature-cards-gap;
+ }
+
+ .home-shelf--core {
+ min-height: var(--home-figma-section-design-height, @home-core-height);
+ gap: @home-space-52;
+ }
+
+ .home-shelf--capability {
+ min-height: var(--home-figma-section-design-height, @home-ability-height);
+ gap: @home-ability-title-to-grid-gap;
+ }
+
+ .home-shelf--overseas {
+ min-height: var(--home-figma-section-design-height, @home-export-height);
+ gap: @home-export-title-to-list-gap;
+ }
+
+ .home-shelf--news {
+ min-height: var(--home-figma-news-section-design-height, @home-news-height);
+ }
+
+ .home-shelf--partner {
+ min-height: var(--home-figma-partner-section-design-height, @home-partner-height);
+ }
+ }
+}
+
+/* 覆盖 home2 桌面端 media query 中的 fluid/clamp,避免破坏 Figma 等比缩放 */
+html.portal-figma-scale-active {
+ .portal-page .home-shelf--hero {
+ justify-content: flex-start;
+ gap: 0;
+ }
+
+ .portal-page .home-hero-content {
+ margin-top: auto;
+ gap: @home-hero-content-gap;
+ }
+
+ .portal-page .top-hero-actions {
+ gap: @home-space-32;
+ }
+
+ .portal-page .top-title-text {
+ font-size: @home-font-size-56;
+ }
+
+ .portal-page .top-title-desc {
+ font-size: @home-font-size-28;
+ }
+
+ .portal-page .hero-cards {
+ gap: @home-feature-cards-gap;
+ }
+
+ .portal-page #section-hero.top-box {
+ min-height: var(--home-figma-hero-design-height, @home-hero-height) !important;
+ height: var(--home-figma-hero-design-height, @home-hero-height) !important;
+ }
+
+ .portal-page .home-shelf--hero {
+ min-height: var(--home-figma-hero-design-height, @home-hero-height) !important;
+ }
+
+ .portal-page .core-section,
+ .portal-page .capability-section,
+ .portal-page .overseas2-section {
+ min-height: var(--home-figma-section-design-height, @home-core-height) !important;
+ height: var(--home-figma-section-design-height, @home-core-height) !important;
+ box-sizing: border-box;
+ }
+
+ .portal-page .news-section {
+ min-height: var(--home-figma-news-section-design-height, @home-news-height) !important;
+ height: var(--home-figma-news-section-design-height, @home-news-height) !important;
+ box-sizing: border-box;
+ }
+
+ .portal-page .partner-section {
+ min-height: var(--home-figma-partner-section-design-height, @home-partner-height) !important;
+ height: var(--home-figma-partner-section-design-height, @home-partner-height) !important;
+ box-sizing: border-box;
+ }
+
+ .portal-page .home-shelf--core,
+ .portal-page .home-shelf--capability,
+ .portal-page .home-shelf--overseas {
+ min-height: var(--home-figma-section-design-height, @home-core-height) !important;
+ }
+
+ .portal-page .home-shelf--news {
+ min-height: var(--home-figma-news-section-design-height, @home-news-height) !important;
+ }
+
+ .portal-page .home-shelf--partner {
+ min-height: var(--home-figma-partner-section-design-height, @home-partner-height) !important;
+ }
+
+ .portal-page .capability-section {
+ background-color: @home-color-page-bg;
+ background-size: 100% 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ .portal-page .overseas2-section {
+ background-size: 100% 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ .portal-page .home-shelf--capability,
+ .portal-page .home-shelf--overseas {
+ min-height: 100% !important;
+ height: 100%;
+ }
+
+ /* CTA 独占一屏;页脚最后一屏贴底;整页高度由 JS 实测锁定 */
+ .portal-page.page-box {
+ box-sizing: border-box;
+ height: var(--home-figma-visual-height) !important;
+ max-height: var(--home-figma-visual-height) !important;
+ overflow: hidden !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ background: @home-color-footer-bar-bg !important;
+ }
+
+ .portal-page .home-figma-scale-viewport {
+ height: var(--home-figma-visual-height) !important;
+ overflow: hidden !important;
+ }
+
+ .portal-page .bottom-box {
+ width: @home-design-width !important;
+ max-width: @home-design-width !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ height: var(--home-figma-cta-design-height, @home-cta-design-height) !important;
+ min-height: var(--home-figma-cta-design-height, @home-cta-design-height) !important;
+ overflow: hidden;
+ background-color: @home-color-cta-section-bg !important;
+ }
+
+ .portal-page .bottom-box-bg {
+ position: absolute !important;
+ left: 0 !important;
+ top: 0 !important;
+ width: 100% !important;
+ height: 100% !important;
+ min-width: 0 !important;
+ transform: none !important;
+ object-fit: fill !important;
+ object-position: top center !important;
+ }
+
+ .portal-page .bottom-box::after {
+ display: none !important;
+ }
+
+ .portal-page .portal-footer-shell,
+ .portal-page .site-footer {
+ flex-shrink: 0;
+ width: @home-design-width !important;
+ max-width: @home-design-width !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
+ margin-top: 0 !important;
+ }
+
+ .content-wrap--home {
+ background: @home-color-footer-bar-bg;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// 门户落地页 Figma 等比缩放(fwsc / hyzt / qych / gxnlpt)
+// -----------------------------------------------------------------------------
+.portal-figma-scale-page() {
+ .portal-figma-scale-viewport {
+ width: 100%;
+ }
+
+ .portal-figma-scale-stage {
+ width: 100%;
+ }
+
+ html.portal-figma-scale-active & {
+ .portal-figma-scale-viewport {
+ width: 100%;
+ height: var(--home-figma-visual-height, auto);
+ overflow: hidden;
+ }
+
+ .portal-figma-scale-stage {
+ width: @home-design-width;
+ margin-left: auto;
+ margin-right: auto;
+ transform: scale(var(--home-figma-scale, 1));
+ transform-origin: top center;
+ margin-bottom: var(--home-figma-stage-margin-bottom, 0);
+ }
+ }
+}
+
+html.portal-figma-scale-active.portal-landing-figma-scale-active {
+ .portal-landing-figma-page {
+ box-sizing: border-box;
+ height: var(--home-figma-visual-height, auto) !important;
+ max-height: var(--home-figma-visual-height, none) !important;
+ overflow: hidden !important;
+ background: #f6f7fa !important;
+ }
+
+ .content-wrap--landing-hub .portal-route-outlet {
+ min-height: var(--portal-landing-first-screen-height) !important;
+ }
+
+ .portal-page-shell.portal-landing-figma-page,
+ .portal-landing-figma-page .main-content,
+ .qych-landing {
+ min-height: var(--portal-landing-first-screen-height) !important;
+ }
+
+ .portal-page-shell .banner-section,
+ .qych-landing .banner-section {
+ height: @portal-landing-banner-height !important;
+ flex-shrink: 0;
+ }
+
+ .hyzt-wrap .banner-bg {
+ top: @hyzt-landing-bg-offset-top !important;
+ width: 100% !important;
+ height: @hyzt-landing-bg-height !important;
+ min-height: @hyzt-landing-bg-height !important;
+ }
+
+ .content-wrap--landing-hub .portal-page-shell .services-section,
+ .qych-landing .services-section {
+ margin-top: -@portal-landing-cards-overlap !important;
+ padding-top: @portal-landing-cards-pt !important;
+ padding-bottom: @portal-landing-cards-pb !important;
+
+ &::before,
+ &::after {
+ flex-grow: 0 !important;
+ flex-basis: 0 !important;
+ min-height: 0 !important;
+ height: 0 !important;
+ content: none !important;
+ display: none !important;
+ }
+ }
+
+ .hyzt-page-inner,
+ .qych-page-inner {
+ max-width: @hyzt-landing-content-width !important;
+ }
+
+ .fwsc-page .services-grid {
+ max-width: @home-content-width !important;
+ }
+
+ .gxnlpt-page .page-content-wrap {
+ max-width: @home-content-width !important;
+ }
+
+ .qych-snap-section {
+ min-height: var(--portal-landing-first-screen-height) !important;
+ }
+
+ .content-wrap--landing-hub,
+ .content-wrap--figma-portal {
+ background: #f6f7fa;
+ }
+}
+
+// 服务中心子页:碳服务/需求/数据/金融市场列表
+html.portal-figma-scale-active.portal-market-figma-scale-active {
+ .portal-market-figma-page {
+ box-sizing: border-box;
+ width: 100%;
+ flex: 1 1 auto;
+ min-height: var(--home-figma-visual-height, auto);
+ background: #f5f5f5 !important;
+ }
+
+ .portal-market-figma-page .portal-figma-scale-stage {
+ min-height: var(--portal-market-shell-min-height, auto);
+ box-sizing: border-box;
+ }
+
+ .content-wrap--figma-market .portal-route-outlet {
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+ min-height: 0;
+ }
+
+ .portal-page-stack,
+ .portal-page-stack--figma-market {
+ display: flex;
+ flex-direction: column;
+ min-height: var(--portal-scroll-height, 100%);
+ }
+
+ .portal-page-stack .portal-layout-footer {
+ flex-shrink: 0;
+ width: 100%;
+ margin-top: 0;
+ }
+
+ .portal-market-figma-page .secondary-nav-content {
+ width: @home-content-width !important;
+ max-width: @home-content-width !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
+ box-sizing: border-box;
+ }
+
+ .portal-market-figma-page .fwsc-main,
+ .portal-market-figma-page .xqsc-main,
+ .portal-market-figma-page .jrsc-main,
+ .portal-market-figma-page .page-body,
+ .portal-market-figma-page .content-wrapper {
+ width: @home-content-width !important;
+ max-width: @home-content-width !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
+ box-sizing: border-box;
+ flex: 1 1 auto;
+ display: flex;
+ flex-direction: column;
+ min-height: calc(var(--portal-market-shell-min-height) - 62px);
+ }
+
+ .portal-market-figma-page .content-area,
+ .portal-market-figma-page .content-wrapper {
+ flex: 1 1 auto;
+ align-items: stretch;
+ }
+
+ .content-wrap--figma-market {
+ background: @home-color-footer-bar-bg;
+ }
+}
+
+// 顶栏与首页共用 html.portal-figma-scale-active + --home-figma-scale
+.home-figma-scale-nav() {
+ html.portal-figma-scale-active .nav-box {
+ height: var(--page-nav-height);
+ overflow: hidden;
+ }
+
+ html.portal-figma-scale-active .nav-figma-scale-viewport {
+ display: flex;
+ width: 100%;
+ height: var(--page-nav-height);
+ overflow: hidden;
+ justify-content: center;
+ }
+
+ html.portal-figma-scale-active .nav-figma-scale-stage {
+ width: @home-design-width;
+ height: @home-nav-height;
+ flex-shrink: 0;
+ transform: scale(var(--home-figma-scale, 1));
+ transform-origin: top center;
+ margin-bottom: var(--home-figma-nav-stage-margin-bottom, 0);
+ }
+
+ html.portal-figma-scale-active .nav-figma-scale-stage .page-nav-inner {
+ width: @home-content-width;
+ max-width: @home-content-width;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 0;
+ padding-right: 0;
+ box-sizing: border-box;
+ }
+
+ html.portal-figma-scale-active .nav-figma-scale-stage .nav-inner,
+ html.portal-figma-scale-active .nav-figma-scale-stage .menu-box,
+ html.portal-figma-scale-active .nav-figma-scale-stage .option-wrapper,
+ html.portal-figma-scale-active .nav-figma-scale-stage .option-box {
+ height: @home-nav-height;
+ min-height: @home-nav-height;
+ }
+}
+
// -----------------------------------------------------------------------------
// 共性能力页 150605:2210 / 150605:2534
// -----------------------------------------------------------------------------
@@ -600,6 +1090,12 @@
@portal-landing-cards-overlap-sm: 32px;
@portal-landing-cards-pt: 60px;
@portal-landing-cards-pb: 80px;
+@portal-landing-cards-pt-fluid: clamp(36px, 4.5vh, 60px);
+@portal-landing-cards-pb-fluid: clamp(24px, 3.5vh, 80px);
+@portal-landing-cards-pb-screen: clamp(20px, 2.5vh, 40px);
+/* 首屏卡片区垂直黄金分割:剩余空间上 38.2% / 下 61.8%,卡片落在 φ 点附近 */
+@portal-landing-golden-flex-top: 382;
+@portal-landing-golden-flex-bottom: 618;
@hyzt-landing-cards-overlap: @portal-landing-cards-overlap;
@hyzt-landing-cards-pt: @portal-landing-cards-pt;
@hyzt-landing-cards-px: 30px;
diff --git a/txw-mhzc-web/src/pages/index/styles/page-layout.less b/txw-mhzc-web/src/pages/index/styles/page-layout.less
index c66e6b9..5e71efc 100644
--- a/txw-mhzc-web/src/pages/index/styles/page-layout.less
+++ b/txw-mhzc-web/src/pages/index/styles/page-layout.less
@@ -1,4 +1,9 @@
// 门户页边距:Figma 1440 画布 · 1200 版心 · 左右各 120px 自适应留白
+@import './portal-landing-hub-layout.less';
+@import './home-figma-variables.less';
+
+.home-figma-scale-nav();
+
:root {
--page-content-max-width: 1200px;
/* Figma 导航 logo:图标区 34px + 与字间距 12px → 「可」字左缘距版心左 46px */
@@ -161,26 +166,6 @@
background: #f6f7fa;
}
-/* 首屏落地页:首屏占满滚动区,页脚在下滑后出现(勿用 flex:1 把页脚吸到首屏底) */
-.content-wrap--landing-hub {
- background: #f6f7fa;
-}
-
-.content-wrap--landing-hub .portal-page-stack--landing-hub {
- min-height: auto;
-}
-
-.content-wrap--landing-hub .portal-page-stack--landing-hub .portal-route-outlet {
- flex: 0 0 auto;
- min-height: var(--portal-scroll-height, 100%);
-}
-
-.content-wrap--landing-hub .portal-page-stack--landing-hub .portal-page-shell {
- box-sizing: border-box;
- min-height: var(--portal-scroll-height, 100%);
- background: #f6f7fa;
-}
-
/* 短页:栈高度至少铺满滚动区,页脚贴底;长页:随内容增高,不在页脚后留白 */
.portal-page-stack {
display: flex;
diff --git a/txw-mhzc-web/src/pages/index/styles/portal-landing-hub-layout.less b/txw-mhzc-web/src/pages/index/styles/portal-landing-hub-layout.less
new file mode 100644
index 0000000..7367eb3
--- /dev/null
+++ b/txw-mhzc-web/src/pages/index/styles/portal-landing-hub-layout.less
@@ -0,0 +1,152 @@
+// =============================================================================
+// 落地页首屏:Banner 350px + 卡片区黄金分割垂直定位 + 页脚下滑出现
+// =============================================================================
+
+@import './home-figma-variables.less';
+@import './portal-landing-cards.less';
+
+.portal-landing-first-screen() {
+ display: flex;
+ flex-direction: column;
+ box-sizing: border-box;
+ min-height: var(--portal-scroll-height, calc(100vh - var(--page-offset-top, 64px)));
+ background: #f6f7fa;
+}
+
+// 卡片区:首屏剩余高度按黄金比 38.2% : 61.8% 分配上下留白,卡片落在 φ 点(略高于贴底)
+.portal-landing-cards-area() {
+ position: relative;
+ z-index: 2;
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+ justify-content: flex-start;
+ min-height: 0;
+ margin-top: -@portal-landing-cards-overlap;
+ padding: @portal-landing-cards-pt-fluid 0 0;
+ box-sizing: border-box;
+
+ &::before,
+ &::after {
+ content: '';
+ display: block;
+ flex-shrink: 1;
+ flex-basis: 0;
+ min-height: 0;
+ width: 100%;
+ pointer-events: none;
+ }
+
+ &::before {
+ flex-grow: @portal-landing-golden-flex-top;
+ }
+
+ &::after {
+ flex-grow: @portal-landing-golden-flex-bottom;
+ }
+
+ .services-grid {
+ flex-shrink: 0;
+ width: 100%;
+ }
+}
+
+.portal-landing-cards-area-flat() {
+ &::before,
+ &::after {
+ content: none;
+ display: none;
+ flex: 0 0 0;
+ }
+
+ padding-bottom: @portal-landing-cards-pb-screen;
+}
+
+/* fwsc / hyzt:Main 布局 landingHubScrollFooter */
+.content-wrap--landing-hub {
+ background: #f6f7fa;
+}
+
+.content-wrap--landing-hub .portal-page-stack--landing-hub {
+ min-height: auto;
+}
+
+.content-wrap--landing-hub .portal-page-stack--landing-hub .portal-route-outlet {
+ flex: 0 0 auto;
+ min-height: var(--portal-scroll-height, calc(100vh - var(--page-offset-top, 64px)));
+}
+
+.content-wrap--landing-hub .portal-page-stack--landing-hub .portal-page-shell {
+ .portal-landing-first-screen();
+}
+
+.content-wrap--landing-hub .portal-page-shell .banner-section {
+ flex-shrink: 0;
+}
+
+.content-wrap--landing-hub .fwsc-page .main-content {
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+ min-height: 0;
+}
+
+.content-wrap--landing-hub .portal-page-shell .services-section {
+ .portal-landing-cards-area();
+}
+
+.content-wrap--landing-hub .hyzt-wrap .services-section {
+ padding-left: @hyzt-landing-cards-px;
+ padding-right: @hyzt-landing-cards-px;
+}
+
+/* 企业出海首屏 */
+.qych-landing {
+ .portal-landing-first-screen();
+ overflow: visible;
+}
+
+.qych-landing .banner-section {
+ flex-shrink: 0;
+}
+
+.qych-landing .services-section {
+ .portal-landing-cards-area();
+ padding-left: @hyzt-landing-cards-px;
+ padding-right: @hyzt-landing-cards-px;
+}
+
+// 窄屏:取消黄金分割、固定卡高(CSS 变量可穿透 scoped),改为自然流式排列
+@media (max-width: 1200px) {
+ .content-wrap--landing-hub .portal-page-shell .services-section,
+ .qych-landing .services-section {
+ --portal-service-card-min-height: auto;
+ margin-top: -@portal-landing-cards-overlap-md;
+ .portal-landing-cards-area-flat();
+ .portal-landing-card-shell-reset();
+ }
+}
+
+@media (max-width: 900px) {
+ .content-wrap--landing-hub .portal-page-shell .services-section,
+ .qych-landing .services-section {
+ margin-top: -@portal-landing-cards-overlap-md;
+ }
+}
+
+@media (max-width: 768px) {
+ .content-wrap--landing-hub .portal-page-shell .services-section,
+ .qych-landing .services-section {
+ margin-top: -@portal-landing-cards-overlap-sm;
+ padding-left: var(--page-gutter-x, 16px);
+ padding-right: var(--page-gutter-x, 16px);
+ }
+}
+
+@media screen and (max-height: 720px) {
+ .content-wrap--landing-hub .portal-page-shell .services-section,
+ .qych-landing .services-section {
+ padding-top: clamp(28px, 3vh, 40px);
+ .portal-landing-cards-area-flat();
+ }
+}
diff --git a/txw-mhzc-web/src/pages/index/utils/home-figma-scale.js b/txw-mhzc-web/src/pages/index/utils/home-figma-scale.js
new file mode 100644
index 0000000..9e270d8
--- /dev/null
+++ b/txw-mhzc-web/src/pages/index/utils/home-figma-scale.js
@@ -0,0 +1,128 @@
+/** Figma 首页画布 1440 × 5079,整页(含顶栏)等比缩放 */
+export const HOME_FIGMA_DESIGN_WIDTH = 1440;
+export const HOME_FIGMA_DESIGN_HEIGHT = 5079;
+export const HOME_FIGMA_NAV_HEIGHT = 64;
+export const HOME_FIGMA_HERO_HEIGHT = 686;
+export const HOME_FIGMA_CORE_HEIGHT = 686;
+export const HOME_FIGMA_ABILITY_HEIGHT = 686;
+export const HOME_FIGMA_EXPORT_HEIGHT = 686;
+export const HOME_FIGMA_NEWS_HEIGHT = 684;
+export const HOME_FIGMA_PARTNER_HEIGHT = 689;
+export const HOME_FIGMA_CTA_HEIGHT = 686;
+export const HOME_FIGMA_FOOTER_HEIGHT = 212;
+export const HOME_FIGMA_HERO_CONTENT_PAD = 64;
+export const HOME_FIGMA_SCALE_MIN_WIDTH = 768;
+/** 抵消 transform:scale 取整误差,避免 section 底部露 1~12px 白边 */
+export const HOME_FIGMA_FILL_VISUAL_BUFFER = 12;
+
+function calcFillDesignHeight(baseHeight, vh, scale) {
+ const filled = Math.ceil((vh + HOME_FIGMA_FILL_VISUAL_BUFFER) / scale) + 1;
+ return Math.max(baseHeight, filled);
+}
+
+export function calcHomeFigmaScale(viewportWidth, viewportHeight) {
+ if (viewportWidth < HOME_FIGMA_SCALE_MIN_WIDTH) {
+ return {
+ enabled: false,
+ scale: 1,
+ stageMarginBottom: 0,
+ navHeightPx: HOME_FIGMA_NAV_HEIGHT,
+ heroDesignHeight: HOME_FIGMA_HERO_HEIGHT,
+ sectionDesignHeight: HOME_FIGMA_CORE_HEIGHT,
+ newsSectionDesignHeight: HOME_FIGMA_NEWS_HEIGHT,
+ partnerSectionDesignHeight: HOME_FIGMA_PARTNER_HEIGHT,
+ ctaDesignHeight: HOME_FIGMA_CTA_HEIGHT,
+ designHeight: HOME_FIGMA_DESIGN_HEIGHT,
+ };
+ }
+
+ const scale = viewportWidth / HOME_FIGMA_DESIGN_WIDTH;
+ const navHeightPx = HOME_FIGMA_NAV_HEIGHT * scale;
+ const vh = viewportHeight || (typeof window !== 'undefined' ? window.innerHeight : 900);
+
+ const heroDesignHeight = calcFillDesignHeight(HOME_FIGMA_HERO_HEIGHT, vh, scale);
+ const sectionDesignHeight = calcFillDesignHeight(HOME_FIGMA_CORE_HEIGHT, vh, scale);
+ const newsSectionDesignHeight = calcFillDesignHeight(HOME_FIGMA_NEWS_HEIGHT, vh, scale);
+ const partnerSectionDesignHeight = calcFillDesignHeight(HOME_FIGMA_PARTNER_HEIGHT, vh, scale);
+ // CTA 独占一屏;页脚为固定高度 footer,不单独占屏
+ const ctaDesignHeight = calcFillDesignHeight(HOME_FIGMA_CTA_HEIGHT, vh, scale);
+
+ const designHeight = HOME_FIGMA_DESIGN_HEIGHT
+ + (heroDesignHeight - HOME_FIGMA_HERO_HEIGHT)
+ + (sectionDesignHeight - HOME_FIGMA_CORE_HEIGHT)
+ + (sectionDesignHeight - HOME_FIGMA_ABILITY_HEIGHT)
+ + (sectionDesignHeight - HOME_FIGMA_EXPORT_HEIGHT)
+ + (newsSectionDesignHeight - HOME_FIGMA_NEWS_HEIGHT)
+ + (partnerSectionDesignHeight - HOME_FIGMA_PARTNER_HEIGHT)
+ + (ctaDesignHeight - HOME_FIGMA_CTA_HEIGHT);
+
+ return {
+ enabled: true,
+ scale,
+ stageMarginBottom: designHeight * (scale - 1),
+ navHeightPx,
+ heroDesignHeight,
+ sectionDesignHeight,
+ newsSectionDesignHeight,
+ partnerSectionDesignHeight,
+ ctaDesignHeight,
+ designHeight,
+ };
+}
+
+/** 写入 documentElement,供首页与顶栏共用同一 scale */
+export function applyHomeFigmaScaleToRoot(viewportWidth, viewportHeight) {
+ const result = calcHomeFigmaScale(viewportWidth, viewportHeight);
+ const root = document.documentElement;
+
+ if (!result.enabled) {
+ root.classList.remove('portal-figma-scale-active');
+ root.style.removeProperty('--home-figma-scale');
+ root.style.removeProperty('--home-figma-stage-margin-bottom');
+ root.style.removeProperty('--home-figma-nav-stage-margin-bottom');
+ root.style.removeProperty('--home-figma-hero-design-height');
+ root.style.removeProperty('--home-figma-section-design-height');
+ root.style.removeProperty('--home-figma-news-section-design-height');
+ root.style.removeProperty('--home-figma-partner-section-design-height');
+ root.style.removeProperty('--home-figma-cta-design-height');
+ root.style.removeProperty('--home-figma-visual-height');
+ root.style.removeProperty('--home-section-min-h');
+ root.style.removeProperty('--home-news-section-min-h');
+ root.style.removeProperty('--page-nav-height');
+ return result;
+ }
+
+ root.classList.add('portal-figma-scale-active');
+ root.style.setProperty('--home-figma-scale', String(result.scale));
+ root.style.setProperty('--home-figma-stage-margin-bottom', `${result.stageMarginBottom}px`);
+ root.style.setProperty('--home-figma-hero-design-height', `${result.heroDesignHeight}px`);
+ root.style.setProperty('--home-figma-section-design-height', `${result.sectionDesignHeight}px`);
+ root.style.setProperty('--home-figma-news-section-design-height', `${result.newsSectionDesignHeight}px`);
+ root.style.setProperty('--home-figma-partner-section-design-height', `${result.partnerSectionDesignHeight}px`);
+ root.style.setProperty('--home-figma-cta-design-height', `${result.ctaDesignHeight}px`);
+ root.style.setProperty('--home-figma-visual-height', `${Math.ceil(result.designHeight * result.scale)}px`);
+ root.style.setProperty('--home-section-min-h', `${result.sectionDesignHeight}px`);
+ root.style.setProperty('--home-news-section-min-h', `${result.newsSectionDesignHeight}px`);
+ root.style.setProperty('--page-nav-height', `${result.navHeightPx}px`);
+ root.style.setProperty('--home-figma-nav-stage-margin-bottom', `${HOME_FIGMA_NAV_HEIGHT * (result.scale - 1)}px`);
+ return result;
+}
+
+export function clearHomeFigmaScaleFromRoot() {
+ applyHomeFigmaScaleToRoot(HOME_FIGMA_SCALE_MIN_WIDTH - 1);
+}
+
+/** 按 stage 实测布局高度修正 margin-bottom 与整页视觉高度,消除页脚下方空白 */
+export function syncHomeFigmaStageLayout(stageEl, scale) {
+ if (!stageEl || !scale) return null;
+
+ const layoutHeight = stageEl.offsetHeight;
+ const marginBottom = layoutHeight * (scale - 1);
+ const visualHeight = layoutHeight * scale;
+ const root = document.documentElement;
+
+ root.style.setProperty('--home-figma-stage-margin-bottom', `${marginBottom}px`);
+ root.style.setProperty('--home-figma-visual-height', `${Math.ceil(visualHeight)}px`);
+
+ return { layoutHeight, visualHeight, marginBottom };
+}
diff --git a/txw-mhzc-web/src/pages/index/utils/portal-figma-scale-mixin.js b/txw-mhzc-web/src/pages/index/utils/portal-figma-scale-mixin.js
new file mode 100644
index 0000000..3ffa70d
--- /dev/null
+++ b/txw-mhzc-web/src/pages/index/utils/portal-figma-scale-mixin.js
@@ -0,0 +1,31 @@
+import { syncPortalFigmaStageLayout } from './portal-figma-scale';
+
+/** 门户 Figma 等比缩放页:mounted/resize 时同步 stage 实测高度 */
+export default {
+ mounted() {
+ this._onPortalFigmaResize = () => {
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => this.syncPortalFigmaStageLayout());
+ });
+ };
+ window.addEventListener('resize', this._onPortalFigmaResize);
+ this.$nextTick(() => this.syncPortalFigmaStageLayout());
+ },
+ beforeDestroy() {
+ if (this._onPortalFigmaResize) {
+ window.removeEventListener('resize', this._onPortalFigmaResize);
+ this._onPortalFigmaResize = null;
+ }
+ },
+ methods: {
+ syncPortalFigmaStageLayout() {
+ if (window.innerWidth < 768) return;
+ const stage = this.$refs.figmaStage;
+ if (!stage) return;
+ const scale = parseFloat(
+ getComputedStyle(document.documentElement).getPropertyValue('--home-figma-scale'),
+ ) || (window.innerWidth / 1440);
+ syncPortalFigmaStageLayout(stage, scale);
+ },
+ },
+};
diff --git a/txw-mhzc-web/src/pages/index/utils/portal-figma-scale.js b/txw-mhzc-web/src/pages/index/utils/portal-figma-scale.js
new file mode 100644
index 0000000..84fffd7
--- /dev/null
+++ b/txw-mhzc-web/src/pages/index/utils/portal-figma-scale.js
@@ -0,0 +1,199 @@
+import {
+ HOME_FIGMA_DESIGN_WIDTH,
+ HOME_FIGMA_SCALE_MIN_WIDTH,
+ HOME_FIGMA_NAV_HEIGHT,
+ HOME_FIGMA_FILL_VISUAL_BUFFER,
+ applyHomeFigmaScaleToRoot,
+ clearHomeFigmaScaleFromRoot,
+ syncHomeFigmaStageLayout,
+} from './home-figma-scale';
+
+/** 落地页 / 市场页首屏最小设计高度(随视口撑满) */
+export const PORTAL_LANDING_FIRST_SCREEN_HEIGHT = 686;
+/** main.vue 中未参与 scale 的页脚大致高度 */
+export const PORTAL_LAYOUT_FOOTER_HEIGHT = 212;
+
+const PORTAL_LANDING_PATHS = new Set(['/fwsc', '/hyzt', '/qych', '/gxnlpt']);
+const PORTAL_MARKET_PATHS = new Set(['/tfwsc', '/txqsc', '/tsjsc', '/tjrsc', '/tsjlbc']);
+
+export function normalizePortalPath(path) {
+ if (!path) return '';
+ let p = path.split('?')[0];
+ if (p.startsWith('/view/mhzc')) {
+ p = p.slice('/view/mhzc'.length) || '/';
+ }
+ return p;
+}
+
+export function isPortalMarketPage(path) {
+ return PORTAL_MARKET_PATHS.has(normalizePortalPath(path));
+}
+
+export function isPortalLandingHubPage(path) {
+ return PORTAL_LANDING_PATHS.has(normalizePortalPath(path));
+}
+
+export function isHomeFigmaPage(path) {
+ const p = normalizePortalPath(path);
+ return p === '/home' || p === '/';
+}
+
+export function isPortalFigmaScalePage(path) {
+ return isHomeFigmaPage(path)
+ || isPortalLandingHubPage(path)
+ || isPortalMarketPage(path);
+}
+
+function calcFillDesignHeight(baseHeight, vh, scale) {
+ const filled = Math.ceil((vh + HOME_FIGMA_FILL_VISUAL_BUFFER) / scale) + 1;
+ return Math.max(baseHeight, filled);
+}
+
+export function calcLandingFigmaScale(viewportWidth, viewportHeight) {
+ if (viewportWidth < HOME_FIGMA_SCALE_MIN_WIDTH) {
+ return {
+ enabled: false,
+ scale: 1,
+ shellMinDesignHeight: PORTAL_LANDING_FIRST_SCREEN_HEIGHT,
+ navHeightPx: HOME_FIGMA_NAV_HEIGHT,
+ };
+ }
+
+ const scale = viewportWidth / HOME_FIGMA_DESIGN_WIDTH;
+ const vh = viewportHeight || (typeof window !== 'undefined' ? window.innerHeight : 900);
+ const shellMinDesignHeight = calcFillDesignHeight(PORTAL_LANDING_FIRST_SCREEN_HEIGHT, vh, scale);
+ const navHeightPx = HOME_FIGMA_NAV_HEIGHT * scale;
+
+ return {
+ enabled: true,
+ scale,
+ shellMinDesignHeight,
+ navHeightPx,
+ };
+}
+
+/** 市场列表页:扣除顶栏与页脚后的可视区至少一屏 */
+export function calcMarketFigmaScale(viewportWidth, viewportHeight) {
+ if (viewportWidth < HOME_FIGMA_SCALE_MIN_WIDTH) {
+ return {
+ enabled: false,
+ scale: 1,
+ shellMinDesignHeight: PORTAL_LANDING_FIRST_SCREEN_HEIGHT,
+ navHeightPx: HOME_FIGMA_NAV_HEIGHT,
+ };
+ }
+
+ const scale = viewportWidth / HOME_FIGMA_DESIGN_WIDTH;
+ const vh = viewportHeight || (typeof window !== 'undefined' ? window.innerHeight : 900);
+ const navHeightPx = HOME_FIGMA_NAV_HEIGHT * scale;
+ const contentAreaPx = Math.max(vh - navHeightPx - PORTAL_LAYOUT_FOOTER_HEIGHT, 320);
+ const shellMinDesignHeight = calcFillDesignHeight(
+ PORTAL_LANDING_FIRST_SCREEN_HEIGHT,
+ contentAreaPx,
+ scale,
+ );
+
+ return {
+ enabled: true,
+ scale,
+ shellMinDesignHeight,
+ navHeightPx,
+ };
+}
+
+function clearPortalScaleModeClasses(root) {
+ root.classList.remove('portal-landing-figma-scale-active');
+ root.classList.remove('portal-market-figma-scale-active');
+}
+
+function applySharedPortalScaleVars(root, result) {
+ root.classList.add('portal-figma-scale-active');
+ root.style.setProperty('--home-figma-scale', String(result.scale));
+ root.style.setProperty('--portal-shell-min-design-height', `${result.shellMinDesignHeight}px`);
+ root.style.setProperty('--page-nav-height', `${result.navHeightPx}px`);
+ root.style.setProperty('--home-figma-nav-stage-margin-bottom', `${HOME_FIGMA_NAV_HEIGHT * (result.scale - 1)}px`);
+
+ root.style.removeProperty('--home-figma-hero-design-height');
+ root.style.removeProperty('--home-figma-section-design-height');
+ root.style.removeProperty('--home-figma-news-section-design-height');
+ root.style.removeProperty('--home-figma-partner-section-design-height');
+ root.style.removeProperty('--home-figma-cta-design-height');
+ root.style.removeProperty('--home-section-min-h');
+ root.style.removeProperty('--home-news-section-min-h');
+}
+
+function applyLandingFigmaScaleToRoot(viewportWidth, viewportHeight) {
+ const result = calcLandingFigmaScale(viewportWidth, viewportHeight);
+ const root = document.documentElement;
+
+ if (!result.enabled) {
+ clearPortalFigmaScaleFromRoot();
+ return result;
+ }
+
+ clearPortalScaleModeClasses(root);
+ root.classList.add('portal-landing-figma-scale-active');
+ applySharedPortalScaleVars(root, result);
+ root.style.setProperty('--portal-landing-first-screen-height', `${result.shellMinDesignHeight}px`);
+ root.style.removeProperty('--portal-market-shell-min-height');
+
+ return result;
+}
+
+function applyMarketFigmaScaleToRoot(viewportWidth, viewportHeight) {
+ const result = calcMarketFigmaScale(viewportWidth, viewportHeight);
+ const root = document.documentElement;
+
+ if (!result.enabled) {
+ clearPortalFigmaScaleFromRoot();
+ return result;
+ }
+
+ clearPortalScaleModeClasses(root);
+ root.classList.add('portal-market-figma-scale-active');
+ applySharedPortalScaleVars(root, result);
+ root.style.setProperty('--portal-market-shell-min-height', `${result.shellMinDesignHeight}px`);
+ root.style.setProperty(
+ '--home-figma-visual-height',
+ `${Math.ceil(result.shellMinDesignHeight * result.scale)}px`,
+ );
+ root.style.setProperty(
+ '--home-figma-stage-margin-bottom',
+ `${result.shellMinDesignHeight * (result.scale - 1)}px`,
+ );
+ root.style.removeProperty('--portal-landing-first-screen-height');
+
+ return result;
+}
+
+/** 首页 / 落地 hub / 市场列表页 统一入口 */
+export function applyPortalFigmaScaleToRoot(viewportWidth, viewportHeight, routePath) {
+ if (viewportWidth < HOME_FIGMA_SCALE_MIN_WIDTH || !isPortalFigmaScalePage(routePath)) {
+ clearPortalFigmaScaleFromRoot();
+ return { enabled: false };
+ }
+
+ if (isHomeFigmaPage(routePath)) {
+ clearPortalScaleModeClasses(document.documentElement);
+ return applyHomeFigmaScaleToRoot(viewportWidth, viewportHeight);
+ }
+
+ if (isPortalMarketPage(routePath)) {
+ return applyMarketFigmaScaleToRoot(viewportWidth, viewportHeight);
+ }
+
+ return applyLandingFigmaScaleToRoot(viewportWidth, viewportHeight);
+}
+
+export function clearPortalFigmaScaleFromRoot() {
+ const root = document.documentElement;
+ clearPortalScaleModeClasses(root);
+ root.style.removeProperty('--portal-landing-first-screen-height');
+ root.style.removeProperty('--portal-market-shell-min-height');
+ root.style.removeProperty('--portal-shell-min-design-height');
+ clearHomeFigmaScaleFromRoot();
+}
+
+export function syncPortalFigmaStageLayout(stageEl, scale) {
+ return syncHomeFigmaStageLayout(stageEl, scale);
+}
diff --git a/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue b/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue
index 871631e..e96a994 100644
--- a/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue
+++ b/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue
@@ -1,5 +1,7 @@
-
+
+
+
@@ -138,6 +140,8 @@
:page-size-options="[10, 20, 30, 50]" @change="onPageChange" align="center" />
+
+
@@ -178,9 +182,11 @@ import FwscPublish from './components/FwscPublish.vue';
import api from '@/pages/index/api/fwsc/index.js';
import { hasLogin } from '@/pages/index/api/login';
import { scrollPortalContentToTop } from '@/pages/index/utils/portal-scroll-mode';
+import portalFigmaScaleMixin from '@/pages/index/utils/portal-figma-scale-mixin';
export default {
name: 'FwscPage',
+ mixins: [portalFigmaScaleMixin],
components: {
NewNav,
BreadcrumbNav,
@@ -486,8 +492,11 @@ export default {