feat: release B2B Trade theme 2.1.0
@@ -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">
|
||||
|
||||
@@ -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 移除加载 | 彻底清理,但未来恢复需重写 |
|
||||
|
||||
> 推荐 A:inquiry.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. 保留仍在使用的 section:hero、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,确保可单独回滚。
|
||||
- 运营图片应通过特色图片或外观配置上传,不写入主题默认数据。
|
||||
- 默认主题包只提供中性占位素材。
|
||||
- 新前端依赖必须本地打包、记录版本与许可证,并经过无外部请求扫描。
|
||||
- 开发验证工具不应作为主题运行依赖进入生产请求路径。
|
||||
|
||||
@@ -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.x,WordPress 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_meta,10 篇文章 = 10 次查询,
|
||||
页面加载时会明显变慢。
|
||||
|
||||
建议:
|
||||
循环前用 get_post_meta( $post_ids, 'key', false ) 批量预取,
|
||||
或在循环内缓存结果。
|
||||
```
|
||||
|
||||
### 💭 细节级
|
||||
|
||||
```
|
||||
💭 [命名] 第 8 行:$d 变量名过于简短
|
||||
|
||||
考虑改为 $display_date 或 $post_date,6 个月后回来看能秒懂。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、当前项目待修复清单
|
||||
|
||||
基于 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 许可证随主题包发布。
|
||||
|
||||
@@ -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`。
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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' );
|
||||
?>
|
||||
<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; ?>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;}
|
||||
@@ -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 |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 32 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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();
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -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.
|
||||
@@ -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">© <?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,6 +4,10 @@
|
||||
*
|
||||
* @package Fragrance_Trade
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<main id="primary" class="site-main fragrance-homepage">
|
||||
|
||||
@@ -15,7 +15,6 @@ $fragrance_trade_modules = array(
|
||||
'helpers.php',
|
||||
'cpt.php',
|
||||
'customizer.php',
|
||||
'inquiry.php',
|
||||
);
|
||||
|
||||
foreach ( $fragrance_trade_modules as $fragrance_trade_module ) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$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',
|
||||
/** 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' ),
|
||||
);
|
||||
for ( $index = 1; $index <= count( $product_fallbacks ); $index++ ) {
|
||||
$title = fragrance_trade_get_mod( 'b2b_product_' . $index . '_title' );
|
||||
}
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
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 ( 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();
|
||||
update_option( 'fragrance_trade_setup_done', 1 );
|
||||
}
|
||||
add_action( 'after_switch_theme', 'fragrance_trade_setup_site_on_activation' );
|
||||
|
||||
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_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' );
|
||||
|
||||
@@ -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' ),
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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' )
|
||||
);
|
||||
|
||||
@@ -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' );
|
||||
@@ -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 );
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 ""
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = 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 ?: '郑州经济技术开发区经开第二大街与经南五路交叉口向西50米路南59号' )
|
||||
. 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>
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
*
|
||||
* @package Fragrance_Trade
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<main id="primary" class="site-main">
|
||||
|
||||
@@ -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">
|
||||
|
||||
|
Before Width: | Height: | Size: 374 KiB After Width: | Height: | Size: 224 KiB |
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
<?php
|
||||
/** Page content. @package Fragrance_Trade */
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
get_template_part( 'template-parts/content' );
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,7 +20,7 @@ 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
|
||||
@@ -23,16 +28,15 @@ if ( ! $service_query->have_posts() ) {
|
||||
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 );
|
||||
$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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||