-
+
-
-
+
diff --git a/archive.php b/archive.php
index a2ec4b2..716fb36 100644
--- a/archive.php
+++ b/archive.php
@@ -5,18 +5,64 @@ if ( ! defined( 'ABSPATH' ) ) {
}
get_header();
+
+$is_news_archive = is_category() || is_tag() || is_date() || is_author();
?>
-
- ' ); ?>
-
-
-
-
-
+
+
+
+ array(
+ array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
+ array( 'label' => __( '新闻资讯', 'fragrance-trade' ), 'url' => fragrance_trade_news_url() ),
+ array( 'label' => wp_strip_all_tags( get_the_archive_title() ), 'url' => null ),
+ ),
+ )
+ );
+ ?>
+
' ); ?>
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+ ' ); ?>
+
+
+
+
+
+
+
+
diff --git a/assets/css/theme.css b/assets/css/theme.css
index b0b58ef..274695a 100644
--- a/assets/css/theme.css
+++ b/assets/css/theme.css
@@ -416,7 +416,9 @@ img {
/* ---- Trust Strip ---- */
.trust-strip {
color: var(--b2b-surface);
- background: var(--b2b-ink);
+ background:
+ linear-gradient(90deg, rgba(20, 20, 18, 0.9), rgba(20, 20, 18, 0.76)),
+ url("../images/trust-workshop-bg.jpg") 62% 55% / cover no-repeat;
}
.trust-metric {
@@ -460,6 +462,10 @@ img {
background: var(--b2b-line);
}
+.capability-grid-archive {
+ background: transparent;
+}
+
.capability-card {
display: grid;
min-width: 0;
@@ -474,7 +480,14 @@ img {
background: var(--b2b-mist);
}
+.capability-image a {
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+
.capability-image img {
+ display: block;
width: 100%;
height: 100%;
object-fit: cover;
@@ -536,6 +549,139 @@ img {
align-self: flex-start;
}
+/* ---- Homepage Carousels ---- */
+.b2b-carousel {
+ --carousel-gap: 1px;
+ --carousel-items: 1;
+}
+
+.services-carousel {
+ --carousel-items: 2;
+}
+
+.cases-carousel {
+ --carousel-items: 2;
+}
+
+.b2b-carousel-viewport {
+ overflow-x: auto;
+ overflow-y: hidden;
+ overscroll-behavior-x: contain;
+ scroll-snap-type: x mandatory;
+ scrollbar-width: none;
+ -webkit-overflow-scrolling: touch;
+}
+
+.b2b-carousel-viewport::-webkit-scrollbar {
+ display: none;
+}
+
+.b2b-carousel .b2b-carousel-track {
+ display: grid;
+ width: auto;
+ grid-auto-flow: column;
+ grid-auto-columns: 100%;
+ grid-template-columns: none;
+ gap: var(--carousel-gap);
+}
+
+.services-carousel .b2b-carousel-track {
+ grid-auto-columns: calc(50% - 0.5px);
+}
+
+.cases-carousel .b2b-carousel-track {
+ grid-auto-columns: calc(50% - 0.5px);
+}
+
+.b2b-carousel-slide {
+ min-width: 0;
+ scroll-snap-align: start;
+}
+
+.b2b-carousel-controls {
+ display: none;
+ min-height: 44px;
+ margin-top: 1.5rem;
+ align-items: center;
+ justify-content: center;
+ gap: 1.25rem;
+}
+
+.b2b-carousel.is-ready .b2b-carousel-controls {
+ display: flex;
+}
+
+.b2b-carousel.is-ready.has-single-page .b2b-carousel-controls {
+ display: none;
+}
+
+.b2b-carousel-arrow,
+.b2b-carousel-dot {
+ appearance: none;
+ color: var(--b2b-ink);
+ background: transparent;
+ border: 0;
+ border-radius: 0;
+ cursor: pointer;
+}
+
+.b2b-carousel-arrow {
+ display: inline-flex;
+ width: 44px;
+ height: 44px;
+ padding: 0;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid var(--b2b-line);
+ font-size: 1.1rem;
+ line-height: 1;
+ transition:
+ color 180ms ease,
+ background-color 180ms ease,
+ border-color 180ms ease,
+ transform 180ms ease;
+}
+
+.b2b-carousel-arrow:hover {
+ color: var(--b2b-surface);
+ background: var(--b2b-ink);
+ border-color: var(--b2b-ink);
+ transform: translateY(-2px);
+}
+
+.b2b-carousel-arrow:active {
+ transform: translateY(0);
+}
+
+.b2b-carousel-arrow:focus-visible,
+.b2b-carousel-dot:focus-visible {
+ outline: 2px solid var(--b2b-ink);
+ outline-offset: 3px;
+}
+
+.b2b-carousel-dots {
+ display: flex;
+ min-width: 64px;
+ align-items: center;
+ justify-content: center;
+ gap: 0.6rem;
+}
+
+.b2b-carousel-dot {
+ width: 7px;
+ height: 7px;
+ padding: 0;
+ background: var(--b2b-line);
+ transition:
+ width 220ms ease,
+ background-color 220ms ease;
+}
+
+.b2b-carousel-dot.is-active {
+ width: 24px;
+ background: var(--b2b-ink);
+}
+
/* ---- Case Grid ---- */
.cases-section {
background: var(--b2b-mist);
@@ -548,6 +694,10 @@ img {
background: var(--b2b-line);
}
+.case-grid-archive {
+ background: transparent;
+}
+
.case-card {
position: relative;
display: block;
@@ -600,7 +750,9 @@ img {
/* ---- CTA Section ---- */
.cta-section {
- background: var(--b2b-ink);
+ background:
+ linear-gradient(90deg, rgba(20, 20, 18, 0.88), rgba(20, 20, 18, 0.7)),
+ url("../images/consultation-studio-bg.jpg") center 58% / cover no-repeat;
color: var(--b2b-surface);
text-align: center;
padding: 5rem 0;
@@ -881,7 +1033,9 @@ img {
/* ---- Documents Section ---- */
.documents-section {
color: rgba(250, 250, 248, 0.65);
- background: var(--b2b-ink);
+ background:
+ linear-gradient(90deg, rgba(20, 20, 18, 0.95), rgba(20, 20, 18, 0.86)),
+ url("../images/trust-workshop-bg.jpg") center 55% / cover no-repeat;
}
.documents-section h2,
@@ -902,7 +1056,7 @@ img {
min-width: 0;
padding: 1.75rem;
gap: 1rem;
- background: var(--b2b-ink);
+ background: rgba(28, 28, 26, 0.88);
}
.document-grid article > span {
@@ -969,10 +1123,21 @@ img {
}
.footer-bottom {
+ align-items: center;
border-color: rgba(250, 250, 248, 0.08) !important;
font-size: 0.78rem;
}
+.footer-icp {
+ text-align: center;
+}
+
+.footer-icp a {
+ text-decoration: underline;
+ text-decoration-color: rgba(250, 250, 248, 0.22);
+ text-underline-offset: 0.2em;
+}
+
/* ---- WordPress Content Area ---- */
.fragrance-content-area {
min-height: 65vh;
@@ -1101,14 +1266,35 @@ textarea:focus-visible {
/* ---- About Page CTA ---- */
.about-cta {
padding: 5rem 0;
- background: var(--b2b-mist);
+ color: var(--b2b-surface);
+ background:
+ linear-gradient(90deg, rgba(20, 20, 18, 0.88), rgba(20, 20, 18, 0.7)),
+ url("../images/consultation-studio-bg.jpg") center 58% / cover no-repeat;
text-align: center;
}
.about-cta h2 {
+ color: var(--b2b-surface);
font-size: clamp(1.8rem, 3vw, 2.4rem);
}
+.about-cta .section-lead {
+ color: rgba(250, 250, 248, 0.74);
+}
+
+.about-cta .btn-b2b-primary {
+ color: var(--b2b-ink);
+ background: var(--b2b-surface);
+ border-color: var(--b2b-surface);
+}
+
+.about-cta .btn-b2b-primary:hover,
+.about-cta .btn-b2b-primary:focus {
+ color: var(--b2b-ink);
+ background: var(--b2b-mist);
+ border-color: var(--b2b-mist);
+}
+
/* ---- Contact Page ---- */
.contact-section {
padding-top: 0;
@@ -1289,6 +1475,319 @@ textarea:focus-visible {
color: var(--b2b-ink-soft);
}
+/* ---- News ---- */
+.news-page {
+ padding-bottom: clamp(5rem, 8vw, 8rem);
+}
+
+.news-page-header {
+ max-width: 760px;
+ padding: 1.5rem 0 clamp(3rem, 6vw, 5rem);
+}
+
+.news-page-header h1 {
+ margin-bottom: 1.25rem;
+ font-family: var(--b2b-font-display);
+ font-size: clamp(2.7rem, 5vw, 4.8rem);
+ font-weight: 300;
+}
+
+.news-page-header > p:last-child,
+.news-page-header .archive-description {
+ color: var(--b2b-ink-soft);
+ font-size: 1.05rem;
+ line-height: 1.8;
+}
+
+.news-page-header .archive-description > :last-child {
+ margin-bottom: 0;
+}
+
+.news-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: clamp(1.25rem, 2.5vw, 2rem);
+}
+
+.news-card {
+ display: flex;
+ min-width: 0;
+ height: 100%;
+ overflow: hidden;
+ background: var(--b2b-surface);
+ border: 1px solid var(--b2b-line);
+ flex-direction: column;
+ transition:
+ border-color 180ms ease,
+ transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
+}
+
+.news-card:hover {
+ border-color: var(--b2b-ink-muted);
+ transform: translateY(-3px);
+}
+
+.news-card-media {
+ display: block;
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ background: var(--b2b-mist);
+}
+
+.news-card-media img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 650ms cubic-bezier(0.2, 0.7, 0.2, 1);
+}
+
+.news-card:hover .news-card-media img {
+ transform: scale(1.025);
+}
+
+.news-card-body {
+ display: flex;
+ padding: clamp(1.35rem, 2.5vw, 2rem);
+ flex: 1;
+ flex-direction: column;
+}
+
+.news-meta {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0.5rem 1rem;
+ margin-bottom: 1rem;
+ color: var(--b2b-ink-muted);
+ font-size: 0.74rem;
+ letter-spacing: 0.06em;
+}
+
+.news-categories a {
+ color: var(--b2b-ink);
+ font-weight: 600;
+ text-decoration: none;
+}
+
+.news-categories a:hover,
+.news-categories a:focus {
+ opacity: 0.65;
+}
+
+.news-card h2 {
+ margin-bottom: 1rem;
+ font-family: var(--b2b-font-display);
+ font-size: clamp(1.45rem, 2vw, 1.9rem);
+ font-weight: 400;
+ line-height: 1.28;
+}
+
+.news-card h2 a {
+ color: var(--b2b-ink);
+ text-decoration: none;
+}
+
+.news-card-body > p {
+ margin-bottom: 1.5rem;
+ color: var(--b2b-ink-soft);
+ line-height: 1.75;
+}
+
+.news-card-body .text-link {
+ margin-top: auto;
+ align-self: flex-start;
+}
+
+.news-pagination {
+ margin-top: clamp(3rem, 6vw, 5rem);
+}
+
+.news-pagination .nav-links,
+.news-single .page-links {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.news-pagination .page-numbers,
+.news-single .post-page-numbers {
+ display: inline-flex;
+ min-width: 2.75rem;
+ min-height: 2.75rem;
+ align-items: center;
+ justify-content: center;
+ padding: 0.6rem 0.85rem;
+ color: var(--b2b-ink);
+ background: var(--b2b-surface);
+ border: 1px solid var(--b2b-line);
+ text-decoration: none;
+}
+
+.news-pagination .page-numbers.current,
+.news-pagination .page-numbers:hover,
+.news-pagination .page-numbers:focus,
+.news-single .post-page-numbers.current,
+.news-single .post-page-numbers:hover,
+.news-single .post-page-numbers:focus {
+ color: var(--b2b-surface);
+ background: var(--b2b-ink);
+ border-color: var(--b2b-ink);
+}
+
+.news-empty {
+ padding: clamp(3rem, 7vw, 6rem);
+ background: var(--b2b-mist);
+ text-align: center;
+}
+
+.news-empty h2 {
+ margin-bottom: 1rem;
+ font-family: var(--b2b-font-display);
+ font-size: clamp(1.8rem, 3vw, 2.5rem);
+ font-weight: 400;
+}
+
+.news-empty p {
+ margin: 0 auto 2rem;
+ color: var(--b2b-ink-soft);
+}
+
+.news-single {
+ padding-bottom: clamp(5rem, 8vw, 8rem);
+}
+
+.news-single-header {
+ max-width: 940px;
+ margin: 2rem auto clamp(2.5rem, 5vw, 4.5rem);
+ text-align: center;
+}
+
+.news-single-header .news-meta {
+ justify-content: center;
+}
+
+.news-single-header h1 {
+ margin: 0;
+ font-family: var(--b2b-font-display);
+ font-size: clamp(2.5rem, 5vw, 4.8rem);
+ font-weight: 300;
+ line-height: 1.14;
+}
+
+.news-single-image {
+ max-width: 1120px;
+ margin: 0 auto clamp(3rem, 6vw, 5rem);
+ overflow: hidden;
+ background: var(--b2b-mist);
+}
+
+.news-single-image img {
+ display: block;
+ width: 100%;
+ height: auto;
+}
+
+.news-single-content {
+ max-width: 800px;
+ margin: 0 auto;
+ color: var(--b2b-ink);
+ font-size: 1.05rem;
+ line-height: 1.9;
+}
+
+.news-single-content > * {
+ max-width: 100%;
+}
+
+.news-single-content h2,
+.news-single-content h3,
+.news-single-content h4 {
+ margin-top: 2.25em;
+ margin-bottom: 0.75em;
+ font-family: var(--b2b-font-display);
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.news-single-content a {
+ color: var(--b2b-ink);
+ text-underline-offset: 0.18em;
+}
+
+.news-single-content img,
+.news-single-content figure {
+ height: auto;
+}
+
+.news-single-content blockquote {
+ margin: 2rem 0;
+ padding: 0.25rem 0 0.25rem 1.5rem;
+ color: var(--b2b-ink-soft);
+ border-left: 3px solid var(--b2b-ink);
+}
+
+.news-single .page-links {
+ margin-top: 2.5rem;
+}
+
+.news-post-navigation {
+ max-width: 960px;
+ margin: clamp(4rem, 8vw, 7rem) auto 0;
+ padding-top: 2rem;
+ border-top: 1px solid var(--b2b-line);
+}
+
+.news-post-navigation .nav-links {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 2rem;
+}
+
+.news-post-navigation .nav-next {
+ text-align: right;
+}
+
+.news-post-navigation a {
+ display: inline-flex;
+ color: var(--b2b-ink);
+ flex-direction: column;
+ text-decoration: none;
+}
+
+.news-post-navigation .nav-subtitle {
+ margin-bottom: 0.5rem;
+ color: var(--b2b-ink-muted);
+ font-size: 0.72rem;
+ letter-spacing: 0.1em;
+}
+
+.news-post-navigation .nav-title {
+ font-family: var(--b2b-font-display);
+ font-size: 1.25rem;
+}
+
+.news-single-cta {
+ max-width: 960px;
+ margin: clamp(3rem, 6vw, 5rem) auto 0;
+ padding: clamp(2rem, 5vw, 4rem);
+ background: var(--b2b-mist);
+ text-align: center;
+}
+
+.news-single-cta h2 {
+ margin-bottom: 1rem;
+ font-family: var(--b2b-font-display);
+ font-size: clamp(1.8rem, 3vw, 2.5rem);
+ font-weight: 400;
+}
+
+.news-single-cta p {
+ max-width: 650px;
+ margin: 0 auto 2rem;
+ color: var(--b2b-ink-soft);
+}
+
/* ---- Reveal Motion ---- */
.motion-ready .reveal-item {
opacity: 0;
@@ -1395,6 +1894,7 @@ textarea:focus-visible {
.b2b-header .offcanvas .nav-item:nth-child(4) { transition-delay: 120ms; }
.b2b-header .offcanvas .nav-item:nth-child(5) { transition-delay: 160ms; }
.b2b-header .offcanvas .nav-item:nth-child(6) { transition-delay: 200ms; }
+ .b2b-header .offcanvas .nav-item:nth-child(7) { transition-delay: 240ms; }
.b2b-header .offcanvas.hiding .nav-item {
opacity: 0;
@@ -1442,6 +1942,14 @@ textarea:focus-visible {
/* LG down — 991px */
@media (max-width: 991px) {
+ .cases-carousel {
+ --carousel-items: 1;
+ }
+
+ .cases-carousel .b2b-carousel-track {
+ grid-auto-columns: 100%;
+ }
+
.b2b-section {
padding: 5rem 0;
}
@@ -1459,6 +1967,10 @@ textarea:focus-visible {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
+ .news-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
.factory-video-section {
padding-bottom: 5rem;
}
@@ -1533,6 +2045,19 @@ textarea:focus-visible {
grid-template-columns: 1fr;
}
+ .news-grid,
+ .news-post-navigation .nav-links {
+ grid-template-columns: 1fr;
+ }
+
+ .news-post-navigation .nav-next {
+ text-align: left;
+ }
+
+ .b2b-carousel-controls {
+ margin-top: 1.25rem;
+ }
+
.factory-gallery {
grid-template-rows: repeat(2, 160px);
}
@@ -1591,8 +2116,25 @@ textarea:focus-visible {
}
}
+/* XS carousel — 575px */
+@media (max-width: 575px) {
+ .services-carousel,
+ .cases-carousel {
+ --carousel-items: 1;
+ }
+
+ .b2b-carousel .b2b-carousel-track {
+ grid-auto-columns: 100%;
+ grid-template-columns: none;
+ }
+}
+
/* SM down — 480px */
@media (max-width: 480px) {
+ .row.g-5 {
+ --bs-gutter-x: 1.5rem;
+ }
+
.b2b-hero .btn {
width: 100%;
}
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/01.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/01.jpg
new file mode 100644
index 0000000..37b57d8
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/01.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/02.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/02.jpg
new file mode 100644
index 0000000..133033e
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/02.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/03.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/03.jpg
new file mode 100644
index 0000000..7092aa4
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/03.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/04.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/04.jpg
new file mode 100644
index 0000000..8298fed
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/04.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/05.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/05.jpg
new file mode 100644
index 0000000..81ad9ca
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/05.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/06.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/06.jpg
new file mode 100644
index 0000000..9f2b1a5
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/06.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/07.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/07.jpg
new file mode 100644
index 0000000..0724c10
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/07.jpg differ
diff --git a/assets/images/cases/byd-han-matte-blue-gold-floating-roof/08.jpg b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/08.jpg
new file mode 100644
index 0000000..68208f6
Binary files /dev/null and b/assets/images/cases/byd-han-matte-blue-gold-floating-roof/08.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/01.jpg b/assets/images/cases/changan-uni-v-gt-silver/01.jpg
new file mode 100644
index 0000000..a2c5d43
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/01.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/02.jpg b/assets/images/cases/changan-uni-v-gt-silver/02.jpg
new file mode 100644
index 0000000..7ae9409
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/02.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/03.jpg b/assets/images/cases/changan-uni-v-gt-silver/03.jpg
new file mode 100644
index 0000000..77959c5
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/03.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/04.jpg b/assets/images/cases/changan-uni-v-gt-silver/04.jpg
new file mode 100644
index 0000000..3ce5022
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/04.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/05.jpg b/assets/images/cases/changan-uni-v-gt-silver/05.jpg
new file mode 100644
index 0000000..205bc4d
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/05.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/06.jpg b/assets/images/cases/changan-uni-v-gt-silver/06.jpg
new file mode 100644
index 0000000..399455d
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/06.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/07.jpg b/assets/images/cases/changan-uni-v-gt-silver/07.jpg
new file mode 100644
index 0000000..1153d5b
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/07.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/08.jpg b/assets/images/cases/changan-uni-v-gt-silver/08.jpg
new file mode 100644
index 0000000..192b317
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/08.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/09.jpg b/assets/images/cases/changan-uni-v-gt-silver/09.jpg
new file mode 100644
index 0000000..dab4ffb
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/09.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/10.jpg b/assets/images/cases/changan-uni-v-gt-silver/10.jpg
new file mode 100644
index 0000000..0b067fa
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/10.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/11.jpg b/assets/images/cases/changan-uni-v-gt-silver/11.jpg
new file mode 100644
index 0000000..0251c3a
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/11.jpg differ
diff --git a/assets/images/cases/changan-uni-v-gt-silver/12.jpg b/assets/images/cases/changan-uni-v-gt-silver/12.jpg
new file mode 100644
index 0000000..4aff59e
Binary files /dev/null and b/assets/images/cases/changan-uni-v-gt-silver/12.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/01.jpg b/assets/images/cases/chery-arrizo-alexander-silver/01.jpg
new file mode 100644
index 0000000..989592b
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/01.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/02.jpg b/assets/images/cases/chery-arrizo-alexander-silver/02.jpg
new file mode 100644
index 0000000..2046312
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/02.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/03.jpg b/assets/images/cases/chery-arrizo-alexander-silver/03.jpg
new file mode 100644
index 0000000..5a32942
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/03.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/04.jpg b/assets/images/cases/chery-arrizo-alexander-silver/04.jpg
new file mode 100644
index 0000000..eddc3eb
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/04.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/05.jpg b/assets/images/cases/chery-arrizo-alexander-silver/05.jpg
new file mode 100644
index 0000000..687ad45
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/05.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/06.jpg b/assets/images/cases/chery-arrizo-alexander-silver/06.jpg
new file mode 100644
index 0000000..1ea69ec
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/06.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/07.jpg b/assets/images/cases/chery-arrizo-alexander-silver/07.jpg
new file mode 100644
index 0000000..0c8423b
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/07.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/08.jpg b/assets/images/cases/chery-arrizo-alexander-silver/08.jpg
new file mode 100644
index 0000000..e02e93c
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/08.jpg differ
diff --git a/assets/images/cases/chery-arrizo-alexander-silver/09.jpg b/assets/images/cases/chery-arrizo-alexander-silver/09.jpg
new file mode 100644
index 0000000..1bb2157
Binary files /dev/null and b/assets/images/cases/chery-arrizo-alexander-silver/09.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/01.jpg b/assets/images/cases/ford-mondeo-alexander-silver/01.jpg
new file mode 100644
index 0000000..28e725d
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/01.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/02.jpg b/assets/images/cases/ford-mondeo-alexander-silver/02.jpg
new file mode 100644
index 0000000..a774522
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/02.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/03.jpg b/assets/images/cases/ford-mondeo-alexander-silver/03.jpg
new file mode 100644
index 0000000..bd3b20a
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/03.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/04.jpg b/assets/images/cases/ford-mondeo-alexander-silver/04.jpg
new file mode 100644
index 0000000..e599c77
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/04.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/05.jpg b/assets/images/cases/ford-mondeo-alexander-silver/05.jpg
new file mode 100644
index 0000000..3af15ad
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/05.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/06.jpg b/assets/images/cases/ford-mondeo-alexander-silver/06.jpg
new file mode 100644
index 0000000..8e490dd
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/06.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/07.jpg b/assets/images/cases/ford-mondeo-alexander-silver/07.jpg
new file mode 100644
index 0000000..b36c491
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/07.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/08.jpg b/assets/images/cases/ford-mondeo-alexander-silver/08.jpg
new file mode 100644
index 0000000..c9b123e
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/08.jpg differ
diff --git a/assets/images/cases/ford-mondeo-alexander-silver/09.jpg b/assets/images/cases/ford-mondeo-alexander-silver/09.jpg
new file mode 100644
index 0000000..20b799b
Binary files /dev/null and b/assets/images/cases/ford-mondeo-alexander-silver/09.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/01.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/01.jpg
new file mode 100644
index 0000000..2dbd591
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/01.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/02.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/02.jpg
new file mode 100644
index 0000000..1391246
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/02.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/03.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/03.jpg
new file mode 100644
index 0000000..f7a5e95
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/03.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/04.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/04.jpg
new file mode 100644
index 0000000..9bb7a99
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/04.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/05.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/05.jpg
new file mode 100644
index 0000000..3f3c461
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/05.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/06.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/06.jpg
new file mode 100644
index 0000000..0282148
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/06.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/07.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/07.jpg
new file mode 100644
index 0000000..6831c1e
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/07.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/08.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/08.jpg
new file mode 100644
index 0000000..a1efeb6
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/08.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/09.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/09.jpg
new file mode 100644
index 0000000..c1a0caa
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/09.jpg differ
diff --git a/assets/images/cases/porsche-718-liquid-metal-silver/10.jpg b/assets/images/cases/porsche-718-liquid-metal-silver/10.jpg
new file mode 100644
index 0000000..78f8395
Binary files /dev/null and b/assets/images/cases/porsche-718-liquid-metal-silver/10.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/01.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/01.jpg
new file mode 100644
index 0000000..d21f39b
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/01.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/02.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/02.jpg
new file mode 100644
index 0000000..5dbf617
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/02.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/03.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/03.jpg
new file mode 100644
index 0000000..c487b84
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/03.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/04.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/04.jpg
new file mode 100644
index 0000000..e4b514f
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/04.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/05.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/05.jpg
new file mode 100644
index 0000000..0b6d4e5
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/05.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/06.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/06.jpg
new file mode 100644
index 0000000..9336f69
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/06.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/07.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/07.jpg
new file mode 100644
index 0000000..5c79a8a
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/07.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/08.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/08.jpg
new file mode 100644
index 0000000..98b8c00
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/08.jpg differ
diff --git a/assets/images/cases/tesla-model-3-highland-alexander-silver/09.jpg b/assets/images/cases/tesla-model-3-highland-alexander-silver/09.jpg
new file mode 100644
index 0000000..63d00de
Binary files /dev/null and b/assets/images/cases/tesla-model-3-highland-alexander-silver/09.jpg differ
diff --git a/assets/images/consultation-studio-bg.jpg b/assets/images/consultation-studio-bg.jpg
new file mode 100644
index 0000000..685bb19
Binary files /dev/null and b/assets/images/consultation-studio-bg.jpg differ
diff --git a/assets/images/placeholder-news.svg b/assets/images/placeholder-news.svg
new file mode 100644
index 0000000..7787f48
--- /dev/null
+++ b/assets/images/placeholder-news.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/images/services/covers/kdx-dunjia-cover.jpg b/assets/images/services/covers/kdx-dunjia-cover.jpg
new file mode 100644
index 0000000..3ada62d
Binary files /dev/null and b/assets/images/services/covers/kdx-dunjia-cover.jpg differ
diff --git a/assets/images/services/covers/kdx-dunjia-plus-cover.jpg b/assets/images/services/covers/kdx-dunjia-plus-cover.jpg
new file mode 100644
index 0000000..e79c7e9
Binary files /dev/null and b/assets/images/services/covers/kdx-dunjia-plus-cover.jpg differ
diff --git a/assets/images/services/covers/kdx-jinjia-pro-cover.jpg b/assets/images/services/covers/kdx-jinjia-pro-cover.jpg
new file mode 100644
index 0000000..57441e8
Binary files /dev/null and b/assets/images/services/covers/kdx-jinjia-pro-cover.jpg differ
diff --git a/assets/images/services/covers/kdx-kaijia-cover.jpg b/assets/images/services/covers/kdx-kaijia-cover.jpg
new file mode 100644
index 0000000..5332875
Binary files /dev/null and b/assets/images/services/covers/kdx-kaijia-cover.jpg differ
diff --git a/assets/images/services/covers/kdx-kaijia-plus-cover.jpg b/assets/images/services/covers/kdx-kaijia-plus-cover.jpg
new file mode 100644
index 0000000..c892c12
Binary files /dev/null and b/assets/images/services/covers/kdx-kaijia-plus-cover.jpg differ
diff --git a/assets/images/services/kdx-dunjia-plus.jpg b/assets/images/services/kdx-dunjia-plus.jpg
new file mode 100644
index 0000000..133809f
Binary files /dev/null and b/assets/images/services/kdx-dunjia-plus.jpg differ
diff --git a/assets/images/services/kdx-dunjia.jpg b/assets/images/services/kdx-dunjia.jpg
new file mode 100644
index 0000000..b5d5fdf
Binary files /dev/null and b/assets/images/services/kdx-dunjia.jpg differ
diff --git a/assets/images/services/kdx-jinjia-pro.jpg b/assets/images/services/kdx-jinjia-pro.jpg
new file mode 100644
index 0000000..4b92fb1
Binary files /dev/null and b/assets/images/services/kdx-jinjia-pro.jpg differ
diff --git a/assets/images/services/kdx-kaijia-plus.jpg b/assets/images/services/kdx-kaijia-plus.jpg
new file mode 100644
index 0000000..cd56530
Binary files /dev/null and b/assets/images/services/kdx-kaijia-plus.jpg differ
diff --git a/assets/images/services/kdx-kaijia.jpg b/assets/images/services/kdx-kaijia.jpg
new file mode 100644
index 0000000..0a152e4
Binary files /dev/null and b/assets/images/services/kdx-kaijia.jpg differ
diff --git a/assets/images/store/authorization.jpg b/assets/images/store/authorization.jpg
index cfa3e55..d7b4f05 100644
Binary files a/assets/images/store/authorization.jpg and b/assets/images/store/authorization.jpg differ
diff --git a/assets/images/store/award.jpg b/assets/images/store/award.jpg
index 71c8fb8..e9dd622 100644
Binary files a/assets/images/store/award.jpg and b/assets/images/store/award.jpg differ
diff --git a/assets/images/store/brand-event.jpg b/assets/images/store/brand-event.jpg
index 9771638..49db5c8 100644
Binary files a/assets/images/store/brand-event.jpg and b/assets/images/store/brand-event.jpg differ
diff --git a/assets/images/store/kdx-logo.jpg b/assets/images/store/kdx-logo.jpg
index 8d850ab..ba320a1 100644
Binary files a/assets/images/store/kdx-logo.jpg and b/assets/images/store/kdx-logo.jpg differ
diff --git a/assets/images/store/showroom-consultation.jpg b/assets/images/store/showroom-consultation.jpg
index 7c2c4af..bba999c 100644
Binary files a/assets/images/store/showroom-consultation.jpg and b/assets/images/store/showroom-consultation.jpg differ
diff --git a/assets/images/store/showroom-main.jpg b/assets/images/store/showroom-main.jpg
index 3b7b21e..1834d9d 100644
Binary files a/assets/images/store/showroom-main.jpg and b/assets/images/store/showroom-main.jpg differ
diff --git a/assets/images/store/storefront.jpg b/assets/images/store/storefront.jpg
index bc8b725..e3331cc 100644
Binary files a/assets/images/store/storefront.jpg and b/assets/images/store/storefront.jpg differ
diff --git a/assets/images/trust-workshop-bg.jpg b/assets/images/trust-workshop-bg.jpg
new file mode 100644
index 0000000..f099579
Binary files /dev/null and b/assets/images/trust-workshop-bg.jpg differ
diff --git a/assets/js/theme.js b/assets/js/theme.js
index c44949a..d85424d 100644
--- a/assets/js/theme.js
+++ b/assets/js/theme.js
@@ -25,6 +25,217 @@
});
}
+ function initCarousels() {
+ var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+
+ document.querySelectorAll('[data-carousel]').forEach(function (carousel) {
+ var viewport = carousel.querySelector('.b2b-carousel-viewport');
+ var track = carousel.querySelector('.b2b-carousel-track');
+ var slides = Array.prototype.slice.call(carousel.querySelectorAll('.b2b-carousel-slide'));
+ var previousButton = carousel.querySelector('.b2b-carousel-prev');
+ var nextButton = carousel.querySelector('.b2b-carousel-next');
+ var dotsContainer = carousel.querySelector('.b2b-carousel-dots');
+ var autoplayDelay = parseInt(carousel.getAttribute('data-autoplay'), 10) || 9000;
+ var pageLabel = carousel.getAttribute('data-page-label') || 'Page %d';
+ var currentPage = 0;
+ var pageCount = 1;
+ var autoplayTimer = null;
+ var scrollTimer = null;
+ var resizeTimer = null;
+ var hoverPaused = false;
+ var focusPaused = false;
+ var pointerPaused = false;
+
+ if (!viewport || !track || !slides.length || !previousButton || !nextButton || !dotsContainer) {
+ return;
+ }
+
+ function getItemsPerPage() {
+ var value = parseInt(window.getComputedStyle(carousel).getPropertyValue('--carousel-items'), 10);
+ return Math.max(1, value || 1);
+ }
+
+ function updateDots() {
+ dotsContainer.querySelectorAll('.b2b-carousel-dot').forEach(function (dot, index) {
+ var active = index === currentPage;
+ dot.classList.toggle('is-active', active);
+ dot.setAttribute('aria-current', active ? 'true' : 'false');
+ });
+ }
+
+ function stopAutoplay() {
+ if (!autoplayTimer) return;
+ window.clearInterval(autoplayTimer);
+ autoplayTimer = null;
+ }
+
+ function goToPage(page, smooth) {
+ if (!pageCount) return;
+ currentPage = (page + pageCount) % pageCount;
+ var targetIndex = Math.min(currentPage * getItemsPerPage(), slides.length - 1);
+ var maximumScroll = Math.max(0, viewport.scrollWidth - viewport.clientWidth);
+ viewport.scrollTo({
+ left: Math.min(slides[targetIndex].offsetLeft, maximumScroll),
+ behavior: smooth && !reducedMotion ? 'smooth' : 'auto'
+ });
+ updateDots();
+ }
+
+ function startAutoplay() {
+ stopAutoplay();
+ if (
+ reducedMotion ||
+ hoverPaused ||
+ focusPaused ||
+ pointerPaused ||
+ pageCount < 2 ||
+ document.hidden
+ ) {
+ return;
+ }
+ autoplayTimer = window.setInterval(function () {
+ goToPage(currentPage + 1, true);
+ }, Math.max(autoplayDelay, 7000));
+ }
+
+ function buildDots() {
+ var itemsPerPage = getItemsPerPage();
+ var nextPageCount = Math.ceil(slides.length / itemsPerPage);
+ var fragment = document.createDocumentFragment();
+
+ pageCount = Math.max(1, nextPageCount);
+ currentPage = Math.min(currentPage, pageCount - 1);
+ dotsContainer.textContent = '';
+
+ for (var index = 0; index < pageCount; index += 1) {
+ var dot = document.createElement('button');
+ dot.type = 'button';
+ dot.className = 'b2b-carousel-dot';
+ dot.setAttribute('aria-label', pageLabel.replace('%d', index + 1));
+ dot.dataset.page = index;
+ dot.addEventListener('click', function () {
+ goToPage(parseInt(this.dataset.page, 10), true);
+ startAutoplay();
+ });
+ fragment.appendChild(dot);
+ }
+
+ dotsContainer.appendChild(fragment);
+ carousel.classList.toggle('has-single-page', pageCount < 2);
+ updateDots();
+ goToPage(currentPage, false);
+ startAutoplay();
+ }
+
+ previousButton.addEventListener('click', function () {
+ goToPage(currentPage - 1, true);
+ startAutoplay();
+ });
+
+ nextButton.addEventListener('click', function () {
+ goToPage(currentPage + 1, true);
+ startAutoplay();
+ });
+
+ viewport.addEventListener(
+ 'scroll',
+ function () {
+ window.clearTimeout(scrollTimer);
+ scrollTimer = window.setTimeout(function () {
+ var itemsPerPage = getItemsPerPage();
+ var maximumScroll = Math.max(0, viewport.scrollWidth - viewport.clientWidth);
+ var closestPage = 0;
+ var closestDistance = Number.POSITIVE_INFINITY;
+
+ for (var page = 0; page < pageCount; page += 1) {
+ var targetIndex = Math.min(page * itemsPerPage, slides.length - 1);
+ var targetPosition = Math.min(slides[targetIndex].offsetLeft, maximumScroll);
+ var distance = Math.abs(viewport.scrollLeft - targetPosition);
+ if (distance < closestDistance) {
+ closestDistance = distance;
+ closestPage = page;
+ }
+ }
+
+ currentPage = closestPage;
+ updateDots();
+ }, 100);
+ },
+ { passive: true }
+ );
+
+ carousel.addEventListener('mouseenter', function () {
+ hoverPaused = true;
+ stopAutoplay();
+ });
+
+ carousel.addEventListener('mouseleave', function () {
+ hoverPaused = false;
+ startAutoplay();
+ });
+
+ carousel.addEventListener('focusin', function () {
+ focusPaused = true;
+ stopAutoplay();
+ });
+
+ carousel.addEventListener('focusout', function () {
+ window.setTimeout(function () {
+ if (carousel.contains(document.activeElement)) return;
+ focusPaused = false;
+ startAutoplay();
+ }, 0);
+ });
+
+ viewport.addEventListener(
+ 'pointerdown',
+ function () {
+ pointerPaused = true;
+ stopAutoplay();
+ },
+ { passive: true }
+ );
+
+ viewport.addEventListener(
+ 'pointerup',
+ function () {
+ pointerPaused = false;
+ startAutoplay();
+ },
+ { passive: true }
+ );
+
+ viewport.addEventListener(
+ 'pointercancel',
+ function () {
+ pointerPaused = false;
+ startAutoplay();
+ },
+ { passive: true }
+ );
+
+ window.addEventListener(
+ 'resize',
+ function () {
+ window.clearTimeout(resizeTimer);
+ resizeTimer = window.setTimeout(buildDots, 160);
+ },
+ { passive: true }
+ );
+
+ document.addEventListener('visibilitychange', function () {
+ if (document.hidden) {
+ stopAutoplay();
+ } else {
+ startAutoplay();
+ }
+ });
+
+ carousel.classList.add('is-ready');
+ buildDots();
+ });
+ }
+
function initRevealMotion() {
var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var compactMotion = window.matchMedia('(max-width: 768px)').matches;
@@ -53,11 +264,12 @@
prepareGroup('.trust-strip .row', '.trust-metric', 60);
prepareGroup('.capability-grid', '.capability-card', 60);
prepareGroup('.case-grid', '.case-card', 60);
+ prepareGroup('.news-grid', '.news-card', 60);
prepareGroup('.factory-gallery', 'figure', 60);
prepareGroup('.credentials-grid', '.credential-card', 60);
prepareGroup('.document-grid', 'article', 60);
prepareGroup('.contact-detail-grid', '.contact-detail-card', 60);
- prepareGroup('.service-content, .case-content', ':scope > *', 40);
+ prepareGroup('.service-content, .case-content, .news-single-content', ':scope > *', 40);
document.querySelectorAll(
[
@@ -70,6 +282,11 @@
'.contact-store-media',
'.contact-map-heading',
'.contact-map-panel',
+ '.news-page-header',
+ '.news-single-header',
+ '.news-single-image',
+ '.news-post-navigation',
+ '.news-single-cta',
'.cta-section .container',
'.about-cta .container',
'.page-header'
@@ -111,6 +328,7 @@
function initTheme() {
initStickyHeader();
initNavigation();
+ initCarousels();
initRevealMotion();
}
diff --git a/footer.php b/footer.php
index 0d02c86..cbc534a 100644
--- a/footer.php
+++ b/footer.php
@@ -9,14 +9,21 @@ $fragrance_social_links = array(
'youtube_url' => __( 'YouTube', 'fragrance-trade' ), 'linkedin_url' => __( 'LinkedIn', 'fragrance-trade' ),
'instagram_social_url' => __( 'Instagram', 'fragrance-trade' ),
);
-$fragrance_email = fragrance_trade_inquiry_email();
$fragrance_whatsapp = fragrance_trade_whatsapp_number();
+$fragrance_store_name = fragrance_trade_get_mod( 'b2b_hero_title' );
+$fragrance_store_phone = fragrance_trade_get_mod( 'store_phone' );
+$fragrance_phone_href = preg_replace( '/[^0-9+]/', '', $fragrance_store_phone );
+$fragrance_store_address = fragrance_trade_get_mod( 'store_address' );
+$fragrance_store_hours = fragrance_trade_get_mod( 'store_hours' );
+$fragrance_contact_name = fragrance_trade_get_mod( 'store_contact_person' );
+$fragrance_icp_number = fragrance_trade_get_mod( 'icp_number', '' );
+$fragrance_icp_url = fragrance_trade_get_mod( 'icp_url', '' );
?>
diff --git a/functions.php b/functions.php
index 30ff5f2..70f550c 100644
--- a/functions.php
+++ b/functions.php
@@ -14,10 +14,11 @@ $fragrance_trade_modules = array(
'setup.php',
'helpers.php',
'cpt.php',
+ 'service-seeds.php',
+ 'case-seeds.php',
'customizer.php',
);
foreach ( $fragrance_trade_modules as $fragrance_trade_module ) {
require_once get_template_directory() . '/inc/' . $fragrance_trade_module;
}
-
diff --git a/home.php b/home.php
new file mode 100644
index 0000000..46a6357
--- /dev/null
+++ b/home.php
@@ -0,0 +1,61 @@
+
+
+
+ array(
+ array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
+ array( 'label' => $page_title, 'url' => null ),
+ ),
+ )
+ );
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inc/case-seeds.php b/inc/case-seeds.php
new file mode 100644
index 0000000..021893d
--- /dev/null
+++ b/inc/case-seeds.php
@@ -0,0 +1,520 @@
+ array(
+ 'title' => __( '福特蒙迪欧|亚历山大银改色膜', 'fragrance-trade' ),
+ 'slug' => 'ford-mondeo-alexander-silver',
+ 'vehicle' => __( '福特蒙迪欧', 'fragrance-trade' ),
+ 'project' => __( '整车改色膜', 'fragrance-trade' ),
+ 'color' => __( '亚历山大银', 'fragrance-trade' ),
+ 'direction' => __( '哑光金属银、黑银对比', 'fragrance-trade' ),
+ 'excerpt' => __( '福特蒙迪欧亚历山大银整车改色,哑光金属银质感搭配黑色车顶与饰件,呈现克制、利落的黑银对比效果。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为福特蒙迪欧,车主选择亚历山大银整车改色。银灰色膜面带有细腻的哑光金属质感,与黑色车顶、后视镜、窗框及前后灯组形成清晰的黑银对比。', 'fragrance-trade' ),
+ 'effect' => __( '亚历山大银弱化了高亮反射,让蒙迪欧的车身折线在室内灯光和自然光下都更容易被看见。大面积银色保持干净、克制,黑色车顶与饰件则进一步压低视觉重心,让整车轮廓显得更修长。', 'fragrance-trade' ),
+ 'details' => __( '施工重点检查了隐藏式门把手、后视镜底座、尾灯边缘、尾翼和车身折角等位置。完成后从正面、侧面和车尾分别复查膜面平整度、拼接位置与边角收口,确保整体颜色连续、车身线条清晰。', 'fragrance-trade' ),
+ 'image_count' => 9,
+ 'featured_index' => 0,
+ ),
+ 'porsche-718-liquid-metal-silver' => array(
+ 'title' => __( '保时捷 718|液态金属银改色膜', 'fragrance-trade' ),
+ 'slug' => 'porsche-718-liquid-metal-silver',
+ 'vehicle' => __( '保时捷 718', 'fragrance-trade' ),
+ 'project' => __( '整车改色膜', 'fragrance-trade' ),
+ 'color' => __( '液态金属银', 'fragrance-trade' ),
+ 'direction' => __( '亮面金属银灰、红色软顶对比', 'fragrance-trade' ),
+ 'excerpt' => __( '保时捷 718 液态金属银整车改色,以亮面金属银灰强化跑车曲面,并保留红色软顶形成鲜明层次。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为保时捷 718,选择液态金属银整车改色。银灰色膜面带有明亮、流动的金属反射,与红色软顶和黑色灯组形成鲜明但克制的颜色层次。', 'fragrance-trade' ),
+ 'effect' => __( '液态金属银会随着光线角度呈现由浅银到深灰的变化,能够突出 718 前翼子板、车门和后轮拱的连续曲面。红色软顶保留原有视觉焦点,让整车兼具精致感与运动感。', 'fragrance-trade' ),
+ 'details' => __( '施工重点检查前后保险杠曲面、进气口边缘、门把手、后视镜底座、尾翼与软顶交界等位置。交付前分别在正面、侧面和车尾复查膜面连续性与边角收口。', 'fragrance-trade' ),
+ 'image_count' => 10,
+ 'featured_index' => 0,
+ ),
+ 'tesla-model-3-highland-alexander-silver' => array(
+ 'title' => __( '特斯拉焕新版 Model 3|亚历山大银改色膜', 'fragrance-trade' ),
+ 'slug' => 'tesla-model-3-highland-alexander-silver',
+ 'vehicle' => __( '特斯拉焕新版 Model 3', 'fragrance-trade' ),
+ 'project' => __( '整车改色膜', 'fragrance-trade' ),
+ 'color' => __( '亚历山大银', 'fragrance-trade' ),
+ 'direction' => __( '哑光金属银、黑色玻璃与轮毂对比', 'fragrance-trade' ),
+ 'excerpt' => __( '特斯拉焕新版 Model 3 亚历山大银整车改色,以细腻哑光金属质感呈现更简洁的黑银对比。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为特斯拉焕新版 Model 3,选择亚历山大银整车改色。低反光的银色膜面与黑色玻璃、门把手、饰件和轮毂组合,延续车辆简洁、科技感明确的外观语言。', 'fragrance-trade' ),
+ 'effect' => __( '亚历山大银降低了车身大面积高光反射,让焕新版 Model 3 的前脸、肩线与溜背轮廓显得更干净。不同光线下,膜面会在冷银与浅灰之间变化,整体观感克制而利落。', 'fragrance-trade' ),
+ 'details' => __( '施工重点覆盖无框车门边缘、隐藏式门把手、后视镜底座、前后灯组与保险杠曲面。完成后检查各覆盖面颜色一致性,并确认门把手和车门开合区域收口平整。', 'fragrance-trade' ),
+ 'image_count' => 9,
+ 'featured_index' => 0,
+ ),
+ 'byd-han-matte-blue-gold-floating-roof' => array(
+ 'title' => __( '比亚迪汉|远峰蓝魅金哑面+悬浮顶', 'fragrance-trade' ),
+ 'slug' => 'byd-han-matte-blue-gold-floating-roof',
+ 'vehicle' => __( '比亚迪汉', 'fragrance-trade' ),
+ 'project' => __( '整车哑面改色膜+悬浮顶', 'fragrance-trade' ),
+ 'color' => __( '远峰蓝魅金(哑面)', 'fragrance-trade' ),
+ 'direction' => __( '低饱和蓝金变色、哑面质感、黑色悬浮顶', 'fragrance-trade' ),
+ 'excerpt' => __( '比亚迪汉远峰蓝魅金哑面整车改色,并搭配黑色悬浮顶,在不同光线下呈现低饱和蓝金变化。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为比亚迪汉,选择远峰蓝魅金哑面改色,并搭配黑色悬浮顶。膜面在银灰基调中带有轻微蓝金变化,车顶与窗框的黑色区域则让车身形成清晰的上下分层。', 'fragrance-trade' ),
+ 'effect' => __( '哑面效果降低了直接反射,远峰蓝魅金在不同角度和灯光下呈现偏冷银、浅蓝与柔和金色变化。黑色悬浮顶进一步拉长侧面视觉比例,让比亚迪汉的车身姿态更低、更完整。', 'fragrance-trade' ),
+ 'details' => __( '施工重点处理悬浮顶边界、A/B/C 柱、后视镜、门把手、尾灯和车身腰线等位置。交付前复查黑色车顶与车身改色膜的边界是否连续,并确认哑面膜无明显压痕或高光点。', 'fragrance-trade' ),
+ 'image_count' => 8,
+ 'featured_index' => 4,
+ ),
+ 'chery-arrizo-alexander-silver' => array(
+ 'title' => __( '奇瑞艾瑞泽|亚历山大银改色膜', 'fragrance-trade' ),
+ 'slug' => 'chery-arrizo-alexander-silver',
+ 'vehicle' => __( '奇瑞艾瑞泽', 'fragrance-trade' ),
+ 'project' => __( '整车改色膜', 'fragrance-trade' ),
+ 'color' => __( '亚历山大银', 'fragrance-trade' ),
+ 'direction' => __( '哑光金属银、黑色格栅与灯组对比', 'fragrance-trade' ),
+ 'excerpt' => __( '奇瑞艾瑞泽亚历山大银整车改色,以细腻哑光金属银突出车身折线与前脸黑色细节。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为奇瑞艾瑞泽,选择亚历山大银整车改色。银色哑光膜面弱化反射,同时保留金属颗粒感,与黑色进气格栅、灯组和车窗区域形成简洁对比。', 'fragrance-trade' ),
+ 'effect' => __( '亚历山大银让艾瑞泽的前脸折线、车门腰线和车尾层次更容易被看见。整体颜色接近低饱和银灰,不会掩盖原有造型,适合希望外观焕新但仍保持稳重观感的方案。', 'fragrance-trade' ),
+ 'details' => __( '施工重点检查前脸饰条、后视镜、门把手、车顶鲨鱼鳍、尾灯边缘与保险杠转角。交付前从不同光线方向复查膜面色差、平整度和细节收口。', 'fragrance-trade' ),
+ 'image_count' => 9,
+ 'featured_index' => 0,
+ ),
+ 'changan-uni-v-gt-silver' => array(
+ 'title' => __( '长安 UNI-V|GT 银改色膜', 'fragrance-trade' ),
+ 'slug' => 'changan-uni-v-gt-silver',
+ 'vehicle' => __( '长安 UNI-V', 'fragrance-trade' ),
+ 'project' => __( '整车改色膜', 'fragrance-trade' ),
+ 'color' => __( 'GT 银', 'fragrance-trade' ),
+ 'direction' => __( '亮面金属银、黑色车顶与运动套件对比', 'fragrance-trade' ),
+ 'excerpt' => __( '长安 UNI-V GT 银整车改色,利用亮面金属银与黑色车顶、尾翼和运动饰件强化低趴姿态。', 'fragrance-trade' ),
+ 'intro' => __( '本次施工车型为长安 UNI-V,选择 GT 银整车改色。亮面银色膜面能够清晰表现车身折线,与黑色车顶、后视镜、窗框和运动套件形成更直接的银黑对比。', 'fragrance-trade' ),
+ 'effect' => __( 'GT 银在室内灯光下呈现干净的金属高光,能够强化 UNI-V 的溜背线条、宽体感和低趴姿态。黑色车顶与尾翼保留原有运动气质,使整体效果更利落。', 'fragrance-trade' ),
+ 'details' => __( '施工重点处理无边框车门区域、隐藏式门把手、后视镜底座、前后保险杠折角、尾灯与升降尾翼周边。车辆交付前同时检查外观覆盖面与开合部件的边缘收口。', 'fragrance-trade' ),
+ 'image_count' => 12,
+ 'featured_index' => 3,
+ ),
+ );
+}
+
+/** Find a case previously created by this importer. */
+function fragrance_trade_find_seeded_case( $seed_key ) {
+ $ids = get_posts(
+ array(
+ 'post_type' => 'case',
+ 'post_status' => fragrance_trade_seed_post_statuses(),
+ 'posts_per_page' => 1,
+ 'fields' => 'ids',
+ 'meta_key' => '_fragrance_case_seed_key',
+ 'meta_value' => $seed_key,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $ids ? (int) $ids[0] : 0;
+}
+
+/** Find a case with the conventional seed slug without changing it. */
+function fragrance_trade_find_case_seed_slug( $slug ) {
+ $posts = get_posts(
+ array(
+ 'post_type' => 'case',
+ 'post_status' => fragrance_trade_seed_post_statuses(),
+ 'name' => $slug,
+ 'posts_per_page' => 1,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $posts ? (int) $posts[0]->ID : 0;
+}
+
+/** Find one media item already copied for a seed image. */
+function fragrance_trade_find_case_seed_attachment( $image_key ) {
+ $ids = get_posts(
+ array(
+ 'post_type' => 'attachment',
+ 'post_status' => 'inherit',
+ 'posts_per_page' => 1,
+ 'fields' => 'ids',
+ 'meta_key' => '_fragrance_case_seed_image',
+ 'meta_value' => $image_key,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $ids ? (int) $ids[0] : 0;
+}
+
+/**
+ * Copy one bundled seed image into the WordPress media library.
+ *
+ * @param int $case_id Parent case post ID.
+ * @param string $seed_key Stable case seed key.
+ * @param array $seed Seed record.
+ * @param int $index Zero-based image index.
+ * @return int|WP_Error
+ */
+function fragrance_trade_import_case_seed_image( $case_id, $seed_key, $seed, $index ) {
+ $image_key = $seed_key . ':' . $index;
+ $existing = fragrance_trade_find_case_seed_attachment( $image_key );
+ if ( $existing ) {
+ if ( (int) wp_get_post_parent_id( $existing ) !== (int) $case_id ) {
+ wp_update_post(
+ array(
+ 'ID' => $existing,
+ 'post_parent' => $case_id,
+ )
+ );
+ }
+ return $existing;
+ }
+
+ $number = $index + 1;
+ $source_file = sprintf(
+ '%1$s/assets/images/cases/%2$s/%3$02d.jpg',
+ get_template_directory(),
+ $seed['slug'],
+ $number
+ );
+
+ if ( ! is_readable( $source_file ) ) {
+ return new WP_Error(
+ 'fragrance_case_seed_image_missing',
+ sprintf(
+ /* translators: 1: case title, 2: image number. */
+ __( '案例“%1$s”的第 %2$d 张初始化图片不存在。', 'fragrance-trade' ),
+ $seed['title'],
+ $number
+ )
+ );
+ }
+
+ $image_bytes = file_get_contents( $source_file );
+ if ( false === $image_bytes ) {
+ return new WP_Error(
+ 'fragrance_case_seed_image_unreadable',
+ sprintf(
+ /* translators: 1: case title, 2: image number. */
+ __( '无法读取案例“%1$s”的第 %2$d 张初始化图片。', 'fragrance-trade' ),
+ $seed['title'],
+ $number
+ )
+ );
+ }
+
+ $filename = sprintf( '%1$s-%2$02d.jpg', $seed['slug'], $number );
+ $upload = wp_upload_bits( $filename, null, $image_bytes );
+ unset( $image_bytes );
+
+ if ( ! empty( $upload['error'] ) ) {
+ return new WP_Error( 'fragrance_case_seed_upload_failed', $upload['error'] );
+ }
+
+ $attachment_id = wp_insert_attachment(
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_title' => sprintf(
+ /* translators: 1: vehicle name, 2: color name, 3: image number. */
+ __( '%1$s %2$s施工实拍图 %3$d', 'fragrance-trade' ),
+ $seed['vehicle'],
+ $seed['color'],
+ $number
+ ),
+ 'post_status' => 'inherit',
+ ),
+ $upload['file'],
+ $case_id,
+ true
+ );
+
+ if ( is_wp_error( $attachment_id ) ) {
+ wp_delete_file( $upload['file'] );
+ return $attachment_id;
+ }
+
+ require_once ABSPATH . 'wp-admin/includes/image.php';
+ $metadata = wp_generate_attachment_metadata( $attachment_id, $upload['file'] );
+ if ( $metadata ) {
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ }
+
+ update_post_meta( $attachment_id, '_fragrance_case_seed_image', $image_key );
+ update_post_meta(
+ $attachment_id,
+ '_wp_attachment_image_alt',
+ sprintf(
+ /* translators: 1: vehicle name, 2: color name, 3: image number. */
+ __( '%1$s%2$s施工实拍图 %3$d', 'fragrance-trade' ),
+ $seed['vehicle'],
+ $seed['color'],
+ $number
+ )
+ );
+
+ return (int) $attachment_id;
+}
+
+/** Build the block-editor content for an imported case. */
+function fragrance_trade_build_case_seed_content( $seed, $attachment_ids ) {
+ $list = sprintf(
+ '
- %1$s%2$s
- %3$s%4$s
- %5$s%6$s
- %7$s%8$s
',
+ esc_html__( '车型:', 'fragrance-trade' ),
+ esc_html( $seed['vehicle'] ),
+ esc_html__( '施工项目:', 'fragrance-trade' ),
+ esc_html( $seed['project'] ),
+ esc_html__( '颜色:', 'fragrance-trade' ),
+ esc_html( $seed['color'] ),
+ esc_html__( '外观方向:', 'fragrance-trade' ),
+ esc_html( $seed['direction'] )
+ );
+
+ $gallery = '';
+ foreach ( $attachment_ids as $attachment_id ) {
+ $full_url = wp_get_attachment_url( $attachment_id );
+ $image = wp_get_attachment_image( $attachment_id, 'large' );
+ if ( ! $full_url || ! $image ) {
+ continue;
+ }
+ $gallery .= sprintf(
+ '
%3$s',
+ $attachment_id,
+ esc_url( $full_url ),
+ $image
+ );
+ }
+
+ return sprintf(
+ '
%1$s
' .
+ '
%2$s
' .
+ '%3$s' .
+ '
%4$s
' .
+ '
%5$s
' .
+ '
%6$s' .
+ '
%7$s
' .
+ '
%8$s
' .
+ '
%9$s
',
+ esc_html( $seed['intro'] ),
+ esc_html__( '项目概览', 'fragrance-trade' ),
+ $list,
+ esc_html__( '整体效果', 'fragrance-trade' ),
+ esc_html( $seed['effect'] ),
+ $gallery,
+ esc_html__( '细节与收口', 'fragrance-trade' ),
+ esc_html( $seed['details'] ),
+ esc_html__( '提示:实际颜色会受到环境光线、屏幕显示和拍摄设备影响,到店选色请以实物色卡与门店样板为准。', 'fragrance-trade' )
+ );
+}
+
+/**
+ * Import every bundled case without duplicating or overwriting existing work.
+ *
+ * @return array{created:int,existing:int,errors:string[]}
+ */
+function fragrance_trade_import_case_seeds() {
+ $result = array(
+ 'created' => 0,
+ 'existing' => 0,
+ 'errors' => array(),
+ );
+
+ $term_name = __( '改色膜', 'fragrance-trade' );
+ $term = term_exists( $term_name, 'case_type' );
+ if ( ! $term ) {
+ $term = wp_insert_term( $term_name, 'case_type' );
+ }
+ if ( is_wp_error( $term ) ) {
+ $result['errors'][] = $term->get_error_message();
+ return $result;
+ }
+ $term_id = (int) ( is_array( $term ) ? $term['term_id'] : $term );
+
+ foreach ( fragrance_trade_case_seeds() as $seed_key => $seed ) {
+ $case_id = fragrance_trade_find_seeded_case( $seed_key );
+ if ( $case_id && 'publish' === get_post_status( $case_id ) ) {
+ ++$result['existing'];
+ continue;
+ }
+ if (
+ $case_id
+ && (
+ 'draft' !== get_post_status( $case_id )
+ || 'importing' !== get_post_meta( $case_id, '_fragrance_case_seed_state', true )
+ )
+ ) {
+ ++$result['existing'];
+ continue;
+ }
+
+ if ( ! $case_id ) {
+ $slug_match = fragrance_trade_find_case_seed_slug( $seed['slug'] );
+ if ( $slug_match ) {
+ ++$result['existing'];
+ continue;
+ }
+
+ $case_id = wp_insert_post(
+ array(
+ 'post_type' => 'case',
+ 'post_name' => $seed['slug'],
+ 'post_title' => $seed['title'],
+ 'post_excerpt' => $seed['excerpt'],
+ 'post_status' => 'draft',
+ ),
+ true
+ );
+ if ( is_wp_error( $case_id ) ) {
+ $result['errors'][] = sprintf(
+ /* translators: 1: case title, 2: error message. */
+ __( '无法创建案例“%1$s”:%2$s', 'fragrance-trade' ),
+ $seed['title'],
+ $case_id->get_error_message()
+ );
+ continue;
+ }
+ update_post_meta( $case_id, '_fragrance_case_seed_key', $seed_key );
+ update_post_meta( $case_id, '_fragrance_case_seed_state', 'importing' );
+ }
+
+ $attachment_ids = array();
+ $case_errors = array();
+ for ( $index = 0; $index < $seed['image_count']; ++$index ) {
+ $attachment_id = fragrance_trade_import_case_seed_image( $case_id, $seed_key, $seed, $index );
+ if ( is_wp_error( $attachment_id ) ) {
+ $case_errors[] = $attachment_id->get_error_message();
+ continue;
+ }
+ $attachment_ids[] = $attachment_id;
+ }
+
+ if ( $case_errors || count( $attachment_ids ) !== (int) $seed['image_count'] ) {
+ $result['errors'] = array_merge( $result['errors'], $case_errors );
+ continue;
+ }
+
+ $terms_set = wp_set_object_terms( $case_id, array( $term_id ), 'case_type', false );
+ if ( is_wp_error( $terms_set ) ) {
+ $result['errors'][] = $terms_set->get_error_message();
+ continue;
+ }
+ set_post_thumbnail( $case_id, $attachment_ids[ $seed['featured_index'] ] );
+
+ $updated = wp_update_post(
+ array(
+ 'ID' => $case_id,
+ 'post_title' => $seed['title'],
+ 'post_name' => $seed['slug'],
+ 'post_excerpt' => $seed['excerpt'],
+ 'post_content' => fragrance_trade_build_case_seed_content( $seed, $attachment_ids ),
+ 'post_status' => 'publish',
+ ),
+ true
+ );
+
+ if ( is_wp_error( $updated ) ) {
+ $result['errors'][] = sprintf(
+ /* translators: 1: case title, 2: error message. */
+ __( '无法发布案例“%1$s”:%2$s', 'fragrance-trade' ),
+ $seed['title'],
+ $updated->get_error_message()
+ );
+ continue;
+ }
+
+ delete_post_meta( $case_id, '_fragrance_case_seed_state' );
+ ++$result['created'];
+ }
+
+ $result['errors'] = array_values( array_unique( $result['errors'] ) );
+ return $result;
+}
+
+/** Add the bundled-content importer below Appearance for administrators. */
+function fragrance_trade_register_case_seed_page() {
+ add_theme_page(
+ __( '初始化内容', 'fragrance-trade' ),
+ __( '初始化内容', 'fragrance-trade' ),
+ 'edit_theme_options',
+ 'fragrance-case-import',
+ 'fragrance_trade_render_case_seed_page'
+ );
+}
+add_action( 'admin_menu', 'fragrance_trade_register_case_seed_page' );
+
+/** Render the one-click service and case importer. */
+function fragrance_trade_render_case_seed_page() {
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
+ return;
+ }
+
+ $transient_key = 'fragrance_trade_case_import_result_' . get_current_user_id();
+ $result = get_transient( $transient_key );
+ if ( false !== $result ) {
+ delete_transient( $transient_key );
+ }
+ ?>
+
+ $services,
+ 'cases' => $cases,
+ 'errors' => array_values( array_unique( array_merge( $services['errors'], $cases['errors'] ) ) ),
+ );
+ set_transient(
+ 'fragrance_trade_case_import_result_' . get_current_user_id(),
+ $result,
+ 5 * MINUTE_IN_SECONDS
+ );
+
+ wp_safe_redirect( admin_url( 'themes.php?page=fragrance-case-import' ) );
+ exit;
+}
+add_action( 'admin_post_fragrance_trade_import_case_seeds', 'fragrance_trade_handle_case_seed_import' );
diff --git a/inc/cpt.php b/inc/cpt.php
index 754cae7..62120ea 100644
--- a/inc/cpt.php
+++ b/inc/cpt.php
@@ -345,9 +345,63 @@ function fragrance_trade_create_required_pages( &$errors ) {
return $result;
}
+/**
+ * Preserve an existing posts page or create the conventional news page.
+ *
+ * @param string[] $errors Setup errors collected by the caller.
+ * @return array{id:int,changed:bool}
+ */
+function fragrance_trade_ensure_news_page( &$errors ) {
+ $result = array( 'id' => 0, 'changed' => false );
+ $current_page_id = absint( get_option( 'page_for_posts', 0 ) );
+ $current_page = $current_page_id ? get_post( $current_page_id ) : null;
+
+ if ( $current_page && 'page' === $current_page->post_type ) {
+ $result['id'] = $current_page_id;
+ return $result;
+ }
+
+ $news_page = fragrance_trade_find_required_page( 'news' );
+ if ( ! $news_page ) {
+ $news_page_id = wp_insert_post(
+ array(
+ 'post_type' => 'page',
+ 'post_name' => 'news',
+ 'post_title' => __( '新闻资讯', 'fragrance-trade' ),
+ 'post_status' => 'publish',
+ ),
+ true
+ );
+ if ( is_wp_error( $news_page_id ) ) {
+ $errors[] = sprintf(
+ /* translators: %s: error message. */
+ __( '无法创建新闻资讯页面:%s', 'fragrance-trade' ),
+ $news_page_id->get_error_message()
+ );
+ return $result;
+ }
+
+ $news_page = get_post( $news_page_id );
+ $result['changed'] = true;
+ }
+
+ $news_page_id = (int) $news_page->ID;
+ if ( $current_page_id !== $news_page_id ) {
+ update_option( 'page_for_posts', $news_page_id );
+ if ( $news_page_id !== absint( get_option( 'page_for_posts', 0 ) ) ) {
+ $errors[] = __( '无法将新闻资讯页面设置为 WordPress 文章页。', 'fragrance-trade' );
+ return $result;
+ }
+ $result['changed'] = true;
+ }
+
+ $result['id'] = $news_page_id;
+ return $result;
+}
+
/** Versioned and retryable site setup. */
function fragrance_trade_maybe_setup_site() {
- $target_version = 3;
+ $target_version = 4;
if ( (int) get_option( 'fragrance_trade_schema_version', 0 ) >= $target_version ) {
return;
}
@@ -356,12 +410,13 @@ function fragrance_trade_maybe_setup_site() {
$seed_changed = fragrance_trade_create_seed_services( $errors );
$copy_changed = fragrance_trade_migrate_seed_service_copy( $errors );
$page_result = fragrance_trade_create_required_pages( $errors );
+ $news_result = fragrance_trade_ensure_news_page( $errors );
if ( ! empty( $page_result['pages']['home'] ) ) {
update_option( 'page_on_front', $page_result['pages']['home'] );
update_option( 'show_on_front', 'page' );
}
- if ( $seed_changed || $copy_changed || $page_result['changed'] ) {
+ if ( $seed_changed || $copy_changed || $page_result['changed'] || $news_result['changed'] ) {
flush_rewrite_rules();
}
@@ -412,6 +467,16 @@ function fragrance_trade_page_status_notice() {
$unpublished[] = $page->post_title;
}
}
+ $posts_page_id = absint( get_option( 'page_for_posts', 0 ) );
+ $posts_page = $posts_page_id ? get_post( $posts_page_id ) : null;
+ if (
+ $posts_page
+ && 'page' === $posts_page->post_type
+ && 'publish' !== $posts_page->post_status
+ && ! in_array( $posts_page->post_title, $unpublished, true )
+ ) {
+ $unpublished[] = $posts_page->post_title;
+ }
if ( ! $unpublished ) {
return;
}
diff --git a/inc/customizer.php b/inc/customizer.php
index b0aa38e..7ef40ae 100644
--- a/inc/customizer.php
+++ b/inc/customizer.php
@@ -92,10 +92,18 @@ function fragrance_trade_customize_register( $wp_customize ) {
array( 'youtube_url', 'fragrance_contact_social', __( 'YouTube 链接', 'fragrance-trade' ), 'url' ),
array( 'linkedin_url', 'fragrance_contact_social', __( 'LinkedIn 链接', 'fragrance-trade' ), 'url' ),
array( 'instagram_social_url', 'fragrance_contact_social', __( 'Instagram 链接', 'fragrance-trade' ), 'url' ),
+ array( 'store_brand', 'fragrance_contact_social', __( '主营品牌', 'fragrance-trade' ), 'text' ),
+ array( 'store_authorization', 'fragrance_contact_social', __( '授权级别', 'fragrance-trade' ), 'text' ),
+ array( 'store_city', 'fragrance_contact_social', __( '所在城市', 'fragrance-trade' ), 'text' ),
+ array( 'store_contact_person', 'fragrance_contact_social', __( '门店联系人', 'fragrance-trade' ), 'text' ),
array( 'store_address', 'fragrance_contact_social', __( '门店地址', 'fragrance-trade' ), 'textarea' ),
array( 'store_phone', 'fragrance_contact_social', __( '联系电话', 'fragrance-trade' ), 'text' ),
array( 'store_hours', 'fragrance_contact_social', __( '营业时间', 'fragrance-trade' ), 'text' ),
array( 'store_map_url', 'fragrance_contact_social', __( '地图导航链接', 'fragrance-trade' ), 'url' ),
+ array( 'store_map_lat', 'fragrance_contact_social', __( '百度地图纬度', 'fragrance-trade' ), 'text' ),
+ array( 'store_map_lng', 'fragrance_contact_social', __( '百度地图经度', 'fragrance-trade' ), 'text' ),
+ array( 'icp_number', 'fragrance_contact_social', __( 'ICP备案号', 'fragrance-trade' ), 'text' ),
+ array( 'icp_url', 'fragrance_contact_social', __( 'ICP备案查询链接', 'fragrance-trade' ), 'url' ),
array( 'footer_text', 'fragrance_contact_social', __( '页脚定位文案', 'fragrance-trade' ), 'text' ),
);
diff --git a/inc/defaults.php b/inc/defaults.php
index ff572a5..8ec5132 100644
--- a/inc/defaults.php
+++ b/inc/defaults.php
@@ -18,8 +18,8 @@ function fragrance_trade_defaults() {
$defaults = array(
'b2b_hero_eyebrow' => __( '需求沟通 · 方案确认 · 施工交付', 'fragrance-trade' ),
- 'b2b_hero_title' => __( 'xxx店铺名字', 'fragrance-trade' ),
- 'b2b_hero_text' => __( 'xxx地址', 'fragrance-trade' ),
+ 'b2b_hero_title' => __( '康得新合肥新创贴膜中心(官方授权店)', 'fragrance-trade' ),
+ 'b2b_hero_text' => __( '康得新 KDX 官方授权至尊服务店,位于合肥市瑶海区铜陵北路高架桥出口与铜陵北路辅路交叉口东北140米。', 'fragrance-trade' ),
'b2b_hero_primary_label' => __( '联系门店', 'fragrance-trade' ),
'b2b_hero_primary_url' => '/contact/',
'b2b_hero_secondary_label' => __( '了解服务项目', 'fragrance-trade' ),
@@ -85,11 +85,19 @@ function fragrance_trade_defaults() {
'youtube_url' => '',
'linkedin_url' => '',
'instagram_social_url' => '',
- 'store_address' => '',
- 'store_phone' => __( 'xxx电话', 'fragrance-trade' ),
- 'store_hours' => '',
+ 'store_brand' => __( '康得新 KDX', 'fragrance-trade' ),
+ 'store_authorization' => __( '官方授权至尊服务店', 'fragrance-trade' ),
+ 'store_city' => __( '合肥市', 'fragrance-trade' ),
+ 'store_contact_person' => __( '贾文浩', 'fragrance-trade' ),
+ 'store_address' => __( '合肥市瑶海区铜陵北路高架桥出口与铜陵北路辅路交叉口东北140米', 'fragrance-trade' ),
+ 'store_phone' => '18655174646',
+ 'store_hours' => __( '09:00–22:30', 'fragrance-trade' ),
'store_map_url' => '',
- 'footer_text' => __( '专注汽车贴膜方案沟通、施工交付与日常护理说明。', 'fragrance-trade' ),
+ 'store_map_lat' => '31.907786',
+ 'store_map_lng' => '117.336666',
+ 'icp_number' => '',
+ 'icp_url' => 'https://beian.miit.gov.cn/',
+ 'footer_text' => __( '康得新 KDX 官方授权至尊服务店,提供隐形车衣、改色膜与汽车隔热膜服务。', 'fragrance-trade' ),
);
return $defaults;
diff --git a/inc/helpers.php b/inc/helpers.php
index 2ceb528..2d3c8e6 100644
--- a/inc/helpers.php
+++ b/inc/helpers.php
@@ -32,6 +32,74 @@ function fragrance_trade_image_uri( $setting, $fallback_filename ) {
return $image ? $image : fragrance_trade_asset_uri( 'images/' . $fallback_filename );
}
+/**
+ * Return the horizontal image used by service cards and carousels.
+ *
+ * Product seeds use a dedicated landscape cover while their featured image
+ * remains the complete parameter poster shown on the service detail page.
+ *
+ * @param int $post_id Service post ID.
+ * @param string $fallback_filename Asset path below assets/images/.
+ * @return string
+ */
+function fragrance_trade_service_card_image( $post_id, $fallback_filename = 'products/placeholder-01.svg' ) {
+ $post_id = absint( $post_id );
+ $image_attr = array(
+ 'class' => 'img-fluid',
+ 'loading' => 'lazy',
+ 'decoding' => 'async',
+ );
+ $cover_id = absint( get_post_meta( $post_id, '_fragrance_service_cover_id', true ) );
+
+ if ( $cover_id ) {
+ $image = wp_get_attachment_image( $cover_id, 'large', false, $image_attr );
+ if ( $image ) {
+ return $image;
+ }
+ }
+
+ $cover_file = (string) get_post_meta( $post_id, '_fragrance_service_cover_file', true );
+ if ( ! $cover_file && function_exists( 'fragrance_trade_product_service_seeds' ) ) {
+ $seeds = fragrance_trade_product_service_seeds();
+ $seed_key = (string) get_post_meta( $post_id, '_fragrance_product_seed_key', true );
+
+ if ( $seed_key && isset( $seeds[ $seed_key ]['cover'] ) ) {
+ $cover_file = $seeds[ $seed_key ]['cover'];
+ } else {
+ $post_slug = (string) get_post_field( 'post_name', $post_id );
+ foreach ( $seeds as $seed ) {
+ if ( $post_slug === $seed['slug'] && ! empty( $seed['cover'] ) ) {
+ $cover_file = $seed['cover'];
+ break;
+ }
+ }
+ }
+ }
+
+ if (
+ $cover_file
+ && preg_match( '#^[a-zA-Z0-9/_-]+\.(?:jpe?g|png|webp)$#', $cover_file )
+ && is_readable( get_template_directory() . '/assets/images/services/' . $cover_file )
+ ) {
+ return sprintf(
+ '

',
+ esc_url( fragrance_trade_asset_uri( 'images/services/' . $cover_file ) ),
+ esc_attr( get_the_title( $post_id ) )
+ );
+ }
+
+ if ( has_post_thumbnail( $post_id ) ) {
+ return (string) get_the_post_thumbnail( $post_id, 'fragrance-capability', $image_attr );
+ }
+
+ $legacy_image = get_post_meta( $post_id, '_service_image', true );
+ return sprintf(
+ '

',
+ esc_url( $legacy_image ? $legacy_image : fragrance_trade_asset_uri( 'images/' . ltrim( $fallback_filename, '/' ) ) ),
+ esc_attr( get_the_title( $post_id ) )
+ );
+}
+
function fragrance_trade_show_section( $setting ) {
return (bool) fragrance_trade_get_mod( $setting, true );
}
@@ -56,11 +124,36 @@ function fragrance_trade_get_inquiry_url( $project = '' ) {
return 'mailto:' . antispambot( fragrance_trade_inquiry_email() ) . '?subject=' . rawurlencode( __( '汽车贴膜服务咨询', 'fragrance-trade' ) ) . '&body=' . rawurlencode( $message );
}
+/** Return the configured WordPress posts-page URL with a stable fresh-site fallback. */
+function fragrance_trade_news_url() {
+ $posts_page_id = absint( get_option( 'page_for_posts', 0 ) );
+ $posts_page = $posts_page_id ? get_post( $posts_page_id ) : null;
+ if ( $posts_page && 'page' === $posts_page->post_type ) {
+ $url = get_permalink( $posts_page_id );
+ if ( $url ) {
+ return $url;
+ }
+ }
+ return home_url( '/news/' );
+}
+
+/** Keep news grids aligned without changing the site's global reading option. */
+function fragrance_trade_news_posts_per_page( $query ) {
+ if ( is_admin() || ! $query->is_main_query() || $query->is_feed() ) {
+ return;
+ }
+ if ( $query->is_home() || $query->is_category() || $query->is_tag() || $query->is_date() || $query->is_author() ) {
+ $query->set( 'posts_per_page', 9 );
+ }
+}
+add_action( 'pre_get_posts', 'fragrance_trade_news_posts_per_page' );
+
function fragrance_trade_primary_menu_fallback() {
$links = array(
array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
array( 'label' => __( '服务项目', 'fragrance-trade' ), 'url' => get_post_type_archive_link( 'service' ) ?: home_url( '/services/' ) ),
array( 'label' => __( '案例作品', 'fragrance-trade' ), 'url' => get_post_type_archive_link( 'case' ) ?: home_url( '/cases/' ) ),
+ array( 'label' => __( '新闻资讯', 'fragrance-trade' ), 'url' => fragrance_trade_news_url() ),
array( 'label' => __( '关于门店', 'fragrance-trade' ), 'url' => home_url( '/about/' ) ),
array( 'label' => __( '常见问题', 'fragrance-trade' ), 'url' => home_url( '/faq/' ) ),
array( 'label' => __( '联系我们', 'fragrance-trade' ), 'url' => home_url( '/contact/' ) ),
@@ -102,7 +195,34 @@ add_action(
printf(
'
',
esc_html__( '主导航菜单项过少', 'fragrance-trade' ),
- esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、联系我们。', 'fragrance-trade' ),
+ esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、新闻资讯、关于门店、常见问题、联系我们。', 'fragrance-trade' ),
+ esc_url( admin_url( 'nav-menus.php' ) ),
+ esc_html__( '编辑菜单', 'fragrance-trade' )
+ );
+ }
+
+ $news_page_id = absint( get_option( 'page_for_posts', 0 ) );
+ $news_page = $news_page_id ? get_post( $news_page_id ) : null;
+ if ( ! $news_page || 'publish' !== $news_page->post_status ) {
+ return;
+ }
+
+ $news_url = untrailingslashit( fragrance_trade_news_url() );
+ $has_news_link = false;
+ foreach ( (array) $items as $item ) {
+ if (
+ ( 'page' === $item->object && $news_page_id === (int) $item->object_id )
+ || $news_url === untrailingslashit( $item->url )
+ ) {
+ $has_news_link = true;
+ break;
+ }
+ }
+ if ( ! $has_news_link ) {
+ printf(
+ '
',
+ esc_html__( '主导航尚未包含新闻资讯', 'fragrance-trade' ),
+ esc_html__( '主题不会自动修改已分配的菜单,请将 WordPress 文章页添加到“主导航”。', 'fragrance-trade' ),
esc_url( admin_url( 'nav-menus.php' ) ),
esc_html__( '编辑菜单', 'fragrance-trade' )
);
diff --git a/inc/service-seeds.php b/inc/service-seeds.php
new file mode 100644
index 0000000..b84f2f2
--- /dev/null
+++ b/inc/service-seeds.php
@@ -0,0 +1,385 @@
+ array(
+ 'title' => __( 'KDX 盾甲隐形车衣', 'fragrance-trade' ),
+ 'slug' => 'kdx-dunjia-paint-protection-film',
+ 'image' => 'kdx-dunjia.jpg',
+ 'cover' => 'covers/kdx-dunjia-cover.jpg',
+ 'excerpt' => __( '7.5mil 厚度 · 7 年质保 · 光泽度 150', 'fragrance-trade' ),
+ 'summary' => __( '盾甲是一款兼顾车漆保护、亮面效果与日常养护的隐形车衣产品,适合关注基础防护与光泽表现的用车场景。', 'fragrance-trade' ),
+ 'specs' => array(
+ __( '产品厚度', 'fragrance-trade' ) => '7.5mil',
+ __( '质保年限', 'fragrance-trade' ) => __( '7 年', 'fragrance-trade' ),
+ __( '光泽度', 'fragrance-trade' ) => '150',
+ __( '拉伸强度', 'fragrance-trade' ) => '18MPa',
+ __( '断裂伸长率', 'fragrance-trade' ) => '380%',
+ __( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
+ __( '水接触角', 'fragrance-trade' ) => '102°',
+ __( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
+ __( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
+ ),
+ ),
+ 'kdx-kaijia-plus' => array(
+ 'title' => __( 'KDX 铠甲 Plus 隐形车衣', 'fragrance-trade' ),
+ 'slug' => 'kdx-kaijia-plus-paint-protection-film',
+ 'image' => 'kdx-kaijia-plus.jpg',
+ 'cover' => 'covers/kdx-kaijia-plus-cover.jpg',
+ 'excerpt' => __( '8.5mil 厚度 · 8 年质保 · 断裂伸长率 460%', 'fragrance-trade' ),
+ 'summary' => __( '铠甲 Plus 采用更高的标称厚度和断裂伸长率,适合希望进一步提升车漆覆盖防护与膜面韧性的用车需求。', 'fragrance-trade' ),
+ 'specs' => array(
+ __( '产品厚度', 'fragrance-trade' ) => '8.5mil',
+ __( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
+ __( '光泽度', 'fragrance-trade' ) => '150',
+ __( '拉伸强度', 'fragrance-trade' ) => '23MPa',
+ __( '断裂伸长率', 'fragrance-trade' ) => '460%',
+ __( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
+ __( '水接触角', 'fragrance-trade' ) => '73°',
+ __( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
+ __( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
+ ),
+ ),
+ 'kdx-kaijia' => array(
+ 'title' => __( 'KDX 铠甲隐形车衣', 'fragrance-trade' ),
+ 'slug' => 'kdx-kaijia-paint-protection-film',
+ 'image' => 'kdx-kaijia.jpg',
+ 'cover' => 'covers/kdx-kaijia-cover.jpg',
+ 'excerpt' => __( '7.5mil 厚度 · 7 年质保 · 拉伸强度 25MPa', 'fragrance-trade' ),
+ 'summary' => __( '铠甲隐形车衣侧重膜面韧性、亮面效果与基础耐粘污表现,并提供雾度、可见光透射比和剥离力等补充参数。', 'fragrance-trade' ),
+ 'specs' => array(
+ __( '产品厚度', 'fragrance-trade' ) => '7.5mil',
+ __( '质保年限', 'fragrance-trade' ) => __( '7 年', 'fragrance-trade' ),
+ __( '光泽度', 'fragrance-trade' ) => '150',
+ __( '拉伸强度', 'fragrance-trade' ) => '25MPa',
+ __( '断裂伸长率', 'fragrance-trade' ) => '430%',
+ __( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
+ __( '水接触角', 'fragrance-trade' ) => '73°',
+ __( '耐粘污性', 'fragrance-trade' ) => __( '三星', 'fragrance-trade' ),
+ __( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
+ __( '雾度', 'fragrance-trade' ) => '0.3%',
+ __( '可见光透射比', 'fragrance-trade' ) => '90%',
+ __( '180°剥离力(30 分钟)', 'fragrance-trade' ) => '1400gf/inch',
+ __( '180°剥离力(2 小时)', 'fragrance-trade' ) => '1800gf/inch',
+ __( '涂层断裂伸长率', 'fragrance-trade' ) => '160%',
+ ),
+ ),
+ 'kdx-dunjia-plus' => array(
+ 'title' => __( 'KDX 盾甲 Plus 隐形车衣', 'fragrance-trade' ),
+ 'slug' => 'kdx-dunjia-plus-paint-protection-film',
+ 'image' => 'kdx-dunjia-plus.jpg',
+ 'cover' => 'covers/kdx-dunjia-plus-cover.jpg',
+ 'excerpt' => __( '8.5mil 厚度 · 8 年质保 · 水接触角 102°', 'fragrance-trade' ),
+ 'summary' => __( '盾甲 Plus 在盾甲产品方向上提升标称厚度与质保年限,兼顾膜面亮度、水接触角和日常车漆保护需求。', 'fragrance-trade' ),
+ 'specs' => array(
+ __( '产品厚度', 'fragrance-trade' ) => '8.5mil',
+ __( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
+ __( '光泽度', 'fragrance-trade' ) => '150',
+ __( '拉伸强度', 'fragrance-trade' ) => '21MPa',
+ __( '断裂伸长率', 'fragrance-trade' ) => '400%',
+ __( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
+ __( '水接触角', 'fragrance-trade' ) => '102°',
+ __( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
+ __( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
+ ),
+ ),
+ 'kdx-jinjia-pro' => array(
+ 'title' => __( 'KDX 金甲 PRO 隐形车衣', 'fragrance-trade' ),
+ 'slug' => 'kdx-jinjia-pro-paint-protection-film',
+ 'image' => 'kdx-jinjia-pro.jpg',
+ 'cover' => 'covers/kdx-jinjia-pro-cover.jpg',
+ 'excerpt' => __( '7.5mil 厚度 · 8 年质保 · 光泽度 153', 'fragrance-trade' ),
+ 'summary' => __( '金甲 PRO 侧重高光泽、耐粘污表现与较长质保周期,适合关注亮面质感和日常清洁便利性的车漆保护方案。', 'fragrance-trade' ),
+ 'specs' => array(
+ __( '产品厚度', 'fragrance-trade' ) => '7.5mil',
+ __( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
+ __( '光泽度', 'fragrance-trade' ) => '153',
+ __( '拉伸强度', 'fragrance-trade' ) => '18MPa',
+ __( '断裂伸长率', 'fragrance-trade' ) => '350%',
+ __( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
+ __( '水接触角', 'fragrance-trade' ) => '95°',
+ __( '耐粘污性', 'fragrance-trade' ) => __( '优秀', 'fragrance-trade' ),
+ __( '热修复', 'fragrance-trade' ) => __( '90 秒', 'fragrance-trade' ),
+ ),
+ ),
+ );
+}
+
+/** Find a product service previously created by this importer. */
+function fragrance_trade_find_product_service_seed( $seed_key ) {
+ $ids = get_posts(
+ array(
+ 'post_type' => 'service',
+ 'post_status' => fragrance_trade_seed_post_statuses(),
+ 'posts_per_page' => 1,
+ 'fields' => 'ids',
+ 'meta_key' => '_fragrance_product_seed_key',
+ 'meta_value' => $seed_key,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $ids ? (int) $ids[0] : 0;
+}
+
+/** Find a service with the conventional product slug. */
+function fragrance_trade_find_product_service_slug( $slug ) {
+ $posts = get_posts(
+ array(
+ 'post_type' => 'service',
+ 'post_status' => fragrance_trade_seed_post_statuses(),
+ 'name' => $slug,
+ 'posts_per_page' => 1,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $posts ? (int) $posts[0]->ID : 0;
+}
+
+/** Find a bundled product image already copied into the media library. */
+function fragrance_trade_find_product_service_attachment( $seed_key ) {
+ $ids = get_posts(
+ array(
+ 'post_type' => 'attachment',
+ 'post_status' => 'inherit',
+ 'posts_per_page' => 1,
+ 'fields' => 'ids',
+ 'meta_key' => '_fragrance_product_seed_image',
+ 'meta_value' => $seed_key,
+ 'no_found_rows' => true,
+ )
+ );
+
+ return $ids ? (int) $ids[0] : 0;
+}
+
+/**
+ * Copy one bundled service image into the WordPress media library.
+ *
+ * @param int $service_id Parent service post ID.
+ * @param string $seed_key Stable service seed key.
+ * @param array $seed Service seed record.
+ * @return int|WP_Error
+ */
+function fragrance_trade_import_product_service_image( $service_id, $seed_key, $seed ) {
+ $existing = fragrance_trade_find_product_service_attachment( $seed_key );
+ if ( $existing ) {
+ if ( (int) wp_get_post_parent_id( $existing ) !== (int) $service_id ) {
+ wp_update_post(
+ array(
+ 'ID' => $existing,
+ 'post_parent' => $service_id,
+ )
+ );
+ }
+ return $existing;
+ }
+
+ $source_file = get_template_directory() . '/assets/images/services/' . $seed['image'];
+ if ( ! is_readable( $source_file ) ) {
+ return new WP_Error(
+ 'fragrance_product_seed_image_missing',
+ sprintf(
+ /* translators: %s: service title. */
+ __( '服务“%s”的初始化图片不存在。', 'fragrance-trade' ),
+ $seed['title']
+ )
+ );
+ }
+
+ $image_bytes = file_get_contents( $source_file );
+ if ( false === $image_bytes ) {
+ return new WP_Error(
+ 'fragrance_product_seed_image_unreadable',
+ sprintf(
+ /* translators: %s: service title. */
+ __( '无法读取服务“%s”的初始化图片。', 'fragrance-trade' ),
+ $seed['title']
+ )
+ );
+ }
+
+ $upload = wp_upload_bits( $seed['image'], null, $image_bytes );
+ unset( $image_bytes );
+ if ( ! empty( $upload['error'] ) ) {
+ return new WP_Error( 'fragrance_product_seed_upload_failed', $upload['error'] );
+ }
+
+ $attachment_id = wp_insert_attachment(
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_title' => sprintf(
+ /* translators: %s: service title. */
+ __( '%s产品参数图', 'fragrance-trade' ),
+ $seed['title']
+ ),
+ 'post_status' => 'inherit',
+ ),
+ $upload['file'],
+ $service_id,
+ true
+ );
+
+ if ( is_wp_error( $attachment_id ) ) {
+ wp_delete_file( $upload['file'] );
+ return $attachment_id;
+ }
+
+ require_once ABSPATH . 'wp-admin/includes/image.php';
+ $metadata = wp_generate_attachment_metadata( $attachment_id, $upload['file'] );
+ if ( $metadata ) {
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ }
+
+ update_post_meta( $attachment_id, '_fragrance_product_seed_image', $seed_key );
+ update_post_meta(
+ $attachment_id,
+ '_wp_attachment_image_alt',
+ sprintf(
+ /* translators: %s: service title. */
+ __( '%s产品参数与车型示意图', 'fragrance-trade' ),
+ $seed['title']
+ )
+ );
+
+ return (int) $attachment_id;
+}
+
+/** Build block-editor content for a product service. */
+function fragrance_trade_build_product_service_content( $seed ) {
+ $items = '';
+ foreach ( $seed['specs'] as $label => $value ) {
+ $items .= sprintf(
+ '
%1$s:%2$s',
+ esc_html( $label ),
+ esc_html( $value )
+ );
+ }
+
+ return sprintf(
+ '
%1$s
' .
+ '
%2$s
' .
+ '
' .
+ '
%4$s
',
+ esc_html( $seed['summary'] ),
+ esc_html__( '产品参数', 'fragrance-trade' ),
+ $items,
+ esc_html__( '以上参数根据所提供的产品资料整理。实际产品版本、施工范围、价格、质保条件与交付标准请以门店最终确认及正式质保文件为准。', 'fragrance-trade' )
+ );
+}
+
+/**
+ * Import every bundled product service without overwriting existing content.
+ *
+ * @return array{created:int,existing:int,errors:string[]}
+ */
+function fragrance_trade_import_product_service_seeds() {
+ $result = array(
+ 'created' => 0,
+ 'existing' => 0,
+ 'errors' => array(),
+ );
+
+ foreach ( fragrance_trade_product_service_seeds() as $seed_key => $seed ) {
+ $service_id = fragrance_trade_find_product_service_seed( $seed_key );
+ if ( $service_id && 'publish' === get_post_status( $service_id ) ) {
+ update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
+ ++$result['existing'];
+ continue;
+ }
+ if (
+ $service_id
+ && (
+ 'draft' !== get_post_status( $service_id )
+ || 'importing' !== get_post_meta( $service_id, '_fragrance_product_seed_state', true )
+ )
+ ) {
+ update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
+ ++$result['existing'];
+ continue;
+ }
+
+ if ( ! $service_id ) {
+ if ( fragrance_trade_find_product_service_slug( $seed['slug'] ) ) {
+ ++$result['existing'];
+ continue;
+ }
+
+ $service_id = wp_insert_post(
+ array(
+ 'post_type' => 'service',
+ 'post_name' => $seed['slug'],
+ 'post_title' => $seed['title'],
+ 'post_excerpt' => $seed['excerpt'],
+ 'post_status' => 'draft',
+ ),
+ true
+ );
+ if ( is_wp_error( $service_id ) ) {
+ $result['errors'][] = sprintf(
+ /* translators: 1: service title, 2: error message. */
+ __( '无法创建服务“%1$s”:%2$s', 'fragrance-trade' ),
+ $seed['title'],
+ $service_id->get_error_message()
+ );
+ continue;
+ }
+
+ update_post_meta( $service_id, '_fragrance_product_seed_key', $seed_key );
+ update_post_meta( $service_id, '_fragrance_product_seed_state', 'importing' );
+ update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
+ }
+
+ $attachment_id = fragrance_trade_import_product_service_image( $service_id, $seed_key, $seed );
+ if ( is_wp_error( $attachment_id ) ) {
+ $result['errors'][] = $attachment_id->get_error_message();
+ continue;
+ }
+
+ set_post_thumbnail( $service_id, $attachment_id );
+ $updated = wp_update_post(
+ array(
+ 'ID' => $service_id,
+ 'post_title' => $seed['title'],
+ 'post_name' => $seed['slug'],
+ 'post_excerpt' => $seed['excerpt'],
+ 'post_content' => fragrance_trade_build_product_service_content( $seed ),
+ 'post_status' => 'publish',
+ ),
+ true
+ );
+
+ if ( is_wp_error( $updated ) ) {
+ $result['errors'][] = sprintf(
+ /* translators: 1: service title, 2: error message. */
+ __( '无法发布服务“%1$s”:%2$s', 'fragrance-trade' ),
+ $seed['title'],
+ $updated->get_error_message()
+ );
+ continue;
+ }
+
+ delete_post_meta( $service_id, '_fragrance_product_seed_state' );
+ update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
+ ++$result['created'];
+ }
+
+ $result['errors'] = array_values( array_unique( $result['errors'] ) );
+ return $result;
+}
diff --git a/languages/fragrance-trade.pot b/languages/fragrance-trade.pot
index fb16635..c73f769 100644
--- a/languages/fragrance-trade.pot
+++ b/languages/fragrance-trade.pot
@@ -2,9 +2,9 @@
# This file is distributed under the GNU General Public License v2 or later.
msgid ""
msgstr ""
-"Project-Id-Version: B2B Trade 2.1.0\n"
+"Project-Id-Version: B2B Trade 2.2.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2026-07-24 14:19+0000\n"
+"POT-Creation-Date: 2026-07-26 00:00+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -335,7 +335,7 @@ msgid "想先了解适合哪种贴膜方案?"
msgstr ""
#: inc/helpers.php:105
-msgid "手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、联系我们。"
+msgid "手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、新闻资讯、关于门店、常见问题、联系我们。"
msgstr ""
#: header.php:32
@@ -968,3 +968,141 @@ msgstr ""
#: inc/defaults.php
msgid "xxx电话"
msgstr ""
+
+#: template-parts/home/case-teaser.php:66
+msgid "下一组案例"
+msgstr ""
+
+#: template-parts/home/service-teaser.php:70
+msgid "下一组服务项目"
+msgstr ""
+
+#: template-parts/home/case-teaser.php:62
+msgid "上一组案例"
+msgstr ""
+
+#: template-parts/home/service-teaser.php:66
+msgid "上一组服务项目"
+msgstr ""
+
+#: template-parts/home/case-teaser.php:61
+msgid "案例作品轮播控制"
+msgstr ""
+
+#: template-parts/home/service-teaser.php:65
+msgid "服务项目轮播控制"
+msgstr ""
+
+#: template-parts/home/case-teaser.php:27
+#: template-parts/home/service-teaser.php:29
+#, php-format
+msgid "转到第 %d 组"
+msgstr ""
+
+#: footer.php home.php archive.php single-post.php inc/cpt.php inc/helpers.php
+msgid "新闻资讯"
+msgstr ""
+
+#. translators: %s: error message.
+#: inc/cpt.php
+#, php-format
+msgid "无法创建新闻资讯页面:%s"
+msgstr ""
+
+#: inc/cpt.php
+msgid "无法将新闻资讯页面设置为 WordPress 文章页。"
+msgstr ""
+
+#: inc/helpers.php
+msgid "主导航尚未包含新闻资讯"
+msgstr ""
+
+#: inc/helpers.php
+msgid "主题不会自动修改已分配的菜单,请将 WordPress 文章页添加到“主导航”。"
+msgstr ""
+
+#: home.php
+msgid "门店动态与用车知识"
+msgstr ""
+
+#: home.php
+msgid "了解门店活动、产品信息、施工知识与汽车膜日常护理建议。"
+msgstr ""
+
+#: home.php
+msgid "新闻内容正在整理中"
+msgstr ""
+
+#: home.php
+msgid "门店动态、产品知识和施工说明将在这里陆续发布。"
+msgstr ""
+
+#: template-parts/content-news-card.php
+msgid "阅读全文"
+msgstr ""
+
+#. translators: %s: news article title.
+#: template-parts/content-news-card.php
+#, php-format
+msgid "阅读%s"
+msgstr ""
+
+#: archive.php
+msgid "新闻归档"
+msgstr ""
+
+#: archive.php
+msgid "此归档暂时没有新闻"
+msgstr ""
+
+#: archive.php
+msgid "可以返回新闻资讯页面浏览其他内容。"
+msgstr ""
+
+#: archive.php
+msgid "返回新闻资讯"
+msgstr ""
+
+#: single-post.php
+msgid "文章分页"
+msgstr ""
+
+#: single-post.php
+msgid "上一篇"
+msgstr ""
+
+#: single-post.php
+msgid "下一篇"
+msgstr ""
+
+#: single-post.php
+msgid "新闻文章导航"
+msgstr ""
+
+#: single-post.php
+msgid "需要了解适合车辆的贴膜方案?"
+msgstr ""
+
+#: single-post.php
+msgid "提供车型、使用场景和关注的问题,门店会结合实际情况说明可选项目。"
+msgstr ""
+
+#: single-post.php
+msgid "咨询贴膜方案"
+msgstr ""
+
+#: inc/customizer.php
+msgid "ICP备案号"
+msgstr ""
+
+#: inc/customizer.php
+msgid "ICP备案查询链接"
+msgstr ""
+
+#: inc/customizer.php
+msgid "百度地图纬度"
+msgstr ""
+
+#: inc/customizer.php
+msgid "百度地图经度"
+msgstr ""
diff --git a/page-contact.php b/page-contact.php
index 5b101b0..5a55309 100644
--- a/page-contact.php
+++ b/page-contact.php
@@ -13,9 +13,15 @@ if ( ! defined( 'ABSPATH' ) ) {
get_header();
$store_name = fragrance_trade_get_mod( 'b2b_hero_title' );
-$store_address = fragrance_trade_get_mod( 'store_address', '' );
+$store_brand = fragrance_trade_get_mod( 'store_brand' );
+$authorization = fragrance_trade_get_mod( 'store_authorization' );
+$store_city = fragrance_trade_get_mod( 'store_city' );
+$contact_name = fragrance_trade_get_mod( 'store_contact_person' );
+$store_address = fragrance_trade_get_mod( 'store_address' );
$store_phone = fragrance_trade_get_mod( 'store_phone' );
-$store_hours = fragrance_trade_get_mod( 'store_hours', '' );
+$store_hours = fragrance_trade_get_mod( 'store_hours' );
+$store_map_lat = fragrance_trade_get_mod( 'store_map_lat' );
+$store_map_lng = fragrance_trade_get_mod( 'store_map_lng' );
$store_image = fragrance_trade_image_uri( 'b2b_factory_image_1', 'store/storefront.jpg' );
$phone_href = preg_replace( '/[^0-9+]/', '', $store_phone );
$has_phone = strlen( preg_replace( '/[^0-9]/', '', $phone_href ) ) >= 5;
@@ -26,10 +32,31 @@ if ( ! $store_address ) {
$map_nav_url = fragrance_trade_get_mod( 'store_map_url', '' );
$baidu_map_url = '';
-if ( $store_address ) {
- $baidu_map_url = 'https://api.map.baidu.com/geocoder?address='
- . rawurlencode( $store_address )
+$map_search_term = $store_name ? $store_name : $store_address;
+$has_map_coordinates = is_numeric( $store_map_lat )
+ && is_numeric( $store_map_lng )
+ && (float) $store_map_lat >= -90
+ && (float) $store_map_lat <= 90
+ && (float) $store_map_lng >= -180
+ && (float) $store_map_lng <= 180;
+
+if ( $has_map_coordinates ) {
+ $baidu_map_url = 'https://api.map.baidu.com/marker?location='
+ . rawurlencode( $store_map_lat . ',' . $store_map_lng )
+ . '&title=' . rawurlencode( $store_name )
+ . '&content=' . rawurlencode( $store_address )
. '&output=html&src=webapp';
+} elseif ( $map_search_term ) {
+ if ( $store_city ) {
+ $baidu_map_url = 'https://api.map.baidu.com/place/search?query='
+ . rawurlencode( $map_search_term )
+ . '®ion=' . rawurlencode( $store_city )
+ . '&city_limit=true&output=html&src=webapp';
+ } else {
+ $baidu_map_url = 'https://api.map.baidu.com/geocoder?address='
+ . rawurlencode( $map_search_term )
+ . '&output=html&src=webapp';
+ }
}
if ( ! $map_nav_url ) {
$map_nav_url = $baidu_map_url;
@@ -97,6 +124,24 @@ $map_title = sprintf( __( '%s门店地图', 'fragrance-trade' ), $store_name );
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -111,6 +156,12 @@ $map_title = sprintf( __( '%s门店地图', 'fragrance-trade' ), $store_name );
+
+
+
+
+
+
@@ -135,8 +186,8 @@ $map_title = sprintf( __( '%s门店地图', 'fragrance-trade' ), $store_name );
diff --git a/single-post.php b/single-post.php
new file mode 100644
index 0000000..be4d340
--- /dev/null
+++ b/single-post.php
@@ -0,0 +1,87 @@
+
+
+
+ >
+ array(
+ array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
+ array( 'label' => __( '新闻资讯', 'fragrance-trade' ), 'url' => fragrance_trade_news_url() ),
+ array( 'label' => get_the_title(), 'url' => null ),
+ ),
+ )
+ );
+ ?>
+
+
+
+
+ 'img-fluid', 'decoding' => 'async' ) ); ?>
+
+
+
+
+
+ '',
+ )
+ );
+ ?>
+
+
+
+
+ '' . esc_html__( '上一篇', 'fragrance-trade' ) . '%title',
+ 'next_text' => '' . esc_html__( '下一篇', 'fragrance-trade' ) . '%title',
+ 'in_same_term' => false,
+ 'taxonomy' => 'category',
+ 'screen_reader_text' => __( '新闻文章导航', 'fragrance-trade' ),
+ )
+ );
+ ?>
+
+
+
+
+
+
+
+
diff --git a/style.css b/style.css
index 17da95b..06adc4a 100644
--- a/style.css
+++ b/style.css
@@ -2,8 +2,8 @@
Theme Name: B2B Trade
Theme URI: http://git.xgouo.cn/zhs123/car-t-t
Author: B2B Trade
-Description: 专业汽车贴膜门店主题,支持服务项目、案例作品集、门店信息和直接联系,适配移动端。
-Version: 2.1.0
+Description: 专业汽车贴膜门店主题,支持服务项目、案例作品集、新闻资讯、门店信息和直接联系,适配移动端。
+Version: 2.2.0
Requires at least: 6.8
Tested up to: 7.0
Requires PHP: 8.1
diff --git a/template-parts/content-news-card.php b/template-parts/content-news-card.php
new file mode 100644
index 0000000..c404b30
--- /dev/null
+++ b/template-parts/content-news-card.php
@@ -0,0 +1,38 @@
+
+>
+
+
+ 'img-fluid', 'loading' => 'lazy', 'decoding' => 'async' ) ); ?>
+
+
+
+
+
+
diff --git a/template-parts/home/case-teaser.php b/template-parts/home/case-teaser.php
index baf42f6..7f76c43 100644
--- a/template-parts/home/case-teaser.php
+++ b/template-parts/home/case-teaser.php
@@ -20,17 +20,53 @@ $case_query = new WP_Query(
have_posts() ) : ?>
-