feat: release B2B Trade theme 2.1.0

This commit is contained in:
WorkBuddy
2026-07-24 22:25:29 +08:00
parent 13a35c7ec7
commit 4f070d4677
64 changed files with 1769 additions and 1762 deletions
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Not-found template. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main container py-5 fragrance-content-area">
+46 -208
View File
@@ -1,225 +1,63 @@
# 代码清理方案
# B2B Trade 2.1.0 清理记录
> 项目:B2B Trade 主题(fragrance-trade
> 基准:2026-07-24 全量代码扫描
> 原则:分阶段、可回滚、每步可验证
本文记录 2.1.0 已执行的清理和必须保留的兼容边界,后续维护不得重新引入已删除的运行路径。
---
## 已完成
## 清理范围总览
### 联系流程
| 类别 | 数量 | 风险 | 说明 |
|------|------|------|------|
| 死模板文件 | 7 个 | 低 | 多页面重构后遗留,无任何 `get_template_part()` 引用 |
| 死 JS 库 | 4 个 | 中 | plugins.js 中 6 个库仅 1 个实际使用 |
| 死 CSS 样式 | ~60% vendor.css | 低 | Jarallax + AOS 样式,对应功能未使用 |
| 死图片资源 | 13 个 | 极低 | 旧模板遗留素材,全项目零引用 |
| 死表单处理器 | 1 个 | 中 | inquiry.php 仍挂在 admin_post 但无表单提交 |
| CDN 安全缺失 | 2 处 | 中 | Bootstrap 无 SRI 完整性校验 |
| jQuery 冗余依赖 | 1 处 | 中 | 仅为 Colorbox 一个函数加载整个 jQuery |
- 联系页只展示联系方式、营业时间和地图导航。
- 不注册前端提交处理、邮件发送、成功/失败状态或防重放字段。
- 服务入口统一跳转 `/contact/`,不拼接服务查询参数。
- 旧的附加查询参数不会影响页面访问,但主题不消费它。
---
### 前端依赖
## 阶段一:死代码删除(零风险)
- Bootstrap 5.3.8 固定在 `assets/vendor/bootstrap/`,包含 CSS、bundle JS 和许可证。
- `theme.js` 使用原生 DOM API。
- 外部视频只在新标签页打开,不解析视频域名、不生成 iframe。
- 字体使用系统英文/中文字体栈。
- 删除无消费者的通用重置包、弹窗样式与脚本聚合文件。
> 删除后不影响任何已上线页面。每步删完刷新全站确认无报错。
### 数据与初始化
### 1.1 删除 7 个死模板文件
- 初始化由 `fragrance_trade_schema_version` 控制。
- 7 个默认服务来自 `fragrance_trade_service_seeds()`,种子标识写入 `_fragrance_seed_key`
- 写入失败会记录后台错误,当前迁移版本不会推进。
- 约定页面会复用已有内容和状态,只补齐页面模板。
- 用户已有的非发布页面不会被自动发布或恢复。
- 旧产品外观设置仅在旧站迁移时读取。
| 文件 | 原用途 | 替代方案 |
|------|--------|----------|
| `template-parts/home/products.php` | 旧 B2B 产品展示 | 已被 CPT `service` + `service-teaser.php` 替代 |
| `template-parts/home/services.php` | 旧服务总览 | 已被 `service-teaser.php` 替代 |
| `template-parts/home/quality.php` | 旧质检流程 | 首页不再展示,内容可在关于页补充 |
| `template-parts/home/process.php` | 旧施工流程 | 首页不再展示 |
| `template-parts/home/projects.php` | 旧项目案例 | 已被 CPT `case` + `case-teaser.php` 替代 |
| `template-parts/home/customization.php` | 旧定制服务 | 首页不再展示 |
| `template-parts/home/rfq.php` | 旧预约表单 | 联系页已改为联系方式卡片,无表单 |
### 资源与样式
**验证方法**:删除后逐页访问首页 / 关于 / FAQ / 联系页 / 服务列表 / 案例列表,确认无 500 错误、无模板缺失警告
- 删除 7 张未被模板引用的旧产品位图
- 删除未引用的 Logo 占位图。
- 保留汽车贴膜服务、门店、视频和案例的中性 SVG 占位图。
- 删除没有 PHP 或 JS 消费者的质量、流程、项目和定制板块配置与 CSS。
- 首页两个展示查询使用 `no_found_rows`
- 默认值数组在单次请求内缓存。
### 1.2 删除 13 个死图片资源
### 安全与直接访问
| 文件 | 说明 |
|------|------|
| `assets/images/main-logo.png` | 旧 logo,已用 `placeholder-logo.svg` + WP custom-logo |
| `assets/images/product-item1.jpg` | 旧产品图 ×3 |
| `assets/images/product-item2.jpg` | |
| `assets/images/product-item3.jpg` | |
| `assets/images/insta-item1.jpg` | 旧 Instagram 展示图 ×6 |
| `assets/images/insta-item2.jpg` | |
| `assets/images/insta-item3.jpg` | |
| `assets/images/insta-item4.jpg` | |
| `assets/images/insta-item5.jpg` | |
| `assets/images/insta-item6.jpg` | |
| `assets/images/single-image1.png` | 旧单图素材 |
| `assets/images/factory-workflow-illustration.webp` | 旧流程插图 |
- 所有主题 PHP 入口、模块和模板片段均检查 `ABSPATH`
- 输出 URL、属性、纯文本和富文本继续按上下文转义。
- 视频新窗口链接使用 `noopener noreferrer`
- 地图链接优先使用 `store_map_url`,否则仅根据非空地址生成。
**验证方法**:全项目 grep 这些文件名,确认零引用(已验证)。
## 保留的兼容接口
---
- 文本域:`fragrance-trade`
- PHP 函数前缀:`fragrance_trade_`
- CSS 前缀:`b2b-`
- 地图设置键:`store_map_url`
- 服务旧图片元数据:`_service_image`
- 旧安装识别选项:`fragrance_trade_setup_done`
## 阶段二:JS 依赖瘦身(中等风险)
这些标识符涉及已有站点数据或第三方定制,未经正式迁移方案不得全局改名或删除。
> 当前 plugins.js 拼接了 6 个库,但只有 Colorbox 真正在用。
> AOS 虽然在 theme.js 中初始化,但没有任何模板使用 `data-aos` 属性,属于空转。
## 后续资源替换原则
### 2.1 库使用情况核实
| 库 | plugins.js 中 | theme.js 调用 | 模板中使用 | 结论 |
|----|--------------|---------------|-----------|------|
| jQuery Easing | 有 | 无 | 无 | **删除** |
| Jarallax v2.0.2 | 有 | 无 | 无 | **删除** |
| Colorbox 1.6.4 | 有 | `$.fn.colorbox()` | `class="youtube"` 在 video.php | **保留** |
| AOS | 有 | `AOS.init()` | 无 `data-aos` 属性 | **删除** |
| anime.js | 有 | 无 | 无 | **删除** |
| HC-Sticky | 有 | 无 | 无 | **删除** |
### 2.2 操作步骤
**步骤 A — 清理 theme.js 中的 AOS 调用**
删除 `initAnimations()` 函数及其调用(第 19-22 行、第 42 行)。AOS 在空转,删了不影响任何可见效果。
**步骤 B — 重写 plugins.js**
将 plugins.js 从 6 库拼接缩减为仅保留 Colorbox 1.6.4(约 4KB)。其余 5 个库全部移除。
**步骤 C — 清理 vendor.css**
删除 vendor.css 中的 Jarallax 样式(第 6-36 行)和 AOS 样式(第 89 行至文件末尾的大段压缩 CSS)。仅保留 Colorbox 样式(第 39-85 行)。
**步骤 D — 评估 jQuery 去留**
Colorbox 依赖 jQuery。两个选项:
| 方案 | 改动量 | 效果 |
|------|--------|------|
| **A. 保留 jQuery**(推荐当前阶段) | 无 | 维持现状,Colorbox 正常工作 |
| B. 用原生 lightbox 替代 Colorbox | 中等 | 彻底去掉 jQuery 依赖,减少 ~90KB 加载 |
> 方案 B 需要找一个不依赖 jQuery 的 lightbox 库(如 GLightbox)并改写 theme.js 的 `initVideoLightbox()`。建议放到独立迭代中做,不在本次清理范围内。
**验证方法**
1. 打开关于门店页,点击施工视频缩略图,确认 Colorbox 弹窗正常弹出
2. 检查浏览器控制台无 JS 报错
3. 对比清理前后页面加载时间(预计减少 ~80KB JS 传输)
---
## 阶段三:死表单处理器处理(中等风险)
### 3.1 现状
`inc/inquiry.php` 注册了 `admin_post_fragrance_rfq``admin_post_nopriv_fragrance_rfq` 两个 hook,但联系页已无表单,这些 hook 永远不会被触发。
### 3.2 两个选项
| 方案 | 操作 | 理由 |
|------|------|------|
| **A. 保留但标注弃用**(推荐) | 在文件头加 `@deprecated` 注释,保留 hook 注册 | 未来可能恢复预约表单功能,代码本身安全合规,留着不碍事 |
| B. 完全删除 | 删除 inquiry.php + 从 functions.php 移除加载 | 彻底清理,但未来恢复需重写 |
> 推荐 Ainquiry.php 的安全实现(nonce + honeypot + 速率限制 + 邮件头注入防护)是项目中的优秀范例,删了可惜。标注弃用即可。
---
## 阶段四:CDN 安全加固(中等风险)
### 4.1 现状
`inc/setup.php` 第 47-54 行从 `cdn.bootcdn.net` 加载 Bootstrap CSS/JS,无 `integrity` 属性(SRI),无本地回退。如果 CDN 被劫持,攻击者可注入恶意代码。
### 4.2 操作步骤
**步骤 A — 添加 SRI 完整性校验**
为 Bootstrap CSS 和 JS 添加 `integrity` + `crossorigin` 属性。需要从 [BootCDN](https://www.bootcdn.cn/) 获取对应版本的 SRI 哈希。
```php
// 修改前
wp_enqueue_style( 'fragrance-bootstrap', 'https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/css/bootstrap.min.css', array(), '5.3.0-alpha3' );
// 修改后(需填入实际哈希)
wp_enqueue_style( 'fragrance-bootstrap', 'https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/css/bootstrap.min.css', array(), '5.3.0-alpha3' );
// WP 的 wp_enqueue_style 不直接支持 integrity,需用 style_loader_tag 过滤器追加属性
```
由于 WordPress 的 `wp_enqueue_*` 函数不直接支持 `integrity` / `crossorigin` 属性,需要通过 `style_loader_tag``script_loader_tag` 过滤器注入:
```php
// 在 inc/setup.php 中添加
function fragrance_trade_resource_integrity( $html, $handle ) {
$sri = array(
'fragrance-bootstrap' => 'sha384-XXXXX', // 替换为实际哈希
);
if ( isset( $sri[ $handle ] ) ) {
$html = str_replace( '/>', ' integrity="' . $sri[ $handle ] . '" crossorigin="anonymous" />', $html );
}
return $html;
}
add_filter( 'style_loader_tag', 'fragrance_trade_resource_integrity', 10, 2 );
```
> **注意**Google Fonts 不支持 SRI(动态生成 CSS),保持现状即可。
**步骤 B — 可选:本地回退**
将 Bootstrap 下载到 `assets/vendor/bootstrap/`,CDN 加载失败时自动回退。此步骤为可选项,当前 CDN 可用性已较高。
**验证方法**:浏览器 DevTools → Network → 确认 Bootstrap 资源加载请求携带 `integrity` 头。
---
## 阶段五:Customizer 配置清理(低风险)
### 5.1 现状
`inc/customizer.php` 中仍有大量为已删除模板配置的 Customizer 字段(products、services、quality、process、projects、customization 等)。这些字段在后台 Customizer 面板中可见但对应的模板已不存在,用户会困惑。
### 5.2 操作步骤
1. 逐个移除已删除模板对应的 Customizer section + 字段注册代码
2. 对应的 `inc/defaults.php` 默认值也一并清理
3. 保留仍在使用的 sectionhero、trust、store_info、contact_social、video、documents、faq
> **注意**:此阶段改动量大且涉及 Customizer 面板结构,建议在测试环境验证后再上线。
---
## 执行顺序与预估
| 阶段 | 内容 | 文件改动数 | 风险 | 建议优先级 |
|------|------|-----------|------|-----------|
| 一 | 删死模板 + 死图片 | 删 20 个文件 | 极低 | 立即执行 |
| 二 | JS 库瘦身 | 改 3 个文件 | 中 | 紧随其后 |
| 三 | 表单处理器标注 | 改 1 个文件 | 极低 | 随手做 |
| 四 | CDN SRI 加固 | 改 1 个文件 | 低 | 本周内 |
| 五 | Customizer 清理 | 改 2 个文件 | 中 | 下次迭代 |
---
## 每阶段完成后的检查清单
- [ ] 全站逐页访问无 500 / 404
- [ ] 浏览器控制台无 JS 报错
- [ ] WP Debug Log 无 PHP warning/notice
- [ ] Customizer 面板无残留无效 section
- [ ] Git 提交信息标注 `[cleanup]` + 阶段编号
- [ ] 推送到 Gitea 前本地验证通过
---
## 回滚方案
每个阶段独立提交,如果发现问题:
```bash
# 查看提交历史
git log --oneline
# 回退到指定提交
git revert <commit-hash>
```
阶段一和阶段二各自独立 commit,确保可单独回滚。
- 运营图片应通过特色图片或外观配置上传,不写入主题默认数据。
- 默认主题包只提供中性占位素材。
- 新前端依赖必须本地打包、记录版本与许可证,并经过无外部请求扫描。
- 开发验证工具不应作为主题运行依赖进入生产请求路径。
+99 -227
View File
@@ -1,266 +1,138 @@
# 代码审查标准与流程
# B2B Trade 发布审查标准
> 适用项目B2B Trade 主题(fragrance-trade
> 技术栈:WordPress 经典主题 / PHP 7.4+ / Bootstrap 5.3 / jQuery
> 版本:v1.0 | 2026-07-24
适用范围B2B Trade 2.1.xWordPress 6.8+PHP 8.1+。
---
## 1. 自动检查
## 一、审查原则
每次发布必须满足:
1. **安全优先** — WordPress 主题的 XSS / SQL 注入 / CSRF 是红线
2. **就事论事** — 评论针对代码,不针对人
3. **说清楚为什么** — 不只说"改这个",要解释原因和潜在风险
4. **给方向不给答案** — 引导作者自己思考,除非是明确的安全漏洞
5. **赞美好代码** — 发现优秀实践要明确指出,让团队学习
- `git diff --check` 无输出;
- 所有 PHP 文件在 PHP 8.1 CLI 下通过 `php -l`
- PHPCS 通过 WordPress Coding Standards 与 PHPCompatibilityWP
- `node --check assets/js/theme.js` 通过;
- CSS 花括号配对,所有 `url(...)` 本地资源存在;
- PHP、CSS 和 JS 不包含脚本、样式或字体 CDN 请求;
- 主题引用的本地静态资源全部存在;
- 仓库不包含已清退的旧业务词、旧视频弹窗库或旧产品位图。
---
## 2. 初始化与数据安全
## 二、优先级体系
每个审查意见必须标注以下级别之一:
| 级别 | 标记 | 含义 | 处理要求 |
|------|------|------|----------|
| 🔴 阻断 | Blocker | 安全漏洞 / 数据丢失 / 破坏功能 | **必须修复后才能合并** |
| 🟡 建议 | Suggestion | 输入验证缺失 / 性能问题 / 可维护性 | **应当修复,可协商** |
| 💭 细节 | Nit | 命名 / 风格 / 文档 | 修不修都行,不阻塞 |
---
在空数据库中:
## 三、WordPress 主题专项审查清单
1. 安装 WordPress 并激活主题;
2. 确认创建 7 个带种子标识的服务;
3. 确认创建 `home``about``faq``contact`
4. 再运行两次初始化;
5. 确认服务数和页面数不增加;
6. 确认 `fragrance_trade_schema_version` 仅在无错误时推进。
### 🔴 阻断级检查项(必须全部通过)
在已有数据库中:
#### 3.1 安全性
- 已有页面正文、标题和状态不被覆盖;
- 草稿、私密或回收站页面不被自动发布;
- 对应页面模板被补齐;
- 后台显示非发布状态提醒;
- 已有 `_service_image``store_map_url` 保持有效。
- [ ] **直接访问防护** — 所有 PHP 文件以 `if ( ! defined( 'ABSPATH' ) ) exit;` 开头
- [ ] **SQL 注入** — 禁止拼接 SQL;必须使用 `$wpdb->prepare()` 或 WP API`get_posts()`, `WP_Query`
- [ ] **XSS 防护** — 所有输出必须经过转义:
- HTML 文本 → `esc_html()`
- URL → `esc_url()`
- 属性 → `esc_attr()`
- 富文本 → `wp_kses_post()`
- [ ] **CSRF 防护** — 所有表单提交 / POST 处理必须有 `wp_nonce_field()` + `check_admin_referer()`
- [ ] **输入净化** — 所有 `$_POST` / `$_GET` / `$_SERVER` 必须用 `wp_unslash()` + 对应 `sanitize_*` 函数
- [ ] **邮件头注入** — 从用户输入构造邮件头时,必须剥离 `\r\n`
- [ ] **文件包含** — 禁止用户输入直接传入 `include` / `require` / `get_template_part()`
- [ ] **权限检查** — 任何管理员操作必须有 `current_user_can()` 检查
#### 3.2 功能正确性
需要注入一次 `wp_insert_post()` 错误,确认错误被记录、管理员可见且迁移版本不推进。
- [ ] **关键路径错误处理** — 表单提交失败有 fallback(非空白白屏)
- [ ] **数据完整性** — 不会因空值 / 缺失字段导致 fatal error
- [ ] **重定向安全** — 使用 `wp_safe_redirect()` + `wp_validate_redirect()`,禁止直接 `header('Location:')`
## 3. 页面冒烟
### 🟡 建议级检查项
以下页面必须返回预期状态,并且 PHP 日志无 Warning、Deprecated、Parse 或 Fatal
#### 3.3 输入验证与数据
| 页面 | 预期 |
| --- | --- |
| 首页 | 200 |
| 服务列表 | 200 |
| 服务详情 | 200 |
| 案例列表 | 200 |
| 案例详情 | 200 |
| 关于门店 | 200 |
| 常见问题 | 200 |
| 联系我们 | 200 |
| 普通文章 | 200 |
| 搜索结果 | 200 |
| 不存在路径 | 404 |
- [ ] Customizer 字段是否有对应类型的 `sanitize_callback`
- [ ] `get_theme_mod()` 取值后是否有默认值兜底
- [ ] 用户上传的 URL 是否用 `esc_url_raw()` 存入、`esc_url()` 输出
浏览器控制台不得出现 JavaScript 错误,Network 面板不得出现主题资源 404。
#### 3.4 性能
## 4. 业务分支
- [ ] **N+1 查询** — 循环内不执行数据库查询,提前预取
- [ ] **资源加载** — 脚本用 `wp_enqueue_script`,不硬编码 `<script src>`
- [ ] **图片优化** — 使用响应式 `srcset` / `loading="lazy"`
- [ ] **Transient 缓存** — 耗时操作(远程请求、复杂查询)用 transient 缓存
### 服务图片
#### 3.5 可维护性
分别构造并确认:
- [ ] **死代码** — 新增模板文件必须有对应的 `get_template_part()` 调用;废弃文件及时删除
- [ ] **命名规范** — 函数 / 变量统一 `fragrance_trade_` 前缀,蛇形命名
- [ ] **函数长度** — 单函数不超过 80 行,超过则考虑拆分
- [ ] **重复代码** — 相同逻辑出现 3 次以上应提取为 helper 函数
- [ ] **文件组织** — 新功能按职责归入 `inc/` 对应模块,不堆在 `functions.php`
1. 有特色图片时优先显示特色图片;
2. 无特色图片、有 `_service_image` 时显示旧 URL
3. 两者都没有时显示对应 SVG 占位图;
4. 首页和列表输出 `fragrance-capability`
5. 详情输出 `large`
#### 3.6 前端质量
### 地图
- [ ] **CDN 资源** — 第三方 CDN 必须有 SRI 完整性哈希 + 本地回退
- [ ] **第三方库** — 禁止将多个库的压缩代码拼接到单文件;用 npm + 构建流程管理
- [ ] **无障碍** — 图片有 `alt`,表单有 `label`,按钮有可读文本
- [ ] **响应式** — 移动端布局不溢出,触控目标不小于 44×44px
- [ ] `prefers-reduced-motion` — 动画尊重用户偏好
分别确认:
### 💭 细节级检查项
1. 显式地图 URL 优先于地址;
2. 只有地址时生成百度地图导航;
3. 地址和 URL 都为空时不渲染地图卡片;
4. 页面不出现任何硬编码门店地址。
- [ ] 文本域统一为 `fragrance-trade`,所有字符串包裹 `__()` / `esc_html_e()`
- [ ] 注释说明"为什么"而非"做了什么"
- [ ] 长行拆分(单行 PHP echo 不超过 120 字符)
- [ ] CSS 自定义属性命名遵循 `--token-name` 格式
### 导航
---
- 未分配菜单时输出 6 项默认导航;
- 少于两个菜单项时后台显示提醒;
- 桌面导航与移动 Offcanvas 均可键盘操作;
- 当前菜单不会造成横向滚动。
## 四、审查流程
### 视频与 FAQ
```
┌─────────────────────────────────────────────────────────────┐
│ 代码审查流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 提交前自检 │
│ 作者按 §三 清单自检 → 确认无 🔴 项 │
│ ↓ │
│ 2. 提交审查 │
│ Gitea PR / 提交说明 → 附上改动摘要和测试方式 │
│ ↓ │
│ 3. 审查者检查 │
│ 按 §三 清单逐项 → 标注 🔴🟡💭 → 写明原因和建议方向 │
│ ↓ │
│ 4. 分支处理 │
│ ├─ 有 🔴 → 打回,作者修复后重新提交 │
│ ├─ 有 🟡 → 讨论确认,修复或记录为后续任务 │
│ └─ 仅 💭 → 可选修复,直接通过 │
│ ↓ │
│ 5. 合并 │
│ 审查者 Approve → 作者合并 → 删除分支 │
│ ↓ │
│ 6. 回顾(每周) │
│ 汇总本周审查发现的共性问题 → 更新本标准 │
│ │
└─────────────────────────────────────────────────────────────┘
```
- 有视频 URL 时只产生普通新窗口链接;
- 链接包含 `target="_blank"``rel="noopener noreferrer"`
- 无视频 URL 时显示联系门店入口;
- FAQ 手风琴可点击和键盘操作,ARIA 状态随展开更新。
### 4.1 提交规范
### 联系
提交 PR / 提交审查时,标题格式:
- 联系页不存在提交表单;
- 服务入口不生成服务查询参数;
- 电话、邮箱与 WhatsApp 链接按配置显示;
- 主题不注册前端提交或邮件发送 Hook。
```
[类型] 简述 — 具体改动
## 5. 兼容矩阵
类型:feat / fix / refactor / style / security / docs / chore
```
至少完成:
示例:
```
[security] RFQ 表单 — 增加 nonce 验证
[feat] 案例详情页 — 添加施工前后对比图
[refactor] inc/defaults.php — 按区块分组重组配置键
```
| 环境 | 用途 |
| --- | --- |
| WordPress 7.0 系列 + PHP 8.3 | 当前版本主回归 |
| WordPress 6.8 系列 + PHP 8.2 | 最低 WordPress 分支 |
| PHP 8.1 CLI | 最低 PHP 语法检查 |
### 4.2 审查时间线
兼容环境可由维护者现有的 WordPress 测试站点提供,不要求主题仓库附带容器配置。
| 阶段 | 时限 | 说明 |
|------|------|------|
| 初次审查 | 提交后 24h 内 | 审查者完成首轮检查 |
| 修复后复审 | 作者修复后 12h 内 | 审查者确认修复 |
| 超时升级 | 超 48h 未回应 | @项目负责人介入协调 |
## 6. 视觉与无障碍
---
桌面至少检查 1440 × 1000,移动至少检查 390 × 844
## 五、审查评论模板
- 首页、服务列表、服务详情、案例列表、关于、FAQ、联系;
- 无水平滚动、布局跳动、遮挡或断裂;
- 图片具有明确尺寸与替代文本;
- 可交互元素有可见焦点;
- 文本与背景保持可读对比度;
- Offcanvas 打开后焦点可进入,关闭后可返回触发按钮;
- 新窗口链接的可访问名称能表达用途。
### 🔴 阻断级
主题预览图必须来自通过桌面验收的中性演示首页,不得包含过时业务内容、品牌承诺或虚构真实门店照片。
```
🔴 [安全/XSS] 第 42 行:用户输入直接输出到 HTML
## 7. 发布元数据
原因
$subtitle 变量来自 $_POST,未经 esc_html() 转义直接 echo
攻击者可注入 <script> 标签执行任意代码。
发布前确认 `style.css`
建议:
echo esc_html( $subtitle );
```
- `Version: 2.1.0`
- `Requires at least: 6.8`
- `Tested up to: 7.0`
- `Requires PHP: 8.1`
- Theme URI 指向实际仓库
- 文本域为 `fragrance-trade`
### 🟡 建议级
```
🟡 [性能/N+1] 第 18-25 行:循环内执行 get_post_meta()
原因:
在 while 循环内逐条查询 post_meta10 篇文章 = 10 次查询,
页面加载时会明显变慢。
建议:
循环前用 get_post_meta( $post_ids, 'key', false ) 批量预取,
或在循环内缓存结果。
```
### 💭 细节级
```
💭 [命名] 第 8 行:$d 变量名过于简短
考虑改为 $display_date 或 $post_date6 个月后回来看能秒懂。
```
---
## 六、当前项目待修复清单
基于 2026-07-24 代码扫描结果,以下问题应优先处理:
| 优先级 | 问题 | 文件 | 说明 |
|--------|------|------|------|
| 🟡 | 11 个死模板文件 | template-parts/home/ | products, services, quality, process, faq, rfq, factory, video, customization, documents, projects 未被引用 |
| 🟡 | plugins.js 拼接 6 个库 | assets/js/plugins.js | jQuery Easing + Jarallax + Colorbox + AOS + anime.js + HC-Sticky 混在一起,无版本标记,无法维护 |
| 🟡 | CDN 无 SRI | inc/setup.php:47-54 | Bootstrap + Google Fonts 缺少 integrity 哈希,无本地回退 |
| 🟡 | 零测试 | 全项目 | 无 phpunit / 无 .phpcs.xml / 无 CI |
| 💭 | defaults.php 扁平数组 | inc/defaults.php | ~170 个键未分组,可按区块拆分 |
| 💭 | jQuery 冗余依赖 | assets/js/theme.js | 仅 colorbox 用 jQuery,其余为原生 DOM,可考虑去掉 jQuery |
---
## 七、工具辅助
### 静态检查(建议引入)
```bash
# PHP 代码规范检查 — WordPress 标准
composer create-project wp-coding-standards/wpcs
phpcs --standard=WordPress --extensions=php inc/ template-parts/
# 自动修复可修复的问题
phpcbf --standard=WordPress --extensions=php inc/ template-parts/
```
### Git Pre-commit Hook(建议配置)
```bash
#!/bin/bash
# .git/hooks/pre-commit
# 提交前自动检查 PHP 语法 + 基本安全扫描
ERRORS=0
# 1. PHP 语法检查
for file in $(git diff --cached --name-only --diff-filter=ACM | grep "\.php$"); do
php -l "$file" > /dev/null 2>&1 || { echo "语法错误: $file"; ERRORS=1; }
done
# 2. 检查是否包含危险函数
for file in $(git diff --cached --name-only --diff-filter=ACM | grep "\.php$"); do
grep -n 'eval\s*(' "$file" && { echo "⚠️ eval() 检测到: $file"; ERRORS=1; }
grep -n 'exec\s*(' "$file" && { echo "⚠️ exec() 检测到: $file"; ERRORS=1; }
grep -n 'system\s*(' "$file" && { echo "⚠️ system() 检测到: $file"; ERRORS=1; }
done
exit $ERRORS
```
---
## 八、审查者轮值
| 角色 | 职责 |
|------|------|
| 主审 | 按 §三 清单逐项检查,出具审查意见 |
| 复审 | 对主审意见复核,确认无遗漏(可选) |
| 作者 | 回复意见,修复 🔴🟡 项,说明 💭 项处理决定 |
> 小团队(≤3人)可轮流担任主审,无需固定复审。
---
## 附录:本项目已有的优秀实践(请保持)
- ✅ 所有文件 `ABSPATH` 守卫
- ✅ RFQ 表单完整安全链:nonce + honeypot + 速率限制 + 邮件头注入防护
- ✅ Customizer 字段全部配置 `sanitize_callback`
- ✅ 统一 `fragrance_trade_` 函数前缀
- ✅ CSS 使用自定义属性设计令牌系统
- ✅ JS 尊重 `prefers-reduced-motion` + passive 事件监听
-`antispambot()` 邮件地址混淆
同时确认 `languages/fragrance-trade.pot` 已按当前源码重新生成,本地 Bootstrap 许可证随主题包发布。
+83 -177
View File
@@ -1,193 +1,99 @@
# B2B Trade — 汽车贴膜门店 WordPress 主题
# B2B Trade
专业汽车贴膜门店(面向终端车主)的经典 WordPress 主题。支持服务项目展示、施工案例作品集、在线预约联系,适配移动端
B2B Trade 是一个面向汽车贴膜门店的 WordPress 经典主题。主题提供服务项目、施工案例、门店介绍、常见问题和联系方式;联系页只展示电话、邮箱、WhatsApp、营业时间与地图导航,不包含提交表单、邮件发送处理器或 SMTP 依赖
## 项目说明
## 运行要求
本主题面向汽车贴膜门店(TPU 保护膜 / 彩色改色膜 / 隔热防爆膜等),不是 B2B 代工厂模板。站点采用多页面架构 + 自定义文章类型,首页为落地页,引导车主浏览服务、查看案例并预约到店。
- WordPress 6.8 或更高版本
- PHP 8.1 或更高版本
- 当前发布版:2.1.0
- 已针对 WordPress 7.0 系列配置回归环境
> 仓库名 `fragrance-trade` 为历史遗留(原是香水贸易模板),代码标识符(文本域 `fragrance-trade`、CSS 前缀 `fragrance-`、PHP 函数前缀 `fragrance_trade_`)保持不变,不影响功能
前端依赖仅包含主题内置的 Bootstrap 5.3.8 CSS 和 bundle JS。字体使用操作系统字体栈,不会向字体、脚本或样式 CDN 发起请求
## 环境要求
## 页面与内容结构
- WordPress 6.5+
- PHP 7.4+
- 生产环境建议使用 HTTPS 和认证 SMTP
首页固定显示 5 个板块:
1. 首屏定位与双按钮
2. 四项信任指标
3. 服务项目(最多 6 项)
4. 案例作品(最多 6 项)
5. 联系门店行动区
关于页承载门店介绍、信任指标、环境图片、外部视频链接和服务文档。FAQ 页复用 8 项手风琴内容;联系页按配置展示门店信息和地图卡片。
主题注册:
- `service` 服务项目文章类型,归档路径 `/services/`
- `case` 案例文章类型,归档路径 `/cases/`
- `case_type` 案例分类法
- `fragrance-capability` 图片尺寸(760 × 720,硬裁切)
服务图片的显示优先级为:
1. WordPress 特色图片
2. 旧站点的 `_service_image` URL
3. 主题内置的中性 SVG 占位图
列表和首页使用 `fragrance-capability`,详情页使用 `large`
## 首次激活
激活主题后会运行版本化且可重试的初始化:
- 创建 7 个默认服务,并使用 `_fragrance_seed_key` 防止重复;
- 创建或复用 `home``about``faq``contact` 页面;
- 为约定页面补齐模板,但不修改已有正文;
- 不会自动发布或恢复用户已有的草稿、私密页或回收站页面;
- 将已发布的 `home` 设置为静态首页;
- 仅在数据库写入全部成功后推进 `fragrance_trade_schema_version`
重复激活和重复执行初始化不会增加服务或页面数量。失败信息和未发布页面状态会在后台显示管理员通知。
未分配主导航时,主题输出:首页、服务项目、案例作品、关于门店、常见问题、联系我们。已分配菜单但少于两个菜单项时,后台同样会提醒。
## 外观配置
“外观 → 自定义 → 门店首页”包含 6 个配置板块:
- 首屏定位
- 信任栏
- 门店环境与参观
- 文档支持
- 常见问题
- 联系方式与社交链接
视频链接不会嵌入页面或打开弹窗;配置后会在新标签页直接打开,并带有 `noopener noreferrer`
地图卡片按以下顺序决定是否显示:
1. 优先使用“地图导航链接”;
2. 没有显式链接但门店地址非空时,生成百度地图导航地址;
3. 两项都为空时,隐藏地图卡片。
Hero 按钮的站内默认路径会通过 `home_url()` 解析,支持 WordPress 子目录安装与多站点路径。
## 安装
1. `fragrance-trade` 文件夹复制到 `wp-content/themes/`
2. **外观 → 主题** 中激活 **B2B Trade**
3. 主题激活时自动完成初始化:
- 注册 `service`(服务项目)和 `case`(案例作品)两个自定义文章类型
- 将 Customizer 中的 7 个产品数据迁移为 `service` 文章
- 自动创建首页、关于门店、常见问题、预约/联系四个页面
- 将首页设置为静态首页
4. **重要:** 激活后进入 **设置 → 固定链接**,点击"保存更改"刷新路由规则。
5.**外观 → 自定义 → 站点身份** 中设置站点标题和 Logo。
6.**外观 → 菜单** 中创建导航菜单并分配到 **主导航**
7. 打开 **外观 → 自定义 → 门店首页**,将所有演示文案替换为真实门店信息。
1.主题目录复制到 WordPress 的 `wp-content/themes/`
2.外观 → 主题中激活 B2B Trade。
3. 在“外观 → 菜单”中创建并分配主导航;未分配时主题会显示默认导航。
4. 在“外观 → 自定义 → 门店首页”中填写真实门店信息。
5. 在服务项目和案例后台上传实际图片与内容。
## 站点架构
发布前应在 WordPress 6.8 或更高版本、PHP 8.1 或更高版本环境中检查首页、列表、详情、关于、FAQ、联系、搜索与 404 页面,并确认桌面和移动端没有资源 404、控制台错误或横向滚动。
### 页面结构
详细验收项见 `CODE_REVIEW_STANDARD.md`,清理范围与兼容策略见 `CODE_CLEANUP_PLAN.md`
| 页面 | 模板 | 说明 |
|------|------|------|
| 首页 | `front-page.php` | 落地页:Hero + 信任栏 + 服务项目预览 + 案例预览 + CTA |
| 服务项目列表 | `archive-service.php` | 展示全部服务项目(膜品) |
| 服务项目详情 | `single-service.php` | 单个膜品详情 |
| 案例作品列表 | `archive-case.php` | 施工案例作品集,支持按分类筛选 |
| 案例详情 | `single-case.php` | 单个施工案例 |
| 关于门店 | `page-about.php` | 门店介绍、环境展示、视频、服务保障 |
| 常见问题 | `page-faq.php` | FAQ 手风琴 |
| 预约/联系 | `page-contact.php` | 门店信息 + 联系方式 + 百度地图导航 |
## 数据兼容
### 首页板块(5 个模板片段)
`front-page.php` 组装以下片段(来自 `template-parts/home/`):
1. `hero` — 首屏定位与行动按钮
2. `trust` — 信任栏(4 个证明点)
3. `service-teaser` — 服务项目预览(从 `service` CPT 读取最新 3 条)
4. `case-teaser` — 案例预览(从 `case` CPT 读取最新 3 条)
5. `cta` — 行动召唤板块
### 自定义文章类型
| CPT | 功能 | URL |
|-----|------|-----|
| `service` | 服务项目 / 膜品(TPU保护膜、彩色改色膜、隔热防爆膜等) | `/services/` |
| `case` | 施工案例作品集 | `/cases/` |
| `case_type` | 案例分类(taxonomy,挂在 `case` 上) | `/case-type/` |
主题激活时自动将 Customizer 中的 7 个产品数据迁移为 `service` 文章。
### 面包屑导航
`template-parts/breadcrumb.php` 提供可复用的面包屑组件,接受 `$args['items']` 数组(每项含 `label` 和可选 `url`)。在服务详情、案例详情等内页中调用以展示层级导航路径。
## 自定义器(Customizer
**门店首页** 面板包含以下板块:
- 首屏定位(眉标、主标题、简介、双按钮)
- 信任栏(4 个证明点)
- 服务项目(4 张服务卡片)
- 产品能力(7 个产品参考卡片及图片)
- 定制选项(8 个定制项)
- 门店环境与参观(简介、4 张门店图片、视频链接)
- 品质管控(6 个品质步骤)
- 项目流程(8 个流程步骤)
- 项目案例(3 个案例,可开关显示)
- 文档支持(4 个文档卡片,可开关显示)
- 常见问题(8 条 FAQ,可开关显示)
- 预约表单(标题、简介、按钮文字)
- 联系方式与社交链接(收件邮箱、WhatsApp、门店地址、电话、营业时间、地图嵌入、社交媒体链接)
> 注:首页仅使用 5 个板块。其余板块(产品能力、定制选项、品质管控等)保留为 Customizer 配置源,同时 `service` CPT 激活时从这些配置迁移数据。
## 前端技术栈
- **Bootstrap 5.3**CDN):响应式栅格、offcanvas 移动导航、手风琴、表单控件
- **Colorbox**:图片灯箱(jQuery 依赖)
- **Google Fonts**`fonts.loli.net` 镜像):Josefin Sans + Jost + Noto Sans SC(思源黑体)
- **jQuery**:由 WordPress 提供,主题不另行打包
- CSS/JS 使用 `filemtime()` 版本号防缓存
- **CDN SRI**Bootstrap CSS/JS 加载时携带 `integrity` 完整性哈希和 `crossorigin` 属性,防止 CDN 劫持
## 安全措施
- 所有 PHP 文件以 `ABSPATH` 守卫开头
- 所有输出经 `esc_html()` / `esc_url()` / `esc_attr()` 转义
- Customizer 字段全部配置 `sanitize_callback`
- RFQ 表单处理器含完整安全链:nonce 验证 + 蜜罐 + 速率限制 + 邮件头注入防护
- 邮箱地址用 `antispambot()` 混淆
- CDN 资源携带 SRI 完整性校验
## 文件结构
```
fragrance-trade/
├── functions.php # 加载 6 个 inc/ 模块
├── front-page.php # 首页(5 个模板片段)
├── header.php # 导航栏 + offcanvas 移动导航
├── footer.php # 页脚 + 联系/社交链接
├── style.css # 主题信息头 + 基础样式
├── archive-service.php # 服务项目列表
├── single-service.php # 服务项目详情
├── archive-case.php # 案例列表(支持分类筛选)
├── single-case.php # 案例详情
├── page-about.php # 关于门店
├── page-faq.php # 常见问题
├── page-contact.php # 预约/联系
├── index.php / single.php / page.php / archive.php / 404.php
├── inc/
│ ├── defaults.php # 全中文安全默认值
│ ├── setup.php # 主题初始化、资源加载、SRI 加固
│ ├── helpers.php # 工具函数(菜单回退、WhatsApp/邮件链接、通知)
│ ├── cpt.php # 自定义文章类型注册 + 激活迁移
│ ├── customizer.php # Customizer 面板和字段
│ └── inquiry.php # 预约表单处理器
├── template-parts/
│ ├── home/ # 首页片段(hero/trust/service-teaser/case-teaser/cta + video/factory/documents/faq
│ ├── breadcrumb.php # 可复用面包屑导航组件
│ ├── content.php / content-page.php / content-none.php
├── assets/
│ ├── css/ # normalize.css + vendor.css + theme.css
│ ├── js/ # theme.js + plugins.js
│ └── images/ # SVG 占位图 + 产品/门店图片
├── CODE_CLEANUP_PLAN.md # 代码清理方案(5 阶段)
├── CODE_REVIEW_STANDARD.md # 代码审查标准与流程
└── languages/ # 翻译文件目录
```
## 占位资源
主题附带以下占位资源,上线前请替换为真实素材:
- 7 个产品 SVG 占位图(灰底虚线边框 + 中文标签)
- 7 个产品 webp 图片
- 4 个门店环境 SVG 占位图
- 1 个视频封面 SVG
- 1 个 Logo SVG
> 旧版图片素材(jpg 产品图、Instagram 图、工厂流程图等)已在代码清理中移除。
## 代码质量
### 代码清理
详见 [CODE_CLEANUP_PLAN.md](CODE_CLEANUP_PLAN.md),分 5 个阶段:
| 阶段 | 内容 | 状态 |
|------|------|------|
| 一 | 删除死模板 + 死图片 | ✅ 已完成 |
| 二 | JS 依赖瘦身 | 待执行 |
| 三 | 死表单处理器处理 | 待执行 |
| 四 | CDN SRI 加固 | ✅ 已完成 |
| 五 | Customizer 配置清理 | 待执行 |
### 代码审查
详见 [CODE_REVIEW_STANDARD.md](CODE_REVIEW_STANDARD.md),包含 WordPress 主题专项审查清单(安全/功能/性能/可维护性/前端质量)、优先级体系(🔴阻断 / 🟡建议 / 💭细节)和审查流程。
## 上线检查清单
1. 在 Customizer 中将所有演示文案替换为真实门店信息
2. 替换所有 SVG 占位图为实拍照片
3. 配置认证 SMTP 或事务性邮件插件
4. 测试预约表单提交、无效邮箱、重复提交
5. 检查移动端无水平滚动
6. 验证固定链接路由(`/services/``/cases/``/about/``/faq/``/contact/`
7. 确认导航菜单链接正确
8. 测试键盘焦点、跳转链接、图片替代文本等无障碍项
## Git 仓库
- **远程仓库**http://git.xgouo.cn/zhs123/car-t-t.git
- **分支**main
- 保留 `fragrance-trade` 文本域和 `fragrance_trade_*` 函数前缀。
- 保留 `store_map_url` 设置键。
- 保留 `_service_image` 只读回退,不自动改写或删除旧元数据。
- 旧的 `fragrance_trade_setup_done` 仅用于识别已有安装;新的流程以 `fragrance_trade_schema_version` 为准。
- 旧的联系页 URL 即使带有额外查询参数也能打开,但主题不再生成、读取、显示或传递服务名称。
## 许可证
GNU General Public License v2 or later。打包的第三方前端资源保留其各自许可证
主题按 GNU GPL v2 或更高版本发布。Bootstrap 5.3.8 的 MIT 许可证副本位于 `assets/vendor/bootstrap/LICENSE`
+7 -3
View File
@@ -4,6 +4,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main">
@@ -22,7 +26,7 @@ get_header();
?>
<header class="page-header pb-5">
<h1><?php esc_html_e( '案例作品', 'fragrance-trade' ); ?></h1>
<p><?php esc_html_e( '看看我们为车主完成的贴膜施工案例。', 'fragrance-trade' ); ?></p>
<p><?php esc_html_e( '浏览不同车型与项目的施工记录。实际效果会受膜料、车漆、光线和拍摄条件影响。', 'fragrance-trade' ); ?></p>
</header>
<div class="pb-5">
<?php
@@ -50,7 +54,7 @@ get_header();
<?php if ( has_post_thumbnail() ) : ?>
<?php the_post_thumbnail( 'medium', array( 'class' => 'img-fluid' ) ); ?>
<?php else : ?>
<img src="<?php echo esc_url( fragrance_trade_asset_uri( 'products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid">
<img src="<?php echo esc_url( fragrance_trade_asset_uri( 'images/products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid">
<?php endif; ?>
<span class="case-card-title"><?php the_title(); ?></span>
</a>
@@ -58,7 +62,7 @@ get_header();
</div>
<?php the_posts_pagination(); ?>
<?php else : ?>
<p><?php esc_html_e( '案例即将上线,敬请期待。', 'fragrance-trade' ); ?></p>
<p><?php esc_html_e( '案例内容正在整理中。', 'fragrance-trade' ); ?></p>
<?php endif; ?>
</div>
</div>
+8 -5
View File
@@ -4,6 +4,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main">
@@ -22,22 +26,21 @@ get_header();
?>
<header class="page-header pb-5">
<h1><?php esc_html_e( '服务项目', 'fragrance-trade' ); ?></h1>
<p><?php esc_html_e( '我们为各类车型提供专业贴膜施工服务,按需定制。', 'fragrance-trade' ); ?></p>
<p><?php esc_html_e( '从车漆保护、外观改色到车窗隔热,按车型与使用需求查看可选项目。', 'fragrance-trade' ); ?></p>
</header>
<div class="pb-5">
<div class="capability-grid">
<?php while ( have_posts() ) : the_post(); ?>
<?php
$image = get_post_meta( get_the_ID(), '_service_image', true );
$img = $image ? $image : fragrance_trade_asset_uri( 'products/placeholder-01.svg' );
$image = get_post_meta( get_the_ID(), '_service_image', true );
?>
<article class="capability-card">
<div class="capability-image"><a href="<?php the_permalink(); ?>"><img src="<?php echo esc_url( $img ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid" loading="lazy"></a></div>
<div class="capability-image"><a href="<?php the_permalink(); ?>"><?php if ( has_post_thumbnail() ) : ?><?php the_post_thumbnail( 'fragrance-capability', array( 'class' => 'img-fluid', 'loading' => 'lazy', 'decoding' => 'async' ) ); ?><?php else : ?><img src="<?php echo esc_url( $image ? $image : fragrance_trade_asset_uri( 'images/products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid" loading="lazy" decoding="async"><?php endif; ?></a></div>
<div class="capability-body">
<p class="capability-label"><?php esc_html_e( '贴膜服务', 'fragrance-trade' ); ?></p>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p><?php echo esc_html( get_the_excerpt() ); ?></p>
<a href="<?php echo esc_url( home_url( '/contact/?service=' . rawurlencode( get_the_title() ) ) ); ?>" class="btn btn-b2b-outline"><?php esc_html_e( '预约', 'fragrance-trade' ); ?></a>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-outline"><?php esc_html_e( '联系门店', 'fragrance-trade' ); ?></a>
</div>
</article>
<?php endwhile; ?>
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Archive template. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main container py-5 fragrance-content-area">
-355
View File
File diff suppressed because one or more lines are too long
+14 -276
View File
@@ -1,5 +1,5 @@
/* ============================================================
Fragrance Trade v3.0 — Minimalist Luxury Design System
B2B Trade v2.1.0 — Minimalist Store Design System
汽车贴膜门店 · 极简高级感 · 黑白灰单色体系
============================================================
Design Philosophy:
@@ -33,6 +33,10 @@
--b2b-shadow-sm: 0 1px 0 0 rgba(28, 28, 26, 0.04);
--b2b-shadow-md: 0 2px 8px rgba(28, 28, 26, 0.06);
--b2b-shadow-lg: 0 8px 32px rgba(28, 28, 26, 0.08);
/* Local system stacks — never trigger external font requests */
--b2b-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", Arial, sans-serif;
--b2b-font-display: Georgia, "Times New Roman", "Songti SC", "SimSun", serif;
}
/* ---- Reset & Base ---- */
@@ -46,7 +50,7 @@ body {
margin: 0;
color: var(--b2b-ink-soft);
background: var(--b2b-surface);
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: 1rem;
font-weight: 400;
line-height: 1.7;
@@ -60,7 +64,7 @@ body {
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
color: var(--b2b-ink);
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-weight: 400;
line-height: 1.15;
letter-spacing: -0.02em;
@@ -146,7 +150,7 @@ img {
gap: 0.5rem;
padding: 0.875rem 1.75rem;
border-radius: 0;
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: 0.8rem;
font-weight: 500;
letter-spacing: 0.08em;
@@ -272,7 +276,7 @@ img {
.b2b-wordmark {
color: var(--b2b-ink);
font-family: "Josefin Sans", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-display);
font-size: 1.35rem;
font-weight: 400;
letter-spacing: 0.1em;
@@ -341,7 +345,7 @@ img {
.b2b-hero h1 {
max-width: 780px;
margin-bottom: 1.75rem;
font-family: "Josefin Sans", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-display);
font-size: clamp(2.8rem, 6vw, 5.2rem);
font-weight: 300;
letter-spacing: -0.03em;
@@ -406,7 +410,7 @@ img {
.trust-metric strong {
margin-bottom: 0.5rem;
color: var(--b2b-surface);
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: clamp(1.3rem, 2.2vw, 1.8rem);
font-weight: 400;
}
@@ -547,7 +551,7 @@ img {
bottom: 0;
padding: 1.5rem 1.25rem;
color: var(--b2b-surface);
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: 1.1rem;
font-weight: 400;
letter-spacing: 0.02em;
@@ -611,7 +615,7 @@ img {
color: var(--b2b-ink);
background: transparent;
box-shadow: none;
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: 1.1rem;
font-weight: 400;
}
@@ -631,247 +635,6 @@ img {
color: var(--b2b-ink-soft);
}
/* ---- RFQ / Contact Form ---- */
.rfq-section {
background: var(--b2b-mist);
}
.rfq-direct {
margin-top: 2.5rem;
padding: 1.5rem;
background: var(--b2b-surface);
border-left: 2px solid var(--b2b-ink);
}
.rfq-direct h3 {
font-size: 1.05rem;
margin-bottom: 0.5rem;
}
.rfq-form-card {
padding: 2rem;
background: var(--b2b-surface);
border: 1px solid var(--b2b-line);
}
.rfq-form-card label {
display: block;
margin-bottom: 0.4rem;
color: var(--b2b-ink);
font-size: 0.8rem;
font-weight: 500;
letter-spacing: 0.04em;
}
.rfq-form-card .form-control,
.rfq-form-card .form-select {
min-height: 46px;
padding: 0.625rem 0.875rem;
color: var(--b2b-ink);
background-color: var(--b2b-surface);
border: 1px solid var(--b2b-line);
border-radius: 0;
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-size: 0.95rem;
transition: border-color 180ms ease;
}
.rfq-form-card textarea.form-control {
min-height: auto;
}
.rfq-form-card .form-control:focus,
.rfq-form-card .form-select:focus {
border-color: var(--b2b-ink);
box-shadow: none;
outline: none;
}
.rfq-form-card .form-control::placeholder {
color: var(--b2b-ink-muted);
}
.fragrance-form-status p {
margin-bottom: 1.5rem;
padding: 1rem 1.25rem;
color: var(--b2b-ink);
background: var(--b2b-mist);
border-left: 2px solid var(--b2b-ink);
}
.rfq-privacy-note {
margin: 1rem 0;
color: var(--b2b-ink-muted);
font-size: 0.78rem;
}
.fragrance-honeypot {
position: absolute !important;
left: -10000px !important;
width: 1px;
height: 1px;
overflow: hidden;
}
/* ---- Quality Grid ---- */
.quality-section {
background: var(--b2b-mist);
}
.quality-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1px;
background: var(--b2b-line);
}
.quality-card {
min-width: 0;
min-height: 240px;
padding: 2rem 1.75rem;
background: var(--b2b-mist);
}
.quality-number {
display: block;
margin-bottom: 2.5rem;
color: var(--b2b-ink-muted);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.1em;
}
.quality-card h3 {
margin-bottom: 0.75rem;
font-size: 1.15rem;
}
.quality-card p {
color: var(--b2b-ink-soft);
font-size: 0.95rem;
}
/* ---- Process Grid ---- */
.process-section {
background: var(--b2b-surface);
}
.process-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 1rem;
}
.process-step {
position: relative;
min-width: 0;
min-height: 250px;
padding: 1.75rem 1.5rem;
background: var(--b2b-elevated);
border-top: 2px solid var(--b2b-ink);
}
.process-step span {
display: block;
margin-bottom: 2rem;
color: var(--b2b-ink-muted);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.08em;
}
.process-step h3 {
margin-bottom: 0.75rem;
font-size: 1.15rem;
}
.process-step p {
color: var(--b2b-ink-soft);
font-size: 0.92rem;
}
/* ---- Project Scenarios ---- */
.projects-section {
background: var(--b2b-mist);
}
.project-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1px;
background: var(--b2b-line);
}
.project-card {
display: flex;
min-width: 0;
min-height: 300px;
padding: 2rem 1.75rem;
flex-direction: column;
background: var(--b2b-mist);
}
.project-meta {
color: var(--b2b-ink-muted);
font-size: 0.7rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.project-card h3 {
margin: 1.25rem 0 0.75rem;
font-size: 1.5rem;
}
.project-card p {
color: var(--b2b-ink-soft);
font-size: 0.95rem;
}
.project-card .text-link {
margin-top: auto;
}
/* ---- Customization Grid ---- */
.customization-section {
color: var(--b2b-surface);
background: var(--b2b-ink);
}
.customization-section h2,
.customization-section .section-eyebrow {
color: var(--b2b-surface);
}
.customization-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
border-top: 1px solid rgba(250, 250, 248, 0.12);
border-left: 1px solid rgba(250, 250, 248, 0.12);
}
.customization-item {
min-width: 0;
padding: 1.75rem;
border-right: 1px solid rgba(250, 250, 248, 0.12);
border-bottom: 1px solid rgba(250, 250, 248, 0.12);
}
.customization-item span {
display: block;
margin-bottom: 1.25rem;
color: rgba(250, 250, 248, 0.4);
font-size: 0.75rem;
letter-spacing: 0.1em;
}
.customization-item h3 {
margin: 0;
color: var(--b2b-surface);
font-size: 1.15rem;
}
/* ---- Factory / Store Environment ---- */
.factory-proof {
background: var(--b2b-surface);
@@ -1092,7 +855,7 @@ img {
}
.entry-title {
font-family: "Jost", "Noto Sans SC", Arial, sans-serif;
font-family: var(--b2b-font-sans);
font-size: clamp(2rem, 4vw, 3rem);
font-weight: 400;
letter-spacing: -0.02em;
@@ -1402,9 +1165,6 @@ textarea:focus-visible {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.process-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
/* LG down — 991px */
@@ -1418,14 +1178,6 @@ textarea:focus-visible {
padding: 7rem 0 4.5rem;
}
.project-grid {
grid-template-columns: 1fr;
}
.quality-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.factory-gallery {
margin-top: 1.5rem;
}
@@ -1481,9 +1233,6 @@ textarea:focus-visible {
}
.capability-grid,
.customization-grid,
.quality-grid,
.process-grid,
.document-grid {
grid-template-columns: 1fr;
}
@@ -1505,17 +1254,6 @@ textarea:focus-visible {
padding: 2rem 1.5rem;
}
.rfq-form-card {
padding: 1.5rem;
}
.project-card,
.quality-card,
.process-step {
min-height: 0;
padding: 1.5rem 1.25rem;
}
.page-header,
.b2b-section.about-intro,
.contact-section,
-53
View File
@@ -1,53 +0,0 @@
/*
- Colorbox Lightbox (only active vendor CSS)
- Jarallax and AOS styles removed (unused) — 2026-07-24
*/
/*--------------------------------------------------------------
/** Colorbox Lightbox
--------------------------------------------------------------*/
/*
Colorbox Core Style:
The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden; -webkit-transform: translate3d(0,0,0);}
#cboxWrapper {max-width:none;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
.cboxIframe{width:100%; height:100%; display:block; border:0; padding:0; margin:0;}
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
/*
User Style:
Change the following styles to modify the appearance of Colorbox. They are
ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:#000;}
#colorbox{outline:0;}
#cboxContent{margin-top:20px;background:#000;}
.cboxIframe{background:#fff;}
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{border:5px solid #000; background:#fff;}
#cboxTitle{position:absolute; top:-20px; left:0; color:#ccc;}
#cboxCurrent{position:absolute; top:-20px; right:0px; color:#ccc;}
#cboxLoadingGraphic{background:url(../images/colorbox/loading.gif) no-repeat center center;}
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
#cboxSlideshow{position:absolute; top:-20px; right:90px; color:#fff;}
#cboxPrevious{position:absolute; top:50%; left:5px; margin-top:-32px; background:url(../images/colorbox/controls.png) no-repeat top left; width:28px; height:65px; text-indent:-9999px;}
#cboxPrevious:hover{background-position:bottom left;}
#cboxNext{position:absolute; top:50%; right:5px; margin-top:-32px; background:url(../images/colorbox/controls.png) no-repeat top right; width:28px; height:65px; text-indent:-9999px;}
#cboxNext:hover{background-position:bottom right;}
#cboxClose{position:absolute; top:5px; right:5px; display:block; background:url(../images/colorbox/controls.png) no-repeat top center; width:38px; height:19px; text-indent:-9999px;}
#cboxClose:hover{background-position:bottom center;}
-7
View File
@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="260" height="96" viewBox="0 0 260 96">
<rect width="260" height="96" fill="#E8E8E8"/>
<rect x="2" y="2" width="256" height="92" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="130" y="48" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="16"
fill="#999999" font-weight="500">LOGO</text>
</svg>

Before

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 1</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 01</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 2</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 02</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 3</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 03</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 4</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 04</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 5</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 05</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 6</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 06</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

+6 -5
View File
@@ -1,7 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="960" viewBox="0 0 960 960">
<rect width="960" height="960" fill="#E8E8E8"/>
<rect x="2" y="2" width="956" height="956" fill="none" stroke="#CCCCCC" stroke-width="1" stroke-dasharray="8 4"/>
<text x="480" y="480" text-anchor="middle" dominant-baseline="central"
font-family="system-ui, -apple-system, sans-serif" font-size="53"
fill="#999999" font-weight="500">产品图 7</text>
<rect width="960" height="960" fill="#E8E6E1"/>
<path d="M180 510h600l-58-122c-14-30-44-49-77-49H361c-34 0-65 20-78 52l-49 119" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linejoin="round"/>
<path d="M180 510v96h50m550-96v96h-50M301 510h358" fill="none" stroke="#4A4A46" stroke-width="12" stroke-linecap="round"/>
<circle cx="300" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<circle cx="660" cy="606" r="42" fill="#E8E6E1" stroke="#1C1C1A" stroke-width="12"/>
<text x="480" y="735" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="36" fill="#4A4A46">汽车贴膜服务 07</text>
</svg>

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 754 B

File diff suppressed because one or more lines are too long
+10 -10
View File
@@ -1,4 +1,4 @@
(function ($) {
(function () {
'use strict';
document.documentElement.classList.remove('no-js');
@@ -14,11 +14,6 @@
window.addEventListener('scroll', updateHeader, { passive: true });
}
function initVideoLightbox() {
if (!$.fn || typeof $.fn.colorbox !== 'function') return;
$('.youtube').colorbox({ iframe: true, innerWidth: 960, innerHeight: 585, maxWidth: '95%', maxHeight: '90%' });
}
function initNavigation() {
var panel = document.querySelector('#fragrance-navigation');
if (!panel || !window.bootstrap || !window.bootstrap.Offcanvas) return;
@@ -30,9 +25,14 @@
});
}
$(function () {
function initTheme() {
initStickyHeader();
initVideoLightbox();
initNavigation();
});
})(jQuery);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTheme);
} else {
initTheme();
}
})();
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2011-2025 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+8 -4
View File
@@ -1,5 +1,9 @@
<?php
/** Site footer. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$fragrance_social_links = array(
'facebook_url' => __( 'Facebook', 'fragrance-trade' ), 'twitter_url' => __( 'X / Twitter', 'fragrance-trade' ),
'youtube_url' => __( 'YouTube', 'fragrance-trade' ), 'linkedin_url' => __( 'LinkedIn', 'fragrance-trade' ),
@@ -14,7 +18,7 @@ $fragrance_whatsapp = fragrance_trade_whatsapp_number();
<div class="col-lg-5">
<h2 class="h3 text-white mb-3"><?php echo esc_html( get_bloginfo( 'name' ) ); ?></h2>
<p class="footer-positioning"><?php echo esc_html( fragrance_trade_get_mod( 'footer_text' ) ); ?></p>
<p class="footer-kicker mb-0"><?php esc_html_e( '汽车贴膜 · 专业施工 · 门店服务', 'fragrance-trade' ); ?></p>
<p class="footer-kicker mb-0"><?php esc_html_e( '需求沟通 · 方案确认 · 施工交付', 'fragrance-trade' ); ?></p>
</div>
<div class="col-sm-6 col-lg-3">
<h2 class="h6 text-uppercase text-white mb-3"><?php esc_html_e( '快速导航', 'fragrance-trade' ); ?></h2>
@@ -22,11 +26,11 @@ $fragrance_whatsapp = fragrance_trade_whatsapp_number();
<li><a href="<?php echo esc_url( home_url( '/services/' ) ); ?>"><?php esc_html_e( '服务项目', 'fragrance-trade' ); ?></a></li>
<li><a href="<?php echo esc_url( home_url( '/cases/' ) ); ?>"><?php esc_html_e( '案例作品', 'fragrance-trade' ); ?></a></li>
<li><a href="<?php echo esc_url( home_url( '/about/' ) ); ?>"><?php esc_html_e( '关于门店', 'fragrance-trade' ); ?></a></li>
<li><a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>"><?php esc_html_e( '预约/联系', 'fragrance-trade' ); ?></a></li>
<li><a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>"><?php esc_html_e( '联系我们', 'fragrance-trade' ); ?></a></li>
</ul>
</div>
<div class="col-sm-6 col-lg-4">
<h2 class="h6 text-uppercase text-white mb-3"><?php esc_html_e( '开始合作', 'fragrance-trade' ); ?></h2>
<h2 class="h6 text-uppercase text-white mb-3"><?php esc_html_e( '联系门店', 'fragrance-trade' ); ?></h2>
<p><a href="mailto:<?php echo esc_attr( antispambot( $fragrance_email ) ); ?>"><?php echo esc_html( antispambot( $fragrance_email ) ); ?></a></p>
<?php if ( $fragrance_whatsapp ) : ?><p><a href="<?php echo esc_url( fragrance_trade_get_inquiry_url() ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( '通过 WhatsApp 联系我们', 'fragrance-trade' ); ?></a></p><?php endif; ?>
<ul class="list-unstyled d-flex flex-wrap gap-3 footer-social mb-0">
@@ -38,7 +42,7 @@ $fragrance_whatsapp = fragrance_trade_whatsapp_number();
</div>
<div class="footer-bottom d-flex flex-wrap justify-content-between gap-2 pt-4 mt-4 border-top">
<p class="mb-0">&copy; <?php echo esc_html( wp_date( 'Y' ) ); ?> <?php echo esc_html( get_bloginfo( 'name' ) ); ?></p>
<p class="mb-0"><?php esc_html_e( '具体服务内容与价格以到店确认为准。', 'fragrance-trade' ); ?></p>
<p class="mb-0"><?php esc_html_e( '项目、价格、工期与质保以门店最终确认为准。', 'fragrance-trade' ); ?></p>
</div>
</div>
</footer>
+4
View File
@@ -4,6 +4,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main fragrance-homepage">
-1
View File
@@ -15,7 +15,6 @@ $fragrance_trade_modules = array(
'helpers.php',
'cpt.php',
'customizer.php',
'inquiry.php',
);
foreach ( $fragrance_trade_modules as $fragrance_trade_module ) {
+7 -3
View File
@@ -1,6 +1,10 @@
<?php
/** Site header. @package Fragrance_Trade */
$fragrance_rfq_url = home_url( '/contact/' );
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$fragrance_contact_url = home_url( '/contact/' );
?><!doctype html>
<html <?php language_attributes(); ?> class="no-js">
<head>
@@ -34,8 +38,8 @@ $fragrance_rfq_url = home_url( '/contact/' );
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="<?php esc_attr_e( '关闭导航', 'fragrance-trade' ); ?>"></button>
</div>
<div class="offcanvas-body">
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'navbar-nav justify-content-end flex-grow-1 gap-xl-4 pe-xl-3', 'container' => false, 'fallback_cb' => false ) ); ?>
<a class="btn b2b-header-cta ms-xl-3" href="<?php echo esc_url( $fragrance_rfq_url ); ?>"><?php esc_html_e( '预约', 'fragrance-trade' ); ?></a>
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'navbar-nav justify-content-end flex-grow-1 gap-xl-4 pe-xl-3', 'container' => false, 'fallback_cb' => 'fragrance_trade_primary_menu_fallback' ) ); ?>
<a class="btn b2b-header-cta ms-xl-3" href="<?php echo esc_url( $fragrance_contact_url ); ?>"><?php esc_html_e( '联系', 'fragrance-trade' ); ?></a>
</div>
</div>
</div>
+314 -36
View File
@@ -74,82 +74,360 @@ function fragrance_trade_filter_cases_archive( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public archive filtering is read-only.
if ( $query->is_post_type_archive( 'case' ) && ! empty( $_GET['case_type'] ) ) {
$query->set( 'case_type', sanitize_text_field( wp_unslash( $_GET['case_type'] ) ) );
}
}
add_action( 'pre_get_posts', 'fragrance_trade_filter_cases_archive' );
/** One-time setup on theme activation: migrate products and create pages. */
function fragrance_trade_setup_site_on_activation() {
if ( get_option( 'fragrance_trade_setup_done' ) ) {
return;
/** Return the default service records created for a fresh installation. */
function fragrance_trade_service_seeds() {
return array(
'b2b_product_1' => array(
'title' => __( '隐形车衣(TPU 保护膜)', 'fragrance-trade' ),
'content' => __( '透明保护膜覆盖车漆表面,可帮助降低日常轻微划痕、飞石和污渍对漆面的影响。具体性能取决于所选产品系列。', 'fragrance-trade' ),
'excerpt' => __( '车漆保护 · 透明外观 · 日常养护', 'fragrance-trade' ),
),
'b2b_product_2' => array(
'title' => __( '彩色改色膜', 'fragrance-trade' ),
'content' => __( '通过不同颜色和表面质感改变车辆外观,可根据车型、原车颜色和日常使用场景选择亮面、哑光等效果。', 'fragrance-trade' ),
'excerpt' => __( '颜色选择 · 表面质感 · 外观焕新', 'fragrance-trade' ),
),
'b2b_product_3' => array(
'title' => __( '隔热防爆膜', 'fragrance-trade' ),
'content' => __( '用于车窗隔热与紫外线防护,可结合透光需求、隐私需求和法规要求选择适合的产品参数。', 'fragrance-trade' ),
'excerpt' => __( '隔热需求 · 紫外线防护 · 车窗适用', 'fragrance-trade' ),
),
'b2b_product_4' => array(
'title' => __( '陶瓷隔热膜', 'fragrance-trade' ),
'content' => __( '陶瓷类隔热膜适合关注隔热表现和车内电子信号使用的车主,实际参数与适用位置以具体产品说明为准。', 'fragrance-trade' ),
'excerpt' => __( '陶瓷膜料 · 信号兼容 · 隔热方案', 'fragrance-trade' ),
),
'b2b_product_5' => array(
'title' => __( '天窗冰甲', 'fragrance-trade' ),
'content' => __( '面向全景天窗的隔热保护项目,需要结合天窗结构、玻璃状况和所选膜料确认是否适合施工。', 'fragrance-trade' ),
'excerpt' => __( '全景天窗 · 隔热需求 · 安装评估', 'fragrance-trade' ),
),
'b2b_product_6' => array(
'title' => __( '前挡专用膜', 'fragrance-trade' ),
'content' => __( '前挡膜重点平衡透光视野、隔热需求和夜间驾驶体验,选购时应核对产品参数及当地法规要求。', 'fragrance-trade' ),
'excerpt' => __( '前挡适用 · 透光视野 · 隔热需求', 'fragrance-trade' ),
),
'b2b_product_7' => array(
'title' => __( '个性定制彩绘膜', 'fragrance-trade' ),
'content' => __( '可根据参考图和车辆尺寸沟通定制外观方案,制作前确认图案、颜色、覆盖范围与交付效果。', 'fragrance-trade' ),
'excerpt' => __( '图案沟通 · 方案确认 · 定制施工', 'fragrance-trade' ),
),
);
}
/** Hashes of the previous untouched seed copy, used to avoid overwriting edited services. */
function fragrance_trade_legacy_service_hashes() {
return array(
'b2b_product_1' => array( 'content' => '4ceefcf5b0d6835b2043eb974862641c4605408b249c47142a1384f8c6aba5a0', 'excerpt' => '474adc2b0a9cb84519f25b32f2aebaf66b7530c582d33a63fc428a70063982dd' ),
'b2b_product_2' => array( 'content' => 'c587d08672a5a73bd9d675a1aaa105b1dec46331a099649474a4669097c41707', 'excerpt' => 'edbbf896ccab06c5cbc79922f2130c190cb4dcd9720d427abd861c5d866d9de2' ),
'b2b_product_3' => array( 'content' => '49a236ff415f92de3c0a789ee42a7ea1083c60779f4dab3d80a162e9fbc534f7', 'excerpt' => '3be7e723aa8cfe1b5ce753e1ede8ceb5eb7122242a8bfde5dc6870e26291111e' ),
'b2b_product_4' => array( 'content' => '96db23ecaebbe16a7fd90254f098d9d652367ea200fe658792a7097082017d56', 'excerpt' => '3e59947da9a09130aeb65c0695c4b0ca1b78737e2cc320184a05ab0b4ca18424' ),
'b2b_product_5' => array( 'content' => '36d83bd3a439f92cdd89c4fb1e863e748d843733a9865b4740e9466c9ba0c916', 'excerpt' => '7e1985099340d070b75b2caa292cb877850bd7e7ed74a14d181dc98780d09666' ),
'b2b_product_6' => array( 'content' => 'caf3a595cc58b69861d66dbb92a04cfdddbe6ebfe7ef10a47e00e5cbbc112ea1', 'excerpt' => '1f1fb96587343da8d3fd938ec47f8f7abfb0a57c52a447c7b84997973ce57999' ),
'b2b_product_7' => array( 'content' => 'b1fda0e7a0c7b3445c61ac1ee1e53c7e27c0612c2e8706901f4a1c07d26959a0', 'excerpt' => '0815c3e0d55c9c491ecfa80d264f2c18e5112ab87e3366bc3bd7ca89c76a951c' ),
);
}
/** Find an existing seed by marker so a failed setup can be retried safely. */
function fragrance_trade_find_seeded_service( $seed_key ) {
$ids = get_posts(
array(
'post_type' => 'service',
'post_status' => array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash' ),
'posts_per_page' => 1,
'fields' => 'ids',
'meta_key' => '_fragrance_seed_key',
'meta_value' => $seed_key,
'no_found_rows' => true,
)
);
return $ids ? (int) $ids[0] : 0;
}
/** Locate an untouched service created by an older theme version and add its seed marker. */
function fragrance_trade_find_legacy_seed_service( $seed_key, $seed, $legacy_hashes ) {
$posts = get_posts(
array(
'post_type' => 'service',
'post_status' => array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash' ),
'title' => $seed['title'],
'posts_per_page' => 5,
'no_found_rows' => true,
)
);
foreach ( $posts as $post ) {
if (
hash_equals( $legacy_hashes['content'], hash( 'sha256', $post->post_content ) )
&& hash_equals( $legacy_hashes['excerpt'], hash( 'sha256', $post->post_excerpt ) )
) {
update_post_meta( $post->ID, '_fragrance_seed_key', $seed_key );
return (int) $post->ID;
}
}
return 0;
}
/** Update only untouched seed copy; preserve every service that an administrator edited. */
function fragrance_trade_migrate_seed_service_copy( &$errors ) {
$changed = false;
$legacy_hashes = fragrance_trade_legacy_service_hashes();
foreach ( fragrance_trade_service_seeds() as $seed_key => $seed ) {
$post_id = fragrance_trade_find_seeded_service( $seed_key );
if ( ! $post_id && isset( $legacy_hashes[ $seed_key ] ) ) {
$post_id = fragrance_trade_find_legacy_seed_service( $seed_key, $seed, $legacy_hashes[ $seed_key ] );
}
if ( ! $post_id || ! isset( $legacy_hashes[ $seed_key ] ) ) {
continue;
}
$post = get_post( $post_id );
$update = array( 'ID' => $post_id );
if ( hash_equals( $legacy_hashes[ $seed_key ]['content'], hash( 'sha256', $post->post_content ) ) ) {
$update['post_content'] = $seed['content'];
}
if ( hash_equals( $legacy_hashes[ $seed_key ]['excerpt'], hash( 'sha256', $post->post_excerpt ) ) ) {
$update['post_excerpt'] = $seed['excerpt'];
}
if ( 1 === count( $update ) ) {
continue;
}
$updated = wp_update_post( $update, true );
if ( is_wp_error( $updated ) ) {
$errors[] = sprintf(
/* translators: 1: service title, 2: error message. */
__( '无法更新服务“%1$s”的默认文案:%2$s', 'fragrance-trade' ),
$seed['title'],
$updated->get_error_message()
);
continue;
}
$changed = true;
}
$product_fallbacks = array(
'products/placeholder-01.svg',
'products/placeholder-02.svg',
'products/placeholder-03.svg',
'products/placeholder-04.svg',
'products/placeholder-05.svg',
'products/placeholder-06.svg',
'products/placeholder-07.svg',
);
for ( $index = 1; $index <= count( $product_fallbacks ); $index++ ) {
$title = fragrance_trade_get_mod( 'b2b_product_' . $index . '_title' );
return $changed;
}
/** Create seed services while preserving legacy Customizer product values. */
function fragrance_trade_create_seed_services( &$errors ) {
if ( get_option( 'fragrance_trade_setup_done' ) ) {
return false;
}
$changed = false;
foreach ( fragrance_trade_service_seeds() as $seed_key => $seed ) {
if ( fragrance_trade_find_seeded_service( $seed_key ) ) {
continue;
}
$title = get_theme_mod( $seed_key . '_title', $seed['title'] );
if ( ! $title ) {
continue;
}
$post_id = wp_insert_post(
array(
'post_type' => 'service',
'post_title' => $title,
'post_content' => fragrance_trade_get_mod( 'b2b_product_' . $index . '_text' ),
'post_excerpt' => fragrance_trade_get_mod( 'b2b_product_' . $index . '_specs' ),
'post_content' => get_theme_mod( $seed_key . '_text', $seed['content'] ),
'post_excerpt' => get_theme_mod( $seed_key . '_specs', $seed['excerpt'] ),
'post_status' => 'publish',
)
),
true
);
if ( $post_id && ! is_wp_error( $post_id ) ) {
$image = fragrance_trade_get_mod( 'b2b_product_' . $index . '_image', '' );
if ( $image ) {
update_post_meta( $post_id, '_service_image', $image );
}
if ( is_wp_error( $post_id ) ) {
$errors[] = sprintf(
/* translators: 1: service title, 2: error message. */
__( '无法创建服务“%1$s”:%2$s', 'fragrance-trade' ),
$title,
$post_id->get_error_message()
);
continue;
}
update_post_meta( $post_id, '_fragrance_seed_key', $seed_key );
$image = get_theme_mod( $seed_key . '_image', '' );
if ( $image ) {
update_post_meta( $post_id, '_service_image', $image );
}
$changed = true;
}
return $changed;
}
/** Find a conventional page, including the renamed slug WordPress uses in Trash. */
function fragrance_trade_find_required_page( $slug ) {
$pages = get_posts(
array(
'post_type' => 'page',
'post_status' => array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash' ),
'post_name__in' => array( $slug, $slug . '__trashed' ),
'posts_per_page' => 1,
'orderby' => 'post_name__in',
'no_found_rows' => true,
)
);
return $pages ? $pages[0] : null;
}
/** Create or repair the required pages without changing existing content or status. */
function fragrance_trade_create_required_pages( &$errors ) {
$pages = array(
'home' => array( 'post_title' => __( '首页', 'fragrance-trade' ), 'template' => '' ),
'about' => array( 'post_title' => __( '关于门店', 'fragrance-trade' ), 'template' => 'page-about.php' ),
'faq' => array( 'post_title' => __( '常见问题', 'fragrance-trade' ), 'template' => 'page-faq.php' ),
'contact' => array( 'post_title' => __( '预约/联系', 'fragrance-trade' ), 'template' => 'page-contact.php' ),
'contact' => array( 'post_title' => __( '联系我们', 'fragrance-trade' ), 'template' => 'page-contact.php' ),
);
$created = array();
$result = array( 'changed' => false, 'pages' => array() );
foreach ( $pages as $slug => $data ) {
$existing = get_page_by_path( $slug );
if ( $existing ) {
$created[ $slug ] = $existing->ID;
$page = fragrance_trade_find_required_page( $slug );
if ( $page ) {
if ( $data['template'] && get_page_template_slug( $page->ID ) !== $data['template'] ) {
$updated = wp_update_post(
array(
'ID' => $page->ID,
'page_template' => $data['template'],
),
true
);
if ( is_wp_error( $updated ) ) {
$errors[] = sprintf(
/* translators: 1: page title, 2: error message. */
__( '无法更新页面“%1$s”的模板:%2$s', 'fragrance-trade' ),
$page->post_title,
$updated->get_error_message()
);
} else {
$result['changed'] = true;
}
}
if ( 'publish' !== $page->post_status ) {
// Preserve user-owned draft and trash states; the admin notice below explains the impact.
} else {
$result['pages'][ $slug ] = $page->ID;
}
continue;
}
$id = wp_insert_post(
$page_id = wp_insert_post(
array(
'post_type' => 'page',
'post_name' => $slug,
'post_title' => $data['post_title'],
'post_status' => 'publish',
'page_template' => $data['template'],
)
),
true
);
if ( $id && ! is_wp_error( $id ) ) {
$created[ $slug ] = $id;
if ( is_wp_error( $page_id ) ) {
$errors[] = sprintf(
/* translators: 1: page title, 2: error message. */
__( '无法创建页面“%1$s”:%2$s', 'fragrance-trade' ),
$data['post_title'],
$page_id->get_error_message()
);
continue;
}
$result['changed'] = true;
$result['pages'][ $slug ] = $page_id;
}
if ( ! empty( $created['home'] ) ) {
update_option( 'page_on_front', $created['home'] );
return $result;
}
/** Versioned and retryable site setup. */
function fragrance_trade_maybe_setup_site() {
$target_version = 3;
if ( (int) get_option( 'fragrance_trade_schema_version', 0 ) >= $target_version ) {
return;
}
$errors = array();
$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 );
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'] ) {
flush_rewrite_rules();
}
flush_rewrite_rules();
if ( $errors ) {
update_option( 'fragrance_trade_setup_errors', array_values( array_unique( $errors ) ), false );
return;
}
delete_option( 'fragrance_trade_setup_errors' );
update_option( 'fragrance_trade_setup_done', 1 );
update_option( 'fragrance_trade_schema_version', $target_version );
}
add_action( 'after_switch_theme', 'fragrance_trade_setup_site_on_activation' );
add_action( 'after_switch_theme', 'fragrance_trade_maybe_setup_site' );
add_action( 'admin_init', 'fragrance_trade_maybe_setup_site' );
/** Show actionable setup failures until they are resolved. */
function fragrance_trade_setup_errors_notice() {
if ( ! current_user_can( 'switch_themes' ) ) {
return;
}
$errors = get_option( 'fragrance_trade_setup_errors', array() );
if ( ! $errors || ! is_array( $errors ) ) {
return;
}
?>
<div class="notice notice-error">
<p><strong><?php esc_html_e( 'B2B Trade 主题初始化未完成', 'fragrance-trade' ); ?></strong></p>
<ul>
<?php foreach ( $errors as $error ) : ?>
<li><?php echo esc_html( $error ); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php
}
add_action( 'admin_notices', 'fragrance_trade_setup_errors_notice' );
/** Warn when a conventional page exists but is not published. */
function fragrance_trade_page_status_notice() {
if ( ! current_user_can( 'edit_pages' ) ) {
return;
}
$unpublished = array();
foreach ( array( 'home', 'about', 'faq', 'contact' ) as $slug ) {
$page = fragrance_trade_find_required_page( $slug );
if ( $page && 'publish' !== $page->post_status ) {
$unpublished[] = $page->post_title;
}
}
if ( ! $unpublished ) {
return;
}
?>
<div class="notice notice-warning">
<p>
<strong><?php esc_html_e( 'B2B Trade 约定页面尚未发布', 'fragrance-trade' ); ?></strong>
<?php
printf(
/* translators: %s: comma-separated page titles. */
esc_html__( '主题保留了这些页面的当前状态,不会自动发布或恢复它们:%s。请确认状态后再用于前台导航。', 'fragrance-trade' ),
esc_html( implode( '、', $unpublished ) )
);
?>
</p>
</div>
<?php
}
add_action( 'admin_notices', 'fragrance_trade_page_status_notice' );
+2 -2
View File
@@ -85,7 +85,7 @@ function fragrance_trade_customize_register( $wp_customize ) {
array( 'b2b_documents_text', 'fragrance_b2b_documents', __( '板块简介', 'fragrance-trade' ), 'textarea' ),
array( 'b2b_show_faq', 'fragrance_b2b_faq', __( '显示常见问题', 'fragrance-trade' ), 'checkbox' ),
array( 'b2b_faq_title', 'fragrance_b2b_faq', __( '常见问题标题', 'fragrance-trade' ), 'text' ),
array( 'inquiry_email', 'fragrance_contact_social', __( '预约收件邮箱', 'fragrance-trade' ), 'email' ),
array( 'inquiry_email', 'fragrance_contact_social', __( '联系邮箱', 'fragrance-trade' ), 'email' ),
array( 'whatsapp', 'fragrance_contact_social', __( 'WhatsApp 号码(含国家代码)', 'fragrance-trade' ), 'text' ),
array( 'facebook_url', 'fragrance_contact_social', __( 'Facebook 链接', 'fragrance-trade' ), 'url' ),
array( 'twitter_url', 'fragrance_contact_social', __( 'X / Twitter 链接', 'fragrance-trade' ), 'url' ),
@@ -95,7 +95,7 @@ function fragrance_trade_customize_register( $wp_customize ) {
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_url', 'fragrance_contact_social', __( '地图导航链接', 'fragrance-trade' ), 'url' ),
array( 'footer_text', 'fragrance_contact_social', __( '页脚定位文案', 'fragrance-trade' ), 'text' ),
);
+53 -143
View File
@@ -11,165 +11,73 @@ if ( ! defined( 'ABSPATH' ) ) {
/** Return all theme defaults. */
function fragrance_trade_defaults() {
return array(
'b2b_hero_eyebrow' => __( '汽车贴膜 · 专业施工', 'fragrance-trade' ),
'b2b_hero_title' => __( '专业汽车贴膜门店,为您提供一站式贴膜服务', 'fragrance-trade' ),
'b2b_hero_text' => __( '从选膜咨询、色彩定制到专业施工和售后保障,我们帮您呵护爱车每一寸车漆。', 'fragrance-trade' ),
'b2b_hero_primary_label' => __( '立即预约', 'fragrance-trade' ),
static $defaults = null;
if ( null !== $defaults ) {
return $defaults;
}
$defaults = array(
'b2b_hero_eyebrow' => __( '需求沟通 · 方案确认 · 施工交付', 'fragrance-trade' ),
'b2b_hero_title' => __( '根据车型与使用场景,选择更合适的汽车贴膜方案', 'fragrance-trade' ),
'b2b_hero_text' => __( '隐形车衣、改色膜、隔热膜等项目,从需求沟通、膜料确认到施工交付,把选择和注意事项先讲清楚。', 'fragrance-trade' ),
'b2b_hero_primary_label' => __( '联系门店', 'fragrance-trade' ),
'b2b_hero_primary_url' => '/contact/',
'b2b_hero_secondary_label' => __( '了解服务项目', 'fragrance-trade' ),
'b2b_hero_secondary_url' => '/services/',
'b2b_trust_title' => __( '从选膜到施工的专业服务团队', 'fragrance-trade' ),
'b2b_metric_1_value' => __( '正品膜料', 'fragrance-trade' ),
'b2b_metric_1_label' => __( '品牌授权 · 质保可查', 'fragrance-trade' ),
'b2b_metric_2_value' => __( '一站式', 'fragrance-trade' ),
'b2b_metric_2_label' => __( '从选膜到施工交付', 'fragrance-trade' ),
'b2b_metric_3_value' => __( '逐车质检', 'fragrance-trade' ),
'b2b_metric_3_label' => __( '交付前品质复检', 'fragrance-trade' ),
'b2b_metric_4_value' => __( '售后无忧', 'fragrance-trade' ),
'b2b_metric_4_label' => __( '施工质保与维护指导', 'fragrance-trade' ),
'b2b_services_title' => __( '围绕您的车型与需求定制的贴膜服务', 'fragrance-trade' ),
'b2b_services_text' => __( '根据您的车型、预算和用车场景,选择最适合的贴膜方案。', 'fragrance-trade' ),
'b2b_service_1_title' => __( '隐形车衣施工', 'fragrance-trade' ),
'b2b_service_1_text' => __( 'TPU 材质全车或局部施工,自修复抗划伤,保护原厂车漆。', 'fragrance-trade' ),
'b2b_service_2_title' => __( '改色膜施工', 'fragrance-trade' ),
'b2b_service_2_text' => __( '丰富色彩与表面效果可选,专业无痕施工,不伤原车漆。', 'fragrance-trade' ),
'b2b_service_3_title' => __( '隔热膜施工', 'fragrance-trade' ),
'b2b_service_3_text' => __( '前挡、侧窗、天窗全覆盖,高效隔热阻紫外线,提升驾乘舒适度。', 'fragrance-trade' ),
'b2b_service_4_title' => __( '定制彩绘施工', 'fragrance-trade' ),
'b2b_service_4_text' => __( '支持个性化图案设计与施工,满足改装车友和商业用车外观需求。', 'fragrance-trade' ),
'b2b_products_title' => __( '门店可选膜料参考', 'fragrance-trade' ),
'b2b_products_text' => __( '以下为本店施工经验验证的主流膜料。施工效果因车型和颜色而异,欢迎到店看样。', 'fragrance-trade' ),
'b2b_product_1_title' => __( '隐形车衣(TPU 保护膜)', 'fragrance-trade' ),
'b2b_product_1_text' => __( '高透明度 TPU 材质,具备自修复功能,有效保护车漆免受石子划伤和紫外线损伤。', 'fragrance-trade' ),
'b2b_product_1_specs' => __( 'TPU 材质 · 自修复 · 高透光 · 抗黄变', 'fragrance-trade' ),
'b2b_product_1_image' => '',
'b2b_product_2_title' => __( '彩色改色膜', 'fragrance-trade' ),
'b2b_product_2_text' => __( '丰富色彩选择,高分子 PVC 材质,贴合度高,可实现哑光、亮面、珠光等多种表面效果。', 'fragrance-trade' ),
'b2b_product_2_specs' => __( 'PVC 材质 · 多色可选 · 哑光/亮面 · 高贴合', 'fragrance-trade' ),
'b2b_product_2_image' => '',
'b2b_product_3_title' => __( '隔热防爆膜', 'fragrance-trade' ),
'b2b_product_3_text' => __( '高效隔热阻紫外线,提升车内舒适度,多层金属镀膜工艺确保清晰视野与安全性。', 'fragrance-trade' ),
'b2b_product_3_specs' => __( '多层金属 · 隔热阻紫 · 高透光 · 防爆', 'fragrance-trade' ),
'b2b_product_3_image' => '',
'b2b_product_4_title' => __( '陶瓷隔热膜', 'fragrance-trade' ),
'b2b_product_4_text' => __( '纳米陶瓷技术,不屏蔽信号,隔热性能卓越,适合高端车型及电子设备密集车辆。', 'fragrance-trade' ),
'b2b_product_4_specs' => __( '纳米陶瓷 · 不挡信号 · 超强隔热 · 持久耐用', 'fragrance-trade' ),
'b2b_product_4_image' => '',
'b2b_product_5_title' => __( '天窗冰甲', 'fragrance-trade' ),
'b2b_product_5_text' => __( '专为全景天窗设计,高隔热率搭配防爆功能,降低车内温度同时提升安全性。', 'fragrance-trade' ),
'b2b_product_5_specs' => __( '天窗专用 · 高隔热 · 防爆 · 降噪', 'fragrance-trade' ),
'b2b_product_5_image' => '',
'b2b_product_6_title' => __( '前挡专用膜', 'fragrance-trade' ),
'b2b_product_6_text' => __( '前挡风玻璃专用配方,高透光率符合国家标准,兼顾隔热性能与驾驶视野。', 'fragrance-trade' ),
'b2b_product_6_specs' => __( '前挡专用 · 高透光 · 符合国标 · 隔热', 'fragrance-trade' ),
'b2b_product_6_image' => '',
'b2b_product_7_title' => __( '个性定制彩绘膜', 'fragrance-trade' ),
'b2b_product_7_text' => __( '支持图案定制设计,适用于个性化改装和商业用车外观需求。', 'fragrance-trade' ),
'b2b_product_7_specs' => __( '图案定制 · 个性化设计 · 专业施工 · 持久耐用', 'fragrance-trade' ),
'b2b_product_7_image' => '',
'b2b_custom_title' => __( '定制您想要的每一处细节', 'fragrance-trade' ),
'b2b_custom_text' => __( '根据车型、预算和个人喜好,灵活调整贴膜方案的关键要素。', 'fragrance-trade' ),
'b2b_custom_1_title' => __( '膜料选型', 'fragrance-trade' ),
'b2b_custom_2_title' => __( '颜色定制', 'fragrance-trade' ),
'b2b_custom_3_title' => __( '厚度规格', 'fragrance-trade' ),
'b2b_custom_4_title' => __( '施工范围', 'fragrance-trade' ),
'b2b_custom_5_title' => __( '表面工艺', 'fragrance-trade' ),
'b2b_custom_6_title' => __( '图案定制', 'fragrance-trade' ),
'b2b_custom_7_title' => __( '交车时间', 'fragrance-trade' ),
'b2b_custom_8_title' => __( '售后质保', 'fragrance-trade' ),
'b2b_factory_eyebrow' => __( '门店环境', 'fragrance-trade' ),
'b2b_factory_title' => __( '专业的施工环境', 'fragrance-trade' ),
'b2b_factory_text' => __( '标准无尘施工车间,专业技师团队,每台车均按流程规范操作。', 'fragrance-trade' ),
'b2b_factory_point_1' => __( '标准无尘施工车间', 'fragrance-trade' ),
'b2b_factory_point_2' => __( '施工前样板确认制度', 'fragrance-trade' ),
'b2b_factory_point_3' => __( '膜料与辅材规范管理', 'fragrance-trade' ),
'b2b_factory_point_4' => __( '施工进度实时沟通', 'fragrance-trade' ),
'b2b_trust_title' => __( '每一步都讲清楚,再开始施工', 'fragrance-trade' ),
'b2b_metric_1_value' => __( '方案透明', 'fragrance-trade' ),
'b2b_metric_1_label' => __( '项目、膜料与费用先确认', 'fragrance-trade' ),
'b2b_metric_2_value' => __( '按车建议', 'fragrance-trade' ),
'b2b_metric_2_label' => __( '结合车型与使用场景', 'fragrance-trade' ),
'b2b_metric_3_value' => __( '过程沟通', 'fragrance-trade' ),
'b2b_metric_3_label' => __( '关键节点及时同步', 'fragrance-trade' ),
'b2b_metric_4_value' => __( '交付说明', 'fragrance-trade' ),
'b2b_metric_4_label' => __( '检查结果与护理事项讲清楚', 'fragrance-trade' ),
'b2b_factory_eyebrow' => __( '施工现场', 'fragrance-trade' ),
'b2b_factory_title' => __( '看得见的施工过程', 'fragrance-trade' ),
'b2b_factory_text' => __( '施工前确认项目与车辆情况,施工中保持沟通,交付时说明检查结果和日常护理事项。', 'fragrance-trade' ),
'b2b_factory_point_1' => __( '接车前检查车辆情况', 'fragrance-trade' ),
'b2b_factory_point_2' => __( '施工方案与费用先确认', 'fragrance-trade' ),
'b2b_factory_point_3' => __( '膜料与辅材分类管理', 'fragrance-trade' ),
'b2b_factory_point_4' => __( '交付检查与护理说明', 'fragrance-trade' ),
'b2b_factory_image_1' => '',
'b2b_factory_image_2' => '',
'b2b_factory_image_3' => '',
'b2b_factory_image_4' => '',
'b2b_show_video' => true,
'b2b_video_title' => __( '汽车贴膜施工流程', 'fragrance-trade' ),
'b2b_video_text' => __( '了解从接车检查、裁膜施工到交付的完整流程。', 'fragrance-trade' ),
'b2b_video_title' => __( '了解汽车贴膜施工步骤', 'fragrance-trade' ),
'b2b_video_text' => __( '查看接车检查、车辆清洁、裁膜施工、复检交付等主要环节。', 'fragrance-trade' ),
'b2b_video_url' => '',
'b2b_video_image' => '',
'b2b_quality_title' => __( '每个施工环节的品质管控', 'fragrance-trade' ),
'b2b_quality_text' => __( '严格遵循标准施工流程,每道工序均有检查确认。', 'fragrance-trade' ),
'b2b_quality_1_title' => __( '车辆检查', 'fragrance-trade' ),
'b2b_quality_1_text' => __( '施工前对车身漆面、玻璃和饰件进行全面检查记录。', 'fragrance-trade' ),
'b2b_quality_2_title' => __( '样板确认', 'fragrance-trade' ),
'b2b_quality_2_text' => __( '以小面积样板确认颜色、质感和贴合效果。', 'fragrance-trade' ),
'b2b_quality_3_title' => __( '施工过程检验', 'fragrance-trade' ),
'b2b_quality_3_text' => __( '监控裁膜精度、贴合平整度和边角处理。', 'fragrance-trade' ),
'b2b_quality_4_title' => __( '色差检测', 'fragrance-trade' ),
'b2b_quality_4_text' => __( '对比确认施工效果与样板颜色的一致性。', 'fragrance-trade' ),
'b2b_quality_5_title' => __( '成品外观检验', 'fragrance-trade' ),
'b2b_quality_5_text' => __( '检查膜面瑕疵、气泡、边角贴合和整体效果。', 'fragrance-trade' ),
'b2b_quality_6_title' => __( '交付前复查', 'fragrance-trade' ),
'b2b_quality_6_text' => __( '交车前复核全车施工效果并拍照存档。', 'fragrance-trade' ),
'b2b_process_title' => __( '清晰的服务流程', 'fragrance-trade' ),
'b2b_process_text' => __( '每个阶段都有明确的沟通与确认,确保您对施工效果心中有数。', 'fragrance-trade' ),
'b2b_process_1_title' => __( '预约咨询', 'fragrance-trade' ),
'b2b_process_1_text' => __( '告知车型、需求和预算,获取初步方案建议。', 'fragrance-trade' ),
'b2b_process_2_title' => __( '需求评估', 'fragrance-trade' ),
'b2b_process_2_text' => __( '到店看样、确认施工范围和预估工时。', 'fragrance-trade' ),
'b2b_process_3_title' => __( '选择膜料与方案', 'fragrance-trade' ),
'b2b_process_3_text' => __( '确定膜料品牌、颜色、部位和施工方案。', 'fragrance-trade' ),
'b2b_process_4_title' => __( '样板确认', 'fragrance-trade' ),
'b2b_process_4_text' => __( '以小面积施工确认效果,确保符合预期。', 'fragrance-trade' ),
'b2b_process_5_title' => __( '方案锁定', 'fragrance-trade' ),
'b2b_process_5_text' => __( '锁定确认的方案、膜料规格和施工排期。', 'fragrance-trade' ),
'b2b_process_6_title' => __( '预约施工', 'fragrance-trade' ),
'b2b_process_6_text' => __( '确认施工日期、交车时间和费用。', 'fragrance-trade' ),
'b2b_process_7_title' => __( '施工与质检', 'fragrance-trade' ),
'b2b_process_7_text' => __( '按标准流程施工,关键节点拍照同步。', 'fragrance-trade' ),
'b2b_process_8_title' => __( '交车与售后', 'fragrance-trade' ),
'b2b_process_8_text' => __( '验收交车,提供质保卡和维护指南。', 'fragrance-trade' ),
'b2b_show_projects' => true,
'b2b_projects_title' => __( '施工案例类型', 'fragrance-trade' ),
'b2b_projects_text' => __( '以下为不同车主选择贴膜服务的常见场景,帮助您了解适合的方案。', 'fragrance-trade' ),
'b2b_project_1_title' => __( '新车提车贴膜', 'fragrance-trade' ),
'b2b_project_1_meta' => __( '提车即保护', 'fragrance-trade' ),
'b2b_project_1_text' => __( '新车落地即施工,在车漆最佳状态下提供全面保护。', 'fragrance-trade' ),
'b2b_project_2_title' => __( '老车改色焕新', 'fragrance-trade' ),
'b2b_project_2_meta' => __( '换个颜色换种心情', 'fragrance-trade' ),
'b2b_project_2_text' => __( '根据个人喜好和流行趋势,为爱车换上全新外观。', 'fragrance-trade' ),
'b2b_project_3_title' => __( '商业车队定制', 'fragrance-trade' ),
'b2b_project_3_meta' => __( '统一形象 · 专业施工', 'fragrance-trade' ),
'b2b_project_3_text' => __( '为商业车队提供统一外观设计和批量施工服务。', 'fragrance-trade' ),
'b2b_show_documents' => true,
'b2b_documents_title' => __( '服务保障与文档', 'fragrance-trade' ),
'b2b_documents_text' => __( '施工完成后您将收到以下文件,确保权益有据可查。', 'fragrance-trade' ),
'b2b_document_1_title' => __( '施工方案确认', 'fragrance-trade' ),
'b2b_document_1_text' => __( '已确认的膜料品牌、规格、施工部位和费用清单。', 'fragrance-trade' ),
'b2b_document_2_title' => __( '施工记录存档', 'fragrance-trade' ),
'b2b_document_2_text' => __( '施工过程关键节点拍照记录,交付前进行最终检查。', 'fragrance-trade' ),
'b2b_document_3_title' => __( '膜料质保卡', 'fragrance-trade' ),
'b2b_document_3_text' => __( '膜料品牌官方质保凭证,包含质保期限和范围说明。', 'fragrance-trade' ),
'b2b_document_4_title' => __( '维护保养指南', 'fragrance-trade' ),
'b2b_document_4_text' => __( '施工后的日常护理建议、注意事项和复检周期说明。', 'fragrance-trade' ),
'b2b_documents_title' => __( '交付信息更清楚', 'fragrance-trade' ),
'b2b_documents_text' => __( '实际提供的文件因项目和膜料而异,下单前可向门店确认。', 'fragrance-trade' ),
'b2b_document_1_title' => __( '项目与费用确认', 'fragrance-trade' ),
'b2b_document_1_text' => __( '记录施工部位、所选膜料、费用和预计工期。', 'fragrance-trade' ),
'b2b_document_2_title' => __( '车辆检查记录', 'fragrance-trade' ),
'b2b_document_2_text' => __( '记录施工前车辆情况和交付检查结果。', 'fragrance-trade' ),
'b2b_document_3_title' => __( '产品与质保凭证', 'fragrance-trade' ),
'b2b_document_3_text' => __( '如项目适用,提供对应品牌或产品的凭证与质保说明。', 'fragrance-trade' ),
'b2b_document_4_title' => __( '日常护理建议', 'fragrance-trade' ),
'b2b_document_4_text' => __( '说明洗车、清洁、检查等日常注意事项。', 'fragrance-trade' ),
'b2b_show_faq' => true,
'b2b_faq_title' => __( '常见问题', 'fragrance-trade' ),
'b2b_faq_1_question' => __( '施工需要多长时间?', 'fragrance-trade' ),
'b2b_faq_1_answer' => __( '全车隐形车衣约 1-2 天,改色膜约 2-3 天,隔热膜约半天。具体以到店评估为准。', 'fragrance-trade' ),
'b2b_faq_2_question' => __( '有哪些颜色和膜料可选', 'fragrance-trade' ),
'b2b_faq_2_answer' => __( '我们提供多种品牌和颜色的膜料,欢迎到店看实物色卡样板,选择最适合您爱车的方案。', 'fragrance-trade' ),
'b2b_faq_1_question' => __( '通常需要多长时间?', 'fragrance-trade' ),
'b2b_faq_1_answer' => __( '工期取决于车型、施工部位、膜料和当日排期。隐形车衣与改色膜通常需要留车,隔热膜所需时间相对较短,具体以门店确认结果为准。', 'fragrance-trade' ),
'b2b_faq_2_question' => __( '怎样选择膜料和颜色', 'fragrance-trade' ),
'b2b_faq_2_answer' => __( '可以结合预算、车辆用途、停车环境和外观偏好进行选择。建议到店看实物色卡样板,并确认不同光线下的效果。', 'fragrance-trade' ),
'b2b_faq_3_question' => __( '可以按我的参考图样施工吗?', 'fragrance-trade' ),
'b2b_faq_3_answer' => __( '可以带上您的参考图样,我们的技师会评估可行性和施工方案。', 'fragrance-trade' ),
'b2b_faq_3_answer' => __( '可以带上参考图,由门店结合车型曲面、膜料效果和施工条件评估。成品会受材质与光线影响,不能仅以屏幕图片作为最终颜色依据。', 'fragrance-trade' ),
'b2b_faq_4_question' => __( '贴膜后多久可以洗车?', 'fragrance-trade' ),
'b2b_faq_4_answer' => __( '建议施工后 7 天内避免高压水枪洗车,让膜料充分贴合。具体以交车时告知的维护指南为准。', 'fragrance-trade' ),
'b2b_faq_4_answer' => __( '不同膜料和施工环境所需的稳定时间不同。交车时请确认首次洗车时间,并避免过早使用高压水枪冲洗膜边。', 'fragrance-trade' ),
'b2b_faq_5_question' => __( '膜料和颜色可以定制搭配吗?', 'fragrance-trade' ),
'b2b_faq_5_answer' => __( '可以。不同部位可选择不同膜料,我们会根据您的需求推荐最优搭配方案。', 'fragrance-trade' ),
'b2b_faq_5_answer' => __( '可以讨论分区搭配,但需要同时考虑颜色协调、膜料厚度、收边位置和后续维护,再确认是否适合施工。', 'fragrance-trade' ),
'b2b_faq_6_question' => __( '施工前可以先看样板效果吗?', 'fragrance-trade' ),
'b2b_faq_6_answer' => __( '可以。我们会先做小面积施工样板供您确认颜色、质感和贴合效果,满意后再全面施工。', 'fragrance-trade' ),
'b2b_faq_7_question' => __( '预约需要提供哪些信息?', 'fragrance-trade' ),
'b2b_faq_7_answer' => __( '请提供车型、想做的项目或膜种,以及期望的施工时间,我们会尽快与您确认方案和排期。', 'fragrance-trade' ),
'b2b_faq_8_question' => __( '施工后质保多久', 'fragrance-trade' ),
'b2b_faq_8_answer' => __( '质保期限因膜料品牌和类型而异,一般在 3-10 年不等。施工完成后会提供品牌官方质保卡。', 'fragrance-trade' ),
'b2b_rfq_title' => __( '在线预约咨询', 'fragrance-trade' ),
'b2b_rfq_text' => __( '填写基本信息,我们的服务顾问将为您提供方案建议和施工排期。', 'fragrance-trade' ),
'b2b_rfq_button_label' => __( '提交预约', 'fragrance-trade' ),
'b2b_faq_6_answer' => __( '可以先查看色卡和现有样板。是否能进行小面积试贴,取决于所选膜料和车辆部位,请在施工前与门店确认。', 'fragrance-trade' ),
'b2b_faq_7_question' => __( '咨询时需要提供哪些信息?', 'fragrance-trade' ),
'b2b_faq_7_answer' => __( '建议准备车型与年份、想做的项目、外观偏好、预算范围和期望用车时间,便于门店更快判断可选方案。', 'fragrance-trade' ),
'b2b_faq_8_question' => __( '质保范围和期限怎么确认', 'fragrance-trade' ),
'b2b_faq_8_answer' => __( '质保范围和期限由所选品牌、产品系列与施工项目决定。下单前请确认适用条件、起止时间和所需凭证,并以最终书面说明为准。', 'fragrance-trade' ),
'inquiry_email' => '',
'whatsapp' => '',
'facebook_url' => '',
@@ -181,6 +89,8 @@ function fragrance_trade_defaults() {
'store_phone' => '',
'store_hours' => '',
'store_map_url' => '',
'footer_text' => __( '为车主提供专业汽车贴膜施工与养护服务。', 'fragrance-trade' ),
'footer_text' => __( '专注汽车贴膜方案沟通、施工交付与日常护理说明。', 'fragrance-trade' ),
);
return $defaults;
}
+39 -16
View File
@@ -15,6 +15,14 @@ function fragrance_trade_get_mod( $key, $fallback = null ) {
return get_theme_mod( $key, $default );
}
function fragrance_trade_resolve_url( $url ) {
$url = trim( (string) $url );
if ( str_starts_with( $url, '/' ) && ! str_starts_with( $url, '//' ) ) {
return home_url( $url );
}
return $url;
}
function fragrance_trade_asset_uri( $relative_path ) {
return trailingslashit( get_template_directory_uri() ) . 'assets/' . ltrim( $relative_path, '/' );
}
@@ -45,32 +53,47 @@ function fragrance_trade_get_inquiry_url( $project = '' ) {
if ( $number ) {
return add_query_arg( 'text', $message, 'https://wa.me/' . $number );
}
return 'mailto:' . antispambot( fragrance_trade_inquiry_email() ) . '?subject=' . rawurlencode( __( '汽车贴膜预约咨询', 'fragrance-trade' ) ) . '&body=' . rawurlencode( $message );
return 'mailto:' . antispambot( fragrance_trade_inquiry_email() ) . '?subject=' . rawurlencode( __( '汽车贴膜服务咨询', 'fragrance-trade' ) ) . '&body=' . rawurlencode( $message );
}
function fragrance_trade_get_notice() {
if ( empty( $_GET['fragrance_notice'] ) ) {
return '';
}
return sanitize_key( wp_unslash( $_GET['fragrance_notice'] ) );
}
function fragrance_trade_notice_message( $code ) {
$messages = array(
'success' => __( '感谢您的提交,预约需求已发送。', 'fragrance-trade' ),
'invalid' => __( '请检查必填项后重新提交。', 'fragrance-trade' ),
'rate_limited' => __( '请稍候片刻再重新提交。', 'fragrance-trade' ),
'mail_failed' => __( '发送失败,请通过邮件或 WhatsApp 联系我们。', 'fragrance-trade' ),
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' => home_url( '/about/' ) ),
array( 'label' => __( '常见问题', 'fragrance-trade' ), 'url' => home_url( '/faq/' ) ),
array( 'label' => __( '联系我们', 'fragrance-trade' ), 'url' => home_url( '/contact/' ) ),
);
return isset( $messages[ $code ] ) ? $messages[ $code ] : '';
echo '<ul class="navbar-nav justify-content-end flex-grow-1 gap-xl-4 pe-xl-3">';
foreach ( $links as $link ) {
printf(
'<li class="nav-item"><a class="nav-link" href="%s">%s</a></li>',
esc_url( $link['url'] ),
esc_html( $link['label'] )
);
}
echo '</ul>';
}
add_action(
'admin_notices',
function () {
if ( ! current_user_can( 'edit_theme_options' ) ) {
return;
}
$locations = get_nav_menu_locations();
$menu_id = isset( $locations['primary'] ) ? $locations['primary'] : 0;
if ( ! $menu_id ) {
printf(
'<div class="notice notice-warning is-dismissible"><p><strong>%s</strong> %s <a href="%s">%s</a></p></div>',
esc_html__( '尚未分配主导航菜单', 'fragrance-trade' ),
esc_html__( '前台暂时显示主题默认导航。请创建正式菜单并分配到“主导航”。', 'fragrance-trade' ),
esc_url( admin_url( 'nav-menus.php' ) ),
esc_html__( '配置菜单', 'fragrance-trade' )
);
return;
}
$items = wp_get_nav_menu_items( $menu_id );
@@ -79,7 +102,7 @@ add_action(
printf(
'<div class="notice notice-warning is-dismissible"><p><strong>%s</strong> %s <a href="%s">%s</a></p></div>',
esc_html__( '主导航菜单项过少', 'fragrance-trade' ),
esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、预约联系。', 'fragrance-trade' ),
esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、联系我们。', 'fragrance-trade' ),
esc_url( admin_url( 'nav-menus.php' ) ),
esc_html__( '编辑菜单', 'fragrance-trade' )
);
-95
View File
@@ -1,95 +0,0 @@
<?php
/**
* Secure RFQ form handler (deprecated).
*
* @package Fragrance_Trade
* @deprecated 2.1.0 Contact page no longer has a form. This handler remains
* registered but is never triggered. Kept as a security reference
* implementation (nonce + honeypot + rate-limit + header injection
* guard) in case a booking form is re-introduced.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function fragrance_trade_post_value( $key ) {
if ( ! isset( $_POST[ $key ] ) || ! is_scalar( $_POST[ $key ] ) ) {
return '';
}
return (string) wp_unslash( $_POST[ $key ] );
}
function fragrance_trade_limit_text( $value, $length ) {
return function_exists( 'mb_substr' ) ? mb_substr( $value, 0, $length ) : substr( $value, 0, $length );
}
function fragrance_trade_form_redirect_url() {
$fallback = home_url( '/' );
$referer = wp_get_referer();
return wp_validate_redirect( $referer ? $referer : $fallback, $fallback );
}
function fragrance_trade_redirect_notice( $notice ) {
$url = remove_query_arg( 'fragrance_notice', fragrance_trade_form_redirect_url() );
$url = add_query_arg( 'fragrance_notice', sanitize_key( $notice ), $url );
wp_safe_redirect( $url . '#rfq' );
exit;
}
function fragrance_trade_is_rate_limited( $action ) {
$address = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 'unknown';
$key = 'fragrance_' . sanitize_key( $action ) . '_' . substr( hash( 'sha256', $address . wp_salt( 'nonce' ) ), 0, 32 );
if ( get_transient( $key ) ) {
return true;
}
set_transient( $key, 1, MINUTE_IN_SECONDS );
return false;
}
function fragrance_trade_honeypot_filled() {
return '' !== trim( fragrance_trade_post_value( 'fragrance_website' ) );
}
function fragrance_trade_handle_rfq() {
check_admin_referer( 'fragrance_rfq', 'fragrance_rfq_nonce' );
if ( fragrance_trade_honeypot_filled() ) {
fragrance_trade_redirect_notice( 'invalid' );
}
if ( fragrance_trade_is_rate_limited( 'rfq' ) ) {
fragrance_trade_redirect_notice( 'rate_limited' );
}
$fields = array(
'name' => fragrance_trade_limit_text( sanitize_text_field( fragrance_trade_post_value( 'name' ) ), 100 ),
'email' => fragrance_trade_limit_text( sanitize_email( fragrance_trade_post_value( 'email' ) ), 190 ),
'company' => fragrance_trade_limit_text( sanitize_text_field( fragrance_trade_post_value( 'company' ) ), 150 ),
'whatsapp' => fragrance_trade_limit_text( sanitize_text_field( fragrance_trade_post_value( 'whatsapp' ) ), 100 ),
'product_type' => fragrance_trade_limit_text( sanitize_text_field( fragrance_trade_post_value( 'product_type' ) ), 150 ),
'message' => fragrance_trade_limit_text( sanitize_textarea_field( fragrance_trade_post_value( 'message' ) ), 2000 ),
);
if ( ! $fields['name'] || ! is_email( $fields['email'] ) || ! $fields['product_type'] || ! $fields['message'] ) {
fragrance_trade_redirect_notice( 'invalid' );
}
$labels = array(
'name' => __( '姓名', 'fragrance-trade' ), 'email' => __( '邮箱', 'fragrance-trade' ),
'company' => __( '车型 / 车牌', 'fragrance-trade' ), 'whatsapp' => __( 'WhatsApp 或电话', 'fragrance-trade' ),
'product_type' => __( '想做的项目 / 膜种', 'fragrance-trade' ), 'message' => __( '简要需求描述', 'fragrance-trade' ),
);
$body_lines = array();
foreach ( $labels as $key => $label ) {
$body_lines[] = $label . ': ' . ( $fields[ $key ] ? $fields[ $key ] : __( '未提供', 'fragrance-trade' ) );
}
$site_name = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
$safe_name = str_replace( array( "\r", "\n" ), ' ', $fields['name'] );
$safe_email = str_replace( array( "\r", "\n" ), '', $fields['email'] );
$context = $fields['company'] ? $fields['company'] : $fields['product_type'];
$subject = sprintf( '[%s] %s - %s', $site_name, __( '汽车贴膜预约', 'fragrance-trade' ), $context );
$headers = array( 'Content-Type: text/plain; charset=UTF-8', 'Reply-To: ' . $safe_name . ' <' . $safe_email . '>' );
$sent = wp_mail( fragrance_trade_inquiry_email(), $subject, implode( "\n\n", $body_lines ), $headers );
fragrance_trade_redirect_notice( $sent ? 'success' : 'mail_failed' );
}
add_action( 'admin_post_fragrance_rfq', 'fragrance_trade_handle_rfq' );
add_action( 'admin_post_nopriv_fragrance_rfq', 'fragrance_trade_handle_rfq' );
+4 -36
View File
@@ -66,43 +66,11 @@ function fragrance_trade_asset_version( $relative_path, $fallback ) {
function fragrance_trade_enqueue_assets() {
$version = wp_get_theme()->get( 'Version' );
wp_enqueue_style( 'fragrance-bootstrap', 'https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/css/bootstrap.min.css', array(), '5.3.0-alpha3' );
wp_enqueue_style( 'fragrance-fonts', 'https://fonts.loli.net/css2?family=Josefin+Sans:wght@200;300;400;500;600;700&family=Jost:wght@200;300;400;500&family=Noto+Sans+SC:wght@300;400;500;700&display=swap', array(), null );
wp_enqueue_style( 'fragrance-normalize', get_template_directory_uri() . '/assets/css/normalize.css', array(), fragrance_trade_asset_version( 'assets/css/normalize.css', $version ) );
wp_enqueue_style( 'fragrance-vendor', get_template_directory_uri() . '/assets/css/vendor.css', array(), fragrance_trade_asset_version( 'assets/css/vendor.css', $version ) );
wp_enqueue_style( 'fragrance-base', get_stylesheet_uri(), array( 'fragrance-bootstrap', 'fragrance-vendor' ), fragrance_trade_asset_version( 'style.css', $version ) );
wp_enqueue_style( 'fragrance-bootstrap', get_template_directory_uri() . '/assets/vendor/bootstrap/bootstrap.min.css', array(), fragrance_trade_asset_version( 'assets/vendor/bootstrap/bootstrap.min.css', '5.3.8' ) );
wp_enqueue_style( 'fragrance-base', get_stylesheet_uri(), array( 'fragrance-bootstrap' ), fragrance_trade_asset_version( 'style.css', $version ) );
wp_enqueue_style( 'fragrance-theme', get_template_directory_uri() . '/assets/css/theme.css', array( 'fragrance-base' ), fragrance_trade_asset_version( 'assets/css/theme.css', $version ) );
wp_enqueue_script( 'fragrance-bootstrap', 'https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/js/bootstrap.bundle.min.js', array(), '5.3.0-alpha3', true );
wp_enqueue_script( 'fragrance-plugins', get_template_directory_uri() . '/assets/js/plugins.js', array( 'jquery' ), fragrance_trade_asset_version( 'assets/js/plugins.js', $version ), true );
wp_enqueue_script( 'fragrance-theme', get_template_directory_uri() . '/assets/js/theme.js', array( 'jquery', 'fragrance-bootstrap', 'fragrance-plugins' ), fragrance_trade_asset_version( 'assets/js/theme.js', $version ), true );
wp_enqueue_script( 'fragrance-bootstrap', get_template_directory_uri() . '/assets/vendor/bootstrap/bootstrap.bundle.min.js', array(), fragrance_trade_asset_version( 'assets/vendor/bootstrap/bootstrap.bundle.min.js', '5.3.8' ), true );
wp_enqueue_script( 'fragrance-theme', get_template_directory_uri() . '/assets/js/theme.js', array( 'fragrance-bootstrap' ), fragrance_trade_asset_version( 'assets/js/theme.js', $version ), true );
}
add_action( 'wp_enqueue_scripts', 'fragrance_trade_enqueue_assets' );
/**
* SRI integrity hashes for CDN-hosted resources.
*
* Computed 2026-07-24 from cdn.bootcdn.net.
* Verify/update via: curl -sL <url> | openssl dgst -sha384 -binary | openssl base64 -A
*/
function fragrance_trade_style_sri( $html, $handle ) {
$sri = array(
'fragrance-bootstrap' => 'sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ',
);
if ( isset( $sri[ $handle ] ) ) {
$html = str_replace( '/>', ' integrity="' . esc_attr( $sri[ $handle ] ) . '" crossorigin="anonymous" />', $html );
}
return $html;
}
add_filter( 'style_loader_tag', 'fragrance_trade_style_sri', 10, 2 );
function fragrance_trade_script_sri( $html, $handle ) {
$sri = array(
'fragrance-bootstrap' => 'sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe',
);
if ( isset( $sri[ $handle ] ) ) {
$html = str_replace( '></script>', ' integrity="' . esc_attr( $sri[ $handle ] ) . '" crossorigin="anonymous"></script>', $html );
}
return $html;
}
add_filter( 'script_loader_tag', 'fragrance_trade_script_sri', 10, 2 );
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Main fallback template. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main container py-5 fragrance-content-area">
+827
View File
@@ -0,0 +1,827 @@
# Copyright (C) 2026 B2B Trade
# This file is distributed under the GNU General Public License v2 or later.
msgid ""
msgstr ""
"Project-Id-Version: B2B Trade 2.1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-24 14:19+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Domain: fragrance-trade\n"
#: scripts/demo-content.php:71
msgid "B2B Trade 中性演示图"
msgstr ""
#: inc/cpt.php:391
msgid "B2B Trade 主题初始化未完成"
msgstr ""
#: inc/cpt.php:421
msgid "B2B Trade 约定页面尚未发布"
msgstr ""
#: footer.php:8
msgid "Facebook"
msgstr ""
#: inc/customizer.php:90
msgid "Facebook 链接"
msgstr ""
#: footer.php:10
msgid "Instagram"
msgstr ""
#: inc/customizer.php:94
msgid "Instagram 链接"
msgstr ""
#: footer.php:9
msgid "LinkedIn"
msgstr ""
#: inc/customizer.php:93
msgid "LinkedIn 链接"
msgstr ""
#: inc/customizer.php:89
msgid "WhatsApp 号码(含国家代码)"
msgstr ""
#: footer.php:8
msgid "X / Twitter"
msgstr ""
#: inc/customizer.php:91
msgid "X / Twitter 链接"
msgstr ""
#: footer.php:9
msgid "YouTube"
msgstr ""
#: inc/customizer.php:92
msgid "YouTube 链接"
msgstr ""
#: inc/customizer.php:81
msgid "YouTube、Vimeo 或视频链接"
msgstr ""
#: inc/defaults.php:72
msgid "不同膜料和施工环境所需的稳定时间不同。交车时请确认首次洗车时间,并避免过早使用高压水枪冲洗膜边。"
msgstr ""
#: inc/defaults.php:92
msgid "专注汽车贴膜方案沟通、施工交付与日常护理说明。"
msgstr ""
#: inc/cpt.php:118
msgid "个性定制彩绘膜"
msgstr ""
#: scripts/demo-content.php:97
msgid "中性施工案例"
msgstr ""
#: header.php:23 inc/setup.php:25
msgid "主导航"
msgstr ""
#: inc/helpers.php:104
msgid "主导航菜单项过少"
msgstr ""
#: inc/customizer.php:70
msgid "主按钮文字"
msgstr ""
#: inc/customizer.php:71
msgid "主按钮链接"
msgstr ""
#: inc/customizer.php:68
msgid "主标题"
msgstr ""
#: inc/cpt.php:425
msgid "主题保留了这些页面的当前状态,不会自动发布或恢复它们:%s。请确认状态后再用于前台导航。"
msgstr ""
#: inc/defaults.php:25
msgid "了解服务项目"
msgstr ""
#: inc/defaults.php:48
msgid "了解汽车贴膜施工步骤"
msgstr ""
#: inc/defaults.php:53
msgid "交付信息更清楚"
msgstr ""
#: inc/defaults.php:42
msgid "交付检查与护理说明"
msgstr ""
#: inc/defaults.php:34 template-parts/home/documents.php:12
msgid "交付说明"
msgstr ""
#: inc/defaults.php:59
msgid "产品与质保凭证"
msgstr ""
#: template-parts/home/case-teaser.php:20
msgid "从案例了解不同项目的实际效果"
msgstr ""
#: archive-service.php:29
msgid "从车漆保护、外观改色到车窗隔热,按车型与使用需求查看可选项目。"
msgstr ""
#: template-parts/home/faq.php:11
msgid "以下内容用于帮助您提前了解选择和施工注意事项。具体项目、价格、工期与质保,请以门店最终确认为准。"
msgstr ""
#: inc/customizer.php:54
msgid "信任栏"
msgstr ""
#: inc/customizer.php:74
msgid "信任栏标题"
msgstr ""
#: inc/customizer.php:103
msgid "信任点 %d 数值"
msgstr ""
#: inc/customizer.php:104
msgid "信任点 %d 标签"
msgstr ""
#: page-about.php:86
msgid "先看样板,再决定"
msgstr ""
#: inc/cpt.php:110
msgid "全景天窗 · 隔热需求 · 安装评估"
msgstr ""
#: archive-case.php:43
msgid "全部"
msgstr ""
#: inc/cpt.php:23
msgid "全部服务项目"
msgstr ""
#: inc/cpt.php:43
msgid "全部案例"
msgstr ""
#: page-about.php:45
msgid "关于我们"
msgstr ""
#: footer.php:28 inc/cpt.php:286 inc/helpers.php:64 page-about.php:28
msgid "关于门店"
msgstr ""
#: inc/defaults.php:33
msgid "关键节点及时同步"
msgstr ""
#: header.php:38
msgid "关闭导航"
msgstr ""
#: inc/helpers.php:93
msgid "前台暂时显示主题默认导航。请创建正式菜单并分配到“主导航”。"
msgstr ""
#: inc/cpt.php:113
msgid "前挡专用膜"
msgstr ""
#: inc/cpt.php:114
msgid "前挡膜重点平衡透光视野、隔热需求和夜间驾驶体验,选购时应核对产品参数及当地法规要求。"
msgstr ""
#: inc/cpt.php:115
msgid "前挡适用 · 透光视野 · 隔热需求"
msgstr ""
#: inc/defaults.php:76
msgid "可以先查看色卡和现有样板。是否能进行小面积试贴,取决于所选膜料和车辆部位,请在施工前与门店确认。"
msgstr ""
#: inc/defaults.php:70
msgid "可以带上参考图,由门店结合车型曲面、膜料效果和施工条件评估。成品会受材质与光线影响,不能仅以屏幕图片作为最终颜色依据。"
msgstr ""
#: inc/defaults.php:69
msgid "可以按我的参考图样施工吗?"
msgstr ""
#: inc/defaults.php:68
msgid "可以结合预算、车辆用途、停车环境和外观偏好进行选择。建议到店查看实物色卡与样板,并确认不同光线下的效果。"
msgstr ""
#: inc/defaults.php:74
msgid "可以讨论分区搭配,但需要同时考虑颜色协调、膜料厚度、收边位置和后续维护,再确认是否适合施工。"
msgstr ""
#: inc/cpt.php:119
msgid "可根据参考图和车辆尺寸沟通定制外观方案,制作前确认图案、颜色、覆盖范围与交付效果。"
msgstr ""
#: template-parts/home/cta.php:11
msgid "告诉我们车型、使用场景、关注的问题和预算范围,门店会结合实际情况说明可选项目与到店安排。"
msgstr ""
#: page-contact.php:44
msgid "咨询与到店"
msgstr ""
#: single-case.php:42
msgid "咨询同类施工"
msgstr ""
#: page-contact.php:46
msgid "咨询时可说明车型、年份、想做的项目和期望时间,方便门店更快判断可选方案。"
msgstr ""
#: inc/defaults.php:77
msgid "咨询时需要提供哪些信息?"
msgstr ""
#: inc/customizer.php:112
msgid "回答 %d"
msgstr ""
#: inc/cpt.php:120
msgid "图案沟通 · 方案确认 · 定制施工"
msgstr ""
#: page-contact.php:112
msgid "在百度地图中导航"
msgstr ""
#: page-contact.php:72
msgid "在线咨询"
msgstr ""
#: inc/customizer.php:98
msgid "地图导航链接"
msgstr ""
#: inc/cpt.php:108
msgid "天窗冰甲"
msgstr ""
#: inc/defaults.php:60
msgid "如项目适用,提供对应品牌或产品的凭证与质保说明。"
msgstr ""
#: inc/defaults.php:54
msgid "实际提供的文件因项目和膜料而异,下单前可向门店确认。"
msgstr ""
#: inc/helpers.php:92
msgid "尚未分配主导航菜单"
msgstr ""
#: inc/defaults.php:66
msgid "工期取决于车型、施工部位、膜料和当日排期。隐形车衣与改色膜通常需要留车,隔热膜所需时间相对较短,具体以门店确认结果为准。"
msgstr ""
#: inc/cpt.php:287 inc/customizer.php:57 inc/defaults.php:64 inc/helpers.php:65 page-faq.php:23 template-parts/home/faq.php:11
msgid "常见问题"
msgstr ""
#: inc/customizer.php:87
msgid "常见问题标题"
msgstr ""
#: inc/defaults.php:78
msgid "建议准备车型与年份、想做的项目、外观偏好、预算范围和期望用车时间,便于门店更快判断可选方案。"
msgstr ""
#: inc/cpt.php:93
msgid "彩色改色膜"
msgstr ""
#: footer.php:24
msgid "快速导航"
msgstr ""
#: inc/defaults.php:67
msgid "怎样选择膜料和颜色?"
msgstr ""
#: inc/helpers.php:50
msgid "您好,我想咨询 %s 的贴膜服务。"
msgstr ""
#: inc/helpers.php:51
msgid "您好,我想咨询汽车贴膜服务。"
msgstr ""
#: template-parts/home/cta.php:10
msgid "想先了解适合哪种贴膜方案?"
msgstr ""
#: inc/helpers.php:105
msgid "手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、联系我们。"
msgstr ""
#: header.php:32
msgid "打开导航"
msgstr ""
#: template-parts/home/service-teaser.php:23
msgid "按车型与需求选择贴膜方案"
msgstr ""
#: inc/defaults.php:30
msgid "按车建议"
msgstr ""
#: inc/defaults.php:39
msgid "接车前检查车辆情况"
msgstr ""
#: inc/customizer.php:108
msgid "文档卡片 %d 描述"
msgstr ""
#: inc/customizer.php:107
msgid "文档卡片 %d 标题"
msgstr ""
#: inc/customizer.php:56
msgid "文档支持"
msgstr ""
#: template-parts/home/hero.php:22
msgid "方案确认"
msgstr ""
#: inc/defaults.php:28
msgid "方案透明"
msgstr ""
#: template-parts/home/hero.php:23
msgid "施工交付"
msgstr ""
#: inc/defaults.php:75
msgid "施工前可以先看样板效果吗?"
msgstr ""
#: inc/defaults.php:38
msgid "施工前确认项目与车辆情况,施工中保持沟通,交付时说明检查结果和日常护理事项。"
msgstr ""
#: inc/defaults.php:40
msgid "施工方案与费用先确认"
msgstr ""
#: template-parts/home/video.php:11
msgid "施工流程"
msgstr ""
#: inc/defaults.php:36
msgid "施工现场"
msgstr ""
#: template-parts/home/case-teaser.php:19
msgid "施工记录"
msgstr ""
#: inc/cpt.php:249
msgid "无法创建服务“%1$s”:%2$s"
msgstr ""
#: inc/cpt.php:335
msgid "无法创建页面“%1$s”:%2$s"
msgstr ""
#: inc/cpt.php:207
msgid "无法更新服务“%1$s”的默认文案:%2$s"
msgstr ""
#: inc/cpt.php:306
msgid "无法更新页面“%1$s”的模板:%2$s"
msgstr ""
#: inc/defaults.php:61
msgid "日常护理建议"
msgstr ""
#: inc/customizer.php:86
msgid "显示常见问题"
msgstr ""
#: inc/customizer.php:83
msgid "显示文档板块"
msgstr ""
#: inc/customizer.php:78
msgid "显示门店视频"
msgstr ""
#: template-parts/home/hero.php:20
msgid "服务步骤"
msgstr ""
#: archive-service.php:22 archive-service.php:28 footer.php:26 inc/cpt.php:19 inc/cpt.php:20 inc/helpers.php:62 single-service.php:26 template-parts/home/service-teaser.php:22
msgid "服务项目"
msgstr ""
#: template-parts/content-none.php:9
msgid "未找到内容"
msgstr ""
#: inc/customizer.php:76 inc/customizer.php:84
msgid "板块标题"
msgstr ""
#: inc/customizer.php:85
msgid "板块简介"
msgstr ""
#: template-parts/home/service-teaser.php:49
msgid "查看全部服务项目"
msgstr ""
#: template-parts/home/case-teaser.php:36
msgid "查看全部案例"
msgstr ""
#: inc/defaults.php:49
msgid "查看接车检查、车辆清洁、裁膜施工、复检交付等主要环节。"
msgstr ""
#: inc/defaults.php:21
msgid "根据车型与使用场景,选择更合适的汽车贴膜方案"
msgstr ""
#: inc/cpt.php:40
msgid "案例"
msgstr ""
#: archive-case.php:22 archive-case.php:28 footer.php:27 inc/cpt.php:39 inc/helpers.php:63 single-case.php:23
msgid "案例作品"
msgstr ""
#: archive-case.php:65 template-parts/home/case-teaser.php:39
msgid "案例内容正在整理中。"
msgstr ""
#: inc/cpt.php:60 inc/cpt.php:61
msgid "案例分类"
msgstr ""
#: inc/defaults.php:35
msgid "检查结果与护理事项讲清楚"
msgstr ""
#: inc/customizer.php:72
msgid "次按钮文字"
msgstr ""
#: inc/customizer.php:73
msgid "次按钮链接"
msgstr ""
#: page-about.php:87
msgid "欢迎到店查看实物色卡、膜料样板与施工环境,再结合车型和预算确认方案。"
msgstr ""
#: inc/defaults.php:27
msgid "每一步都讲清楚,再开始施工"
msgstr ""
#: template-parts/home/video.php:11
msgid "汽车贴膜施工流程示意图"
msgstr ""
#: inc/helpers.php:56
msgid "汽车贴膜服务咨询"
msgstr ""
#: scripts/demo-content.php:102
msgid "汽车贴膜维护说明"
msgstr ""
#: archive-case.php:29
msgid "浏览不同车型与项目的施工记录。实际效果会受膜料、车漆、光线和拍摄条件影响。"
msgstr ""
#: inc/cpt.php:21
msgid "添加服务项目"
msgstr ""
#: inc/cpt.php:41
msgid "添加案例"
msgstr ""
#: scripts/demo-content.php:98
msgid "用于本地冒烟和视觉回归的中性案例内容。"
msgstr ""
#: inc/cpt.php:99
msgid "用于车窗隔热与紫外线防护,可结合透光需求、隐私需求和法规要求选择适合的产品参数。"
msgstr ""
#: scripts/demo-content.php:103
msgid "用于验证主题普通文章模板的中性演示内容。"
msgstr ""
#: page-contact.php:95
msgid "电子邮箱"
msgstr ""
#: inc/customizer.php:67 inc/customizer.php:75
msgid "眉标"
msgstr ""
#: inc/defaults.php:37
msgid "看得见的施工过程"
msgstr ""
#: inc/customizer.php:69
msgid "简介文案"
msgstr ""
#: inc/defaults.php:31
msgid "结合车型与使用场景"
msgstr ""
#: inc/customizer.php:47
msgid "编辑固定布局的汽车贴膜门店首页。上线前请将所有演示文案替换为真实门店信息。"
msgstr ""
#: inc/cpt.php:22
msgid "编辑服务项目"
msgstr ""
#: inc/cpt.php:42
msgid "编辑案例"
msgstr ""
#: inc/helpers.php:107
msgid "编辑菜单"
msgstr ""
#: header.php:42
msgid "联系"
msgstr ""
#: footer.php:29 inc/cpt.php:288 inc/helpers.php:66 page-contact.php:36
msgid "联系我们"
msgstr ""
#: inc/customizer.php:58
msgid "联系方式与社交链接"
msgstr ""
#: inc/customizer.php:96 page-contact.php:58
msgid "联系电话"
msgstr ""
#: inc/customizer.php:88
msgid "联系邮箱"
msgstr ""
#: archive-service.php:43 footer.php:33 inc/defaults.php:23 page-about.php:89 single-service.php:43 template-parts/home/cta.php:12 template-parts/home/service-teaser.php:39
msgid "联系门店"
msgstr ""
#: template-parts/home/video.php:11
msgid "联系门店查看实拍"
msgstr ""
#: page-contact.php:45
msgid "联系门店,确认您的需求"
msgstr ""
#: inc/defaults.php:41
msgid "膜料与辅材分类管理"
msgstr ""
#: inc/defaults.php:73
msgid "膜料和颜色可以定制搭配吗?"
msgstr ""
#: inc/customizer.php:97 page-contact.php:84
msgid "营业时间"
msgstr ""
#: template-parts/home/video.php:11
msgid "观看门店视频"
msgstr ""
#: inc/customizer.php:82
msgid "视频封面图"
msgstr ""
#: inc/customizer.php:80
msgid "视频描述"
msgstr ""
#: inc/customizer.php:79
msgid "视频标题"
msgstr ""
#: inc/defaults.php:58
msgid "记录施工前车辆情况和交付检查结果。"
msgstr ""
#: inc/defaults.php:56
msgid "记录施工部位、所选膜料、费用和预计工期。"
msgstr ""
#: inc/defaults.php:62
msgid "说明洗车、清洁、检查等日常注意事项。"
msgstr ""
#: template-parts/content-none.php:10
msgid "请尝试其他搜索词或返回首页。"
msgstr ""
#: inc/defaults.php:79
msgid "质保范围和期限怎么确认?"
msgstr ""
#: inc/defaults.php:80
msgid "质保范围和期限由所选品牌、产品系列与施工项目决定。下单前请确认适用条件、起止时间和所需凭证,并以最终书面说明为准。"
msgstr ""
#: inc/defaults.php:71
msgid "贴膜后多久可以洗车?"
msgstr ""
#: archive-service.php:40 template-parts/home/service-teaser.php:36
msgid "贴膜服务"
msgstr ""
#: header.php:17
msgid "跳转到内容"
msgstr ""
#: inc/cpt.php:90
msgid "车漆保护 · 透明外观 · 日常养护"
msgstr ""
#: inc/defaults.php:57
msgid "车辆检查记录"
msgstr ""
#: inc/defaults.php:32
msgid "过程沟通"
msgstr ""
#: 404.php:14
msgid "返回首页"
msgstr ""
#: inc/cpt.php:89
msgid "透明保护膜覆盖车漆表面,可帮助降低日常轻微划痕、飞石和污渍对漆面的影响。具体性能取决于所选产品系列。"
msgstr ""
#: inc/defaults.php:65
msgid "通常需要多长时间?"
msgstr ""
#: footer.php:35
msgid "通过 WhatsApp 联系我们"
msgstr ""
#: inc/cpt.php:94
msgid "通过不同颜色和表面质感改变车辆外观,可根据车型、原车颜色和日常使用场景选择亮面、哑光等效果。"
msgstr ""
#: inc/helpers.php:95
msgid "配置菜单"
msgstr ""
#: inc/customizer.php:105
msgid "门店亮点 %d"
msgstr ""
#: inc/customizer.php:106
msgid "门店图片 %d"
msgstr ""
#: inc/customizer.php:95
msgid "门店地址"
msgstr ""
#: template-parts/home/factory.php:13
msgid "门店实景 %d"
msgstr ""
#: inc/customizer.php:55
msgid "门店环境与参观"
msgstr ""
#: inc/customizer.php:77
msgid "门店简介"
msgstr ""
#: inc/customizer.php:46
msgid "门店首页"
msgstr ""
#: inc/customizer.php:111
msgid "问题 %d"
msgstr ""
#: inc/cpt.php:104
msgid "陶瓷类隔热膜适合关注隔热表现和车内电子信号使用的车主,实际参数与适用位置以具体产品说明为准。"
msgstr ""
#: inc/cpt.php:105
msgid "陶瓷膜料 · 信号兼容 · 隔热方案"
msgstr ""
#: inc/cpt.php:103
msgid "陶瓷隔热膜"
msgstr ""
#: inc/defaults.php:22
msgid "隐形车衣、改色膜、隔热膜等项目,从需求沟通、膜料确认到施工交付,把选择和注意事项先讲清楚。"
msgstr ""
#: inc/cpt.php:88
msgid "隐形车衣(TPU 保护膜)"
msgstr ""
#: inc/cpt.php:98
msgid "隔热防爆膜"
msgstr ""
#: inc/cpt.php:100
msgid "隔热需求 · 紫外线防护 · 车窗适用"
msgstr ""
#: template-parts/home/hero.php:21
msgid "需求沟通"
msgstr ""
#: footer.php:21 inc/defaults.php:20
msgid "需求沟通 · 方案确认 · 施工交付"
msgstr ""
#: template-parts/breadcrumb.php:18
msgid "面包屑导航"
msgstr ""
#: inc/cpt.php:109
msgid "面向全景天窗的隔热保护项目,需要结合天窗结构、玻璃状况和所选膜料确认是否适合施工。"
msgstr ""
#: inc/customizer.php:99
msgid "页脚定位文案"
msgstr ""
#: 404.php:12
msgid "页面可能已迁移,请搜索网站或返回首页。"
msgstr ""
#: template-parts/home/video.php:11
msgid "页面图片为流程示意;门店实拍内容以实际上传为准。"
msgstr ""
#: 404.php:11
msgid "页面未找到"
msgstr ""
#: footer.php:45
msgid "项目、价格、工期与质保以门店最终确认为准。"
msgstr ""
#: inc/defaults.php:29
msgid "项目、膜料与费用先确认"
msgstr ""
#: inc/defaults.php:55
msgid "项目与费用确认"
msgstr ""
#: inc/cpt.php:95
msgid "颜色选择 · 表面质感 · 外观焕新"
msgstr ""
#: inc/customizer.php:53
msgid "首屏定位"
msgstr ""
#: archive-case.php:21 archive-service.php:21 inc/cpt.php:285 inc/helpers.php:61 page-about.php:27 page-contact.php:35 page-faq.php:22 single-case.php:22 single-service.php:25
msgid "首页"
msgstr ""
+7 -3
View File
@@ -5,6 +5,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
@@ -79,10 +83,10 @@ get_header();
?>
<section class="b2b-section about-cta text-center">
<div class="container">
<h2><?php esc_html_e( '来店里看看?', 'fragrance-trade' ); ?></h2>
<p class="section-lead mx-auto"><?php esc_html_e( '欢迎到店看实物色卡、施工样板,我们的顾问为您提供一对一咨询服务。', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '先看样板,再决定', 'fragrance-trade' ); ?></h2>
<p class="section-lead mx-auto"><?php esc_html_e( '欢迎到店看实物色卡、膜料样板与施工环境,再结合车型和预算确认方案。', 'fragrance-trade' ); ?></p>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary btn-lg mt-3">
<?php esc_html_e( '预约到店', 'fragrance-trade' ); ?>
<?php esc_html_e( '联系门店', 'fragrance-trade' ); ?>
</a>
</div>
</section>
+19 -11
View File
@@ -1,10 +1,14 @@
<?php
/**
* Template Name: 预约/联系
* Template Name: 联系我们
* Contact page with store info and map navigation.
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
$store_address = fragrance_trade_get_mod( 'store_address', '' );
@@ -13,10 +17,12 @@ $store_hours = fragrance_trade_get_mod( 'store_hours', '' );
$whatsapp = fragrance_trade_whatsapp_number();
$email = fragrance_trade_inquiry_email();
// Build Baidu Map navigation link from address
$map_nav_url = 'https://api.map.baidu.com/geocoder?address='
. rawurlencode( $store_address ?: '郑州经济技术开发区经开第二大街与经南五路交叉口向西50米路南59号' )
. '&output=html&src=webapp';
$map_nav_url = fragrance_trade_get_mod( 'store_map_url', '' );
if ( ! $map_nav_url && $store_address ) {
$map_nav_url = 'https://api.map.baidu.com/geocoder?address='
. rawurlencode( $store_address )
. '&output=html&src=webapp';
}
?>
<main id="primary" class="site-main">
<div class="page-content container">
@@ -27,7 +33,7 @@ $map_nav_url = 'https://api.map.baidu.com/geocoder?address='
array(
'items' => array(
array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
array( 'label' => __( '预约联系', 'fragrance-trade' ), 'url' => null ),
array( 'label' => __( '联系我们', 'fragrance-trade' ), 'url' => null ),
),
)
);
@@ -35,13 +41,13 @@ $map_nav_url = 'https://api.map.baidu.com/geocoder?address='
<section class="b2b-section contact-section">
<div class="container">
<div class="section-heading text-center mx-auto mb-5">
<p class="section-eyebrow"><?php esc_html_e( '到店咨询', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '联系与到店', 'fragrance-trade' ); ?></h2>
<p class="section-lead"><?php esc_html_e( '欢迎直接到店或通过以下方式联系我们,预约您的贴膜服务。', 'fragrance-trade' ); ?></p>
<p class="section-eyebrow"><?php esc_html_e( '咨询与到店', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '联系门店,确认您的需求', 'fragrance-trade' ); ?></h2>
<p class="section-lead"><?php esc_html_e( '咨询时可说明车型、年份、想做的项目和期望时间,方便门店更快判断可选方案。', 'fragrance-trade' ); ?></p>
</div>
<div class="row g-4">
<div class="col-lg-5">
<div class="<?php echo $map_nav_url ? 'col-lg-5' : 'col-lg-8 mx-auto'; ?>">
<div class="contact-info-card">
<?php if ( $store_phone ) : ?>
<div class="contact-info-item">
@@ -93,8 +99,9 @@ $map_nav_url = 'https://api.map.baidu.com/geocoder?address='
</div>
</div>
<?php if ( $map_nav_url ) : ?>
<div class="col-lg-7">
<a href="<?php echo esc_url( $map_nav_url ); ?>" class="contact-map-card" target="_blank" rel="noopener">
<a href="<?php echo esc_url( $map_nav_url ); ?>" class="contact-map-card" target="_blank" rel="noopener noreferrer">
<div class="contact-map-icon" aria-hidden="true">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
</div>
@@ -106,6 +113,7 @@ $map_nav_url = 'https://api.map.baidu.com/geocoder?address='
</span>
</a>
</div>
<?php endif; ?>
</div>
</div>
</section>
+4
View File
@@ -5,6 +5,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main">
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Page template. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main container py-5 fragrance-content-area">
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 224 KiB

+5 -1
View File
@@ -4,6 +4,10 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main">
@@ -35,7 +39,7 @@ get_header();
<?php endif; ?>
</header>
<div class="case-content"><?php the_content(); ?></div>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary mt-3"><?php esc_html_e( '预约同款施工', 'fragrance-trade' ); ?></a>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary mt-3"><?php esc_html_e( '咨询同类施工', 'fragrance-trade' ); ?></a>
</article>
<?php endwhile; ?>
</main>
+10 -3
View File
@@ -4,13 +4,16 @@
*
* @package Fragrance_Trade
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main">
<?php while ( have_posts() ) : the_post(); ?>
<?php
$image = get_post_meta( get_the_ID(), '_service_image', true );
$img = $image ? $image : fragrance_trade_asset_uri( 'products/placeholder-01.svg' );
?>
<article class="page-content container">
<?php
@@ -28,12 +31,16 @@ get_header();
?>
<div class="row g-5 align-items-center">
<div class="col-lg-6">
<img src="<?php echo esc_url( $img ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid rounded">
<?php if ( has_post_thumbnail() ) : ?>
<?php the_post_thumbnail( 'large', array( 'class' => 'img-fluid rounded', 'decoding' => 'async' ) ); ?>
<?php else : ?>
<img src="<?php echo esc_url( $image ? $image : fragrance_trade_asset_uri( 'images/products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid rounded" decoding="async">
<?php endif; ?>
</div>
<div class="col-lg-6">
<h1><?php the_title(); ?></h1>
<div class="service-content"><?php the_content(); ?></div>
<a href="<?php echo esc_url( home_url( '/contact/?service=' . rawurlencode( get_the_title() ) ) ); ?>" class="btn btn-b2b-primary mt-3"><?php esc_html_e( '预约这项服务', 'fragrance-trade' ); ?></a>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary mt-3"><?php esc_html_e( '联系门店', 'fragrance-trade' ); ?></a>
</div>
</div>
</article>
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Single post template. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
<main id="primary" class="site-main container py-5 fragrance-content-area">
+6 -6
View File
@@ -1,12 +1,12 @@
/*
Theme Name: B2B Trade
Theme URI: https://example.com/b2b-trade/
Theme URI: http://git.xgouo.cn/zhs123/car-t-t
Author: B2B Trade
Description: 专业汽车贴膜门店主题,支持服务项目展示、案例作品集、在线预约联系,适配移动端。
Version: 2.0.0
Requires at least: 6.5
Tested up to: 6.6
Requires PHP: 7.4
Description: 专业汽车贴膜门店主题,支持服务项目、案例作品集、门店信息和直接联系,适配移动端。
Version: 2.1.0
Requires at least: 6.8
Tested up to: 7.0
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: fragrance-trade
+4
View File
@@ -6,6 +6,10 @@
*
* @param array $items Array of ['label' => string, 'url' => string|null].
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( empty( $args['items'] ) || ! is_array( $args['items'] ) ) {
return;
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Empty-loop content. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<section class="no-results not-found text-center py-5">
<h1 class="page-title"><?php esc_html_e( '未找到内容', 'fragrance-trade' ); ?></h1>
+4
View File
@@ -1,3 +1,7 @@
<?php
/** Page content. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_template_part( 'template-parts/content' );
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Generic loop content. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'fragrance-entry' ); ?>>
<header class="entry-header mb-3">
+9 -4
View File
@@ -1,18 +1,23 @@
<?php
/** Case teaser on the homepage. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$case_query = new WP_Query(
array(
'post_type' => 'case',
'posts_per_page' => 6,
'post_status' => 'publish',
'no_found_rows' => true,
)
);
?>
<section id="cases" class="b2b-section cases-section">
<div class="container">
<div class="section-heading text-center mx-auto">
<p class="section-eyebrow"><?php esc_html_e( '施工案例', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '为车主完成的贴膜施工', 'fragrance-trade' ); ?></h2>
<p class="section-eyebrow"><?php esc_html_e( '施工记录', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '从案例了解不同项目的实际效果', 'fragrance-trade' ); ?></h2>
</div>
<?php if ( $case_query->have_posts() ) : ?>
<div class="case-grid mt-5">
@@ -21,7 +26,7 @@ $case_query = new WP_Query(
<?php if ( has_post_thumbnail() ) : ?>
<?php the_post_thumbnail( 'medium', array( 'class' => 'img-fluid' ) ); ?>
<?php else : ?>
<img src="<?php echo esc_url( fragrance_trade_asset_uri( 'products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid">
<img src="<?php echo esc_url( fragrance_trade_asset_uri( 'images/products/placeholder-01.svg' ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid">
<?php endif; ?>
<span class="case-card-title"><?php the_title(); ?></span>
</a>
@@ -31,7 +36,7 @@ $case_query = new WP_Query(
<a href="<?php echo esc_url( home_url( '/cases/' ) ); ?>" class="btn btn-b2b-primary"><?php esc_html_e( '查看全部案例', 'fragrance-trade' ); ?></a>
</div>
<?php else : ?>
<p class="text-center mt-4 mb-0"><?php esc_html_e( '案例即将上线,敬请期待。', 'fragrance-trade' ); ?></p>
<p class="text-center mt-4 mb-0"><?php esc_html_e( '案例内容正在整理中。', 'fragrance-trade' ); ?></p>
<?php endif; ?>
</div>
</section>
+7 -3
View File
@@ -1,10 +1,14 @@
<?php
/** Booking call-to-action band on the homepage. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<section class="b2b-section cta-section">
<div class="container text-center">
<h2><?php esc_html_e( '准备好为爱车贴膜了吗', 'fragrance-trade' ); ?></h2>
<p class="section-lead mx-auto"><?php esc_html_e( '留下您的车型与需求,我们会尽快与您联系,确认到店施工时间。', 'fragrance-trade' ); ?></p>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary btn-lg"><?php esc_html_e( '立即预约', 'fragrance-trade' ); ?></a>
<h2><?php esc_html_e( '想先了解适合哪种贴膜方案', 'fragrance-trade' ); ?></h2>
<p class="section-lead mx-auto"><?php esc_html_e( '告诉我们车型、使用场景、关注的问题和预算范围,门店会结合实际情况说明可选项目与到店安排。', 'fragrance-trade' ); ?></p>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-primary btn-lg"><?php esc_html_e( '联系门店', 'fragrance-trade' ); ?></a>
</div>
</section>
+11 -2
View File
@@ -1,4 +1,13 @@
<?php /** Documentation support. @package Fragrance_Trade */ if ( ! fragrance_trade_show_section( 'b2b_show_documents' ) ) { return; } ?>
<?php
/** Documentation support. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! fragrance_trade_show_section( 'b2b_show_documents' ) ) {
return;
}
?>
<section id="documents" class="b2b-section documents-section">
<div class="container"><div class="row g-5"><div class="col-lg-5"><p class="section-eyebrow"><?php esc_html_e( '文档支持', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_documents_title' ) ); ?></h2><p class="section-lead"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_documents_text' ) ); ?></p></div><div class="col-lg-7"><div class="document-grid"><?php for ( $index = 1; $index <= 4; $index++ ) : ?><article><span aria-hidden="true">✓</span><div><h3><?php echo esc_html( fragrance_trade_get_mod( 'b2b_document_' . $index . '_title' ) ); ?></h3><p><?php echo esc_html( fragrance_trade_get_mod( 'b2b_document_' . $index . '_text' ) ); ?></p></div></article><?php endfor; ?></div></div></div></div>
<div class="container"><div class="row g-5"><div class="col-lg-5"><p class="section-eyebrow"><?php esc_html_e( '交付说明', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_documents_title' ) ); ?></h2><p class="section-lead"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_documents_text' ) ); ?></p></div><div class="col-lg-7"><div class="document-grid"><?php for ( $index = 1; $index <= 4; $index++ ) : ?><article><span aria-hidden="true">✓</span><div><h3><?php echo esc_html( fragrance_trade_get_mod( 'b2b_document_' . $index . '_title' ) ); ?></h3><p><?php echo esc_html( fragrance_trade_get_mod( 'b2b_document_' . $index . '_text' ) ); ?></p></div></article><?php endfor; ?></div></div></div></div>
</section>
+4
View File
@@ -1,5 +1,9 @@
<?php
/** Factory proof section. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$factory_fallbacks = array( 'placeholder-factory-01.svg', 'placeholder-factory-02.svg', 'placeholder-factory-03.svg', 'placeholder-factory-04.svg' );
?>
<section id="factory" class="b2b-section factory-proof">
+11 -2
View File
@@ -1,2 +1,11 @@
<?php /** B2B FAQ. @package Fragrance_Trade */ if ( ! fragrance_trade_show_section( 'b2b_show_faq' ) ) { return; } ?>
<section id="faqs" class="b2b-section faq-section"><div class="container"><div class="row g-5"><div class="col-lg-4"><p class="section-eyebrow"><?php esc_html_e( '常见问题', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_title' ) ); ?></h2><p><?php esc_html_e( '服务内容、价格和工期以到店确认为准。如需具体答复请使用预约表单。', 'fragrance-trade' ); ?></p></div><div class="col-lg-8"><div class="accordion" id="b2b-faq-accordion"><?php for ( $index = 1; $index <= 8; $index++ ) : $first = 1 === $index; ?><div class="accordion-item"><h3 class="accordion-header" id="b2b-faq-heading-<?php echo esc_attr( $index ); ?>"><button class="accordion-button<?php echo $first ? '' : ' collapsed'; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#b2b-faq-panel-<?php echo esc_attr( $index ); ?>" aria-expanded="<?php echo $first ? 'true' : 'false'; ?>" aria-controls="b2b-faq-panel-<?php echo esc_attr( $index ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_' . $index . '_question' ) ); ?></button></h3><div id="b2b-faq-panel-<?php echo esc_attr( $index ); ?>" class="accordion-collapse collapse<?php echo $first ? ' show' : ''; ?>" aria-labelledby="b2b-faq-heading-<?php echo esc_attr( $index ); ?>" data-bs-parent="#b2b-faq-accordion"><div class="accordion-body"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_' . $index . '_answer' ) ); ?></div></div></div><?php endfor; ?></div></div></div></div></section>
<?php
/** B2B FAQ. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! fragrance_trade_show_section( 'b2b_show_faq' ) ) {
return;
}
?>
<section id="faqs" class="b2b-section faq-section"><div class="container"><div class="row g-5"><div class="col-lg-4"><p class="section-eyebrow"><?php esc_html_e( '常见问题', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_title' ) ); ?></h2><p><?php esc_html_e( '以下内容用于帮助您提前了解选择和施工注意事项。具体项目、价格、工期与质保,请以门店最终确认为准。', 'fragrance-trade' ); ?></p></div><div class="col-lg-8"><div class="accordion" id="b2b-faq-accordion"><?php for ( $index = 1; $index <= 8; $index++ ) : $first = 1 === $index; ?><div class="accordion-item"><h3 class="accordion-header" id="b2b-faq-heading-<?php echo esc_attr( $index ); ?>"><button class="accordion-button<?php echo $first ? '' : ' collapsed'; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#b2b-faq-panel-<?php echo esc_attr( $index ); ?>" aria-expanded="<?php echo $first ? 'true' : 'false'; ?>" aria-controls="b2b-faq-panel-<?php echo esc_attr( $index ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_' . $index . '_question' ) ); ?></button></h3><div id="b2b-faq-panel-<?php echo esc_attr( $index ); ?>" class="accordion-collapse collapse<?php echo $first ? ' show' : ''; ?>" aria-labelledby="b2b-faq-heading-<?php echo esc_attr( $index ); ?>" data-bs-parent="#b2b-faq-accordion"><div class="accordion-body"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_faq_' . $index . '_answer' ) ); ?></div></div></div><?php endfor; ?></div></div></div></div></section>
+10 -6
View File
@@ -1,5 +1,9 @@
<?php
/** Hero — minimalist luxury. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$title = fragrance_trade_get_mod( 'b2b_hero_title' );
?>
<section id="intro" class="b2b-hero">
@@ -10,13 +14,13 @@ $title = fragrance_trade_get_mod( 'b2b_hero_title' );
<h1><?php echo esc_html( $title ); ?></h1>
<p class="b2b-hero-lead"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_hero_text' ) ); ?></p>
<div class="d-flex flex-wrap gap-3 mt-4">
<a class="btn btn-b2b-primary btn-lg" href="<?php echo esc_url( fragrance_trade_get_mod( 'b2b_hero_primary_url' ) ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_hero_primary_label' ) ); ?></a>
<a class="btn btn-b2b-outline btn-lg" href="<?php echo esc_url( fragrance_trade_get_mod( 'b2b_hero_secondary_url' ) ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_hero_secondary_label' ) ); ?></a>
<a class="btn btn-b2b-primary btn-lg" href="<?php echo esc_url( fragrance_trade_resolve_url( fragrance_trade_get_mod( 'b2b_hero_primary_url' ) ) ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_hero_primary_label' ) ); ?></a>
<a class="btn btn-b2b-outline btn-lg" href="<?php echo esc_url( fragrance_trade_resolve_url( fragrance_trade_get_mod( 'b2b_hero_secondary_url' ) ) ); ?>"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_hero_secondary_label' ) ); ?></a>
</div>
<ul class="hero-proof-list" aria-label="<?php esc_attr_e( '施工服务', 'fragrance-trade' ); ?>">
<li><?php esc_html_e( '选膜咨询', 'fragrance-trade' ); ?></li>
<li><?php esc_html_e( '专业施工', 'fragrance-trade' ); ?></li>
<li><?php esc_html_e( '售后保障', 'fragrance-trade' ); ?></li>
<ul class="hero-proof-list" aria-label="<?php esc_attr_e( '服务步骤', 'fragrance-trade' ); ?>">
<li><?php esc_html_e( '需求沟通', 'fragrance-trade' ); ?></li>
<li><?php esc_html_e( '方案确认', 'fragrance-trade' ); ?></li>
<li><?php esc_html_e( '施工交付', 'fragrance-trade' ); ?></li>
</ul>
</div>
</div>
+10 -6
View File
@@ -1,10 +1,15 @@
<?php
/** Service teaser on the homepage. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$service_query = new WP_Query(
array(
'post_type' => 'service',
'posts_per_page' => 6,
'post_status' => 'publish',
'no_found_rows' => true,
)
);
if ( ! $service_query->have_posts() ) {
@@ -15,24 +20,23 @@ if ( ! $service_query->have_posts() ) {
<div class="container">
<div class="section-heading text-center mx-auto">
<p class="section-eyebrow"><?php esc_html_e( '服务项目', 'fragrance-trade' ); ?></p>
<h2><?php esc_html_e( '为您的爱车提供的贴膜服务', 'fragrance-trade' ); ?></h2>
<h2><?php esc_html_e( '按车型与需求选择贴膜方案', 'fragrance-trade' ); ?></h2>
</div>
<div class="capability-grid mt-5">
<?php
$count = 1;
while ( $service_query->have_posts() ) :
$service_query->the_post();
$image = get_post_meta( get_the_ID(), '_service_image', true );
$fallback = 'products/placeholder-0' . ( $count < 10 ? $count : 1 ) . '.svg';
$img = $image ? $image : fragrance_trade_asset_uri( $fallback );
$image = get_post_meta( get_the_ID(), '_service_image', true );
$fallback = 'images/products/placeholder-0' . ( $count < 10 ? $count : 1 ) . '.svg';
?>
<article class="capability-card">
<div class="capability-image"><a href="<?php the_permalink(); ?>"><img src="<?php echo esc_url( $img ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid" loading="lazy" decoding="async"></a></div>
<div class="capability-image"><a href="<?php the_permalink(); ?>"><?php if ( has_post_thumbnail() ) : ?><?php the_post_thumbnail( 'fragrance-capability', array( 'class' => 'img-fluid', 'loading' => 'lazy', 'decoding' => 'async' ) ); ?><?php else : ?><img src="<?php echo esc_url( $image ? $image : fragrance_trade_asset_uri( $fallback ) ); ?>" alt="<?php the_title_attribute(); ?>" class="img-fluid" loading="lazy" decoding="async"><?php endif; ?></a></div>
<div class="capability-body">
<p class="capability-label"><?php esc_html_e( '贴膜服务', 'fragrance-trade' ); ?></p>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p><?php echo esc_html( get_the_excerpt() ); ?></p>
<a href="<?php echo esc_url( home_url( '/contact/?service=' . rawurlencode( get_the_title() ) ) ); ?>" class="btn btn-b2b-outline"><?php esc_html_e( '预约这项服务', 'fragrance-trade' ); ?></a>
<a href="<?php echo esc_url( home_url( '/contact/' ) ); ?>" class="btn btn-b2b-outline"><?php esc_html_e( '联系门店', 'fragrance-trade' ); ?></a>
</div>
</article>
<?php
+6 -1
View File
@@ -1,4 +1,9 @@
<?php /** Trust metrics — minimalist. @package Fragrance_Trade */ ?>
<?php
/** Trust metrics — minimalist. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<section class="trust-strip" aria-labelledby="trust-strip-title">
<div class="container">
<h2 id="trust-strip-title" class="visually-hidden"><?php echo esc_html( fragrance_trade_get_mod( 'b2b_trust_title' ) ); ?></h2>
+6 -3
View File
@@ -1,9 +1,12 @@
<?php
/** Factory tour video. @package Fragrance_Trade */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! fragrance_trade_show_section( 'b2b_show_video' ) ) { return; }
$url = esc_url( fragrance_trade_get_mod( 'b2b_video_url', '' ) );
$lightbox = $url && preg_match( '/(youtube(?:-nocookie)?\.com|youtu\.be|vimeo\.com)/i', $url );
$url = fragrance_trade_get_mod( 'b2b_video_url', '' );
?>
<section class="factory-video-section">
<div class="container"><div class="factory-video-card"><img src="<?php echo esc_url( fragrance_trade_image_uri( 'b2b_video_image', 'placeholder-video.svg' ) ); ?>" alt="<?php esc_attr_e( '汽车贴膜施工流程示意图', 'fragrance-trade' ); ?>" width="1600" height="899" loading="lazy" decoding="async"><div class="factory-video-overlay"><p class="section-eyebrow"><?php esc_html_e( '门店参观', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_video_title' ) ); ?></h2><p><?php echo esc_html( fragrance_trade_get_mod( 'b2b_video_text' ) ); ?></p><p class="factory-video-disclosure"><?php esc_html_e( '流程示意图 — 如需查看实拍素材请联系我们。', 'fragrance-trade' ); ?></p><?php if ( $url ) : ?><a class="video-play-link<?php echo $lightbox ? ' youtube' : ''; ?>" href="<?php echo esc_url( $url ); ?>" target="_blank" rel="noopener noreferrer"><svg width="26" height="30" aria-hidden="true"><use href="#play"></use></svg><span><?php esc_html_e( '观看门店视频', 'fragrance-trade' ); ?></span></a><?php else : ?><a class="btn btn-b2b-light" href="<?php echo esc_url( home_url( '/contact/' ) ); ?>"><?php esc_html_e( '获取实拍门店素材', 'fragrance-trade' ); ?></a><?php endif; ?></div></div></div>
<div class="container"><div class="factory-video-card"><img src="<?php echo esc_url( fragrance_trade_image_uri( 'b2b_video_image', 'placeholder-video.svg' ) ); ?>" alt="<?php esc_attr_e( '汽车贴膜施工流程示意图', 'fragrance-trade' ); ?>" width="1600" height="899" loading="lazy" decoding="async"><div class="factory-video-overlay"><p class="section-eyebrow"><?php esc_html_e( '施工流程', 'fragrance-trade' ); ?></p><h2><?php echo esc_html( fragrance_trade_get_mod( 'b2b_video_title' ) ); ?></h2><p><?php echo esc_html( fragrance_trade_get_mod( 'b2b_video_text' ) ); ?></p><p class="factory-video-disclosure"><?php esc_html_e( '页面图片为流程示意;门店实拍内容以实际上传为准。', 'fragrance-trade' ); ?></p><?php if ( $url ) : ?><a class="video-play-link" href="<?php echo esc_url( $url ); ?>" target="_blank" rel="noopener noreferrer"><svg width="26" height="30" aria-hidden="true"><use href="#play"></use></svg><span><?php esc_html_e( '观看门店视频', 'fragrance-trade' ); ?></span></a><?php else : ?><a class="btn btn-b2b-light" href="<?php echo esc_url( home_url( '/contact/' ) ); ?>"><?php esc_html_e( '联系门店查看实拍', 'fragrance-trade' ); ?></a><?php endif; ?></div></div></div>
</section>