更新官网首页、服务与案例页面及配套视觉资源

这个提交包含在:
wikiboss
2026-11-05 14:58:25 +08:00
父节点 7ce37ad995
当前提交 77495769c4
共有 75 个文件被更改,包括 3025 次插入 和 8735 次删除

查看文件

@@ -82,9 +82,9 @@ class CasesPageTest
$hasFilter = (strpos($this->htmlContent, 'nhc-case-filter') !== false || strpos($this->htmlContent, '全部案例') !== false);
$this->assert($hasFilter, "案例页必须包含【筛选】(多维业务/行业分类筛选器)板块");
$hasChallenge = (strpos($this->htmlContent, '业务挑战') !== false || strpos($this->htmlContent, 'CHALLENGE') !== false);
$hasSolution = (strpos($this->htmlContent, '技术方案') !== false || strpos($this->htmlContent, 'SOLUTION') !== false || strpos($this->htmlContent, '解决方案') !== false);
$hasResult = (strpos($this->htmlContent, '成果验证') !== false || strpos($this->htmlContent, 'RESULT') !== false || strpos($this->htmlContent, '交付成效') !== false);
$hasChallenge = (strpos($this->htmlContent, '遇到的问题') !== false || strpos($this->htmlContent, '业务挑战') !== false || strpos($this->htmlContent, 'CHALLENGE') !== false);
$hasSolution = (strpos($this->htmlContent, '我们的做法') !== false || strpos($this->htmlContent, '技术方案') !== false || strpos($this->htmlContent, '实施方案') !== false || strpos($this->htmlContent, 'SOLUTION') !== false || strpos($this->htmlContent, '解决方案') !== false);
$hasResult = (strpos($this->htmlContent, '交付结果') !== false || strpos($this->htmlContent, '成果验证') !== false || strpos($this->htmlContent, '交付内容') !== false || strpos($this->htmlContent, 'RESULT') !== false || strpos($this->htmlContent, '交付成效') !== false);
$this->assert($hasChallenge && $hasSolution && $hasResult, "案例页必须深度包含【挑战、方案、结果】三位一体标杆案例档案");
$hasData = (strpos($this->htmlContent, 'nhc-case-metrics') !== false || strpos($this->htmlContent, '数据验证') !== false || strpos($this->htmlContent, '成果指标') !== false);
@@ -93,9 +93,9 @@ class CasesPageTest
public function testNoAiCharacteristics()
{
// 必须具备真实量化指标(百分比、单量等)
$hasMetrics = (strpos($this->htmlContent, '%') !== false && (strpos($this->htmlContent, '10W') !== false || strpos($this->htmlContent, '300') !== false || strpos($this->htmlContent, '50') !== false));
$this->assert($hasMetrics, "去AI味道:案例必须具备真实可信的量化业务指标数据");
// 必须具备真实可信的业务机制与指标(不使用无出处的百分比/单量)
$hasMetrics = (strpos($this->htmlContent, 'nhc-case-metrics') !== false && (strpos($this->htmlContent, '自动分单') !== false || strpos($this->htmlContent, '动态 BOM') !== false || strpos($this->htmlContent, '断网断电仍可收银') !== false));
$this->assert($hasMetrics, "去AI味道:案例必须具备真实可信的业务机制与指标");
// 覆盖重点实体行业(商贸零售、智能制造、政企服务等)
$hasRealIndustries = (strpos($this->htmlContent, '商贸') !== false || strpos($this->htmlContent, '零售') !== false || strpos($this->htmlContent, '制造') !== false);
@@ -122,7 +122,7 @@ class CasesPageTest
$this->assert(!empty($this->mobileHtmlContent), "移动端案例模板 list_e.html 文件必须存在");
$this->assert(strpos($this->mobileHtmlContent, '纳海川') !== false, "移动端模板必须包含品牌名【纳海川】");
$this->assert(strpos($this->mobileHtmlContent, 'nhc-case-filter') !== false, "移动端模板必须包含多维案例筛选器");
$this->assert(strpos($this->mobileHtmlContent, 'CHALLENGE') !== false || strpos($this->mobileHtmlContent, '业务挑战') !== false, "移动端模板必须包含标杆案例挑战/方案/结果");
$this->assert(strpos($this->mobileHtmlContent, '遇到的问题') !== false || strpos($this->mobileHtmlContent, 'CHALLENGE') !== false || strpos($this->mobileHtmlContent, '业务挑战') !== false, "移动端模板必须包含标杆案例挑战/方案/结果");
$this->assert(strpos($this->mobileHtmlContent, 'nhc-case-metrics') !== false, "移动端模板必须包含数据指标墙");
}
}

查看文件

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
本地测试驱动运行器 (Local TDD Test Runner)
与各 PHP 单元测试断言 100% 对齐,提供极速本地验证反馈
"""
import os
import re
import sys
@@ -13,6 +13,15 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if BASE_DIR not in sys.path:
sys.path.insert(0, BASE_DIR)
def _read(path):
"""读取文本文件;文件不存在时返回空字符串。"""
if not os.path.exists(path):
return ""
with open(path, encoding="utf-8") as f:
return f.read()
class TestResult:
def __init__(self, name):
self.name = name
@@ -34,280 +43,486 @@ class TestResult:
print(msg)
return self.failed == 0
def test_cases_page():
res = TestResult("案例独立页 (CasesPage)")
list_html_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_case_show', 'list.html')
list_e_html_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_case_show', 'list_e.html')
css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css')
list_html_path = os.path.join(
BASE_DIR, "addons", "official", "view", "web", "official_case_show", "list.html"
)
list_e_html_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_case_show",
"list_e.html",
)
css_path = os.path.join(
BASE_DIR, "public", "assets", "addons", "official", "css", "modern_nhc.css"
)
html = open(list_html_path, 'r', encoding='utf-8').read() if os.path.exists(list_html_path) else ''
mobile_html = open(list_e_html_path, 'r', encoding='utf-8').read() if os.path.exists(list_e_html_path) else ''
css = open(css_path, 'r', encoding='utf-8').read() if os.path.exists(css_path) else ''
html = _read(list_html_path) if os.path.exists(list_html_path) else ""
mobile_html = _read(list_e_html_path) if os.path.exists(list_e_html_path) else ""
css = _read(css_path) if os.path.exists(css_path) else ""
res.assert_true('纳海川' in html, "PC 案例页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r'纳川(?!海)', html), "PC 案例页严禁错误简称为【纳川】")
res.assert_true("纳海川" in html, "PC 案例页必须明确包含品牌名称【纳海川】")
res.assert_true(
not re.search(r"纳川(?!海)", html), "PC 案例页严禁错误简称为【纳川】"
)
has_filter = 'nhc-case-filter' in html or '全部案例' in html
has_filter = "nhc-case-filter" in html or "全部案例" in html
res.assert_true(has_filter, "PC 案例页必须包含【筛选】板块")
has_chal = '业务挑战' in html or 'CHALLENGE' in html
has_sol = '技术方案' in html or 'SOLUTION' in html
has_res = '成果验证' in html or 'RESULT' in html
res.assert_true(has_chal and has_sol and has_res, "PC 案例页必须包含【挑战、方案、结果】档案")
res.assert_true('nhc-case-metrics' in html or '数据验证' in html, "PC 案例页必须包含【数据】板块")
has_chal = "遇到的问题" in html or "业务挑战" in html or "CHALLENGE" in html
has_sol = any(label in html for label in ("我们的做法", "技术方案", "实施方案", "SOLUTION"))
has_res = any(label in html for label in ("交付结果", "成果验证", "交付内容", "RESULT"))
res.assert_true(
has_chal and has_sol and has_res, "PC 案例页必须包含【挑战、方案、结果】档案"
)
res.assert_true(
"nhc-case-metrics" in html or "数据验证" in html,
"PC 案例页必须包含【数据】板块",
)
has_metrics = 'nhc-case-metrics' in html and ('自动化分单' in html or '断网收银' in html or '动态BOM' in html)
has_metrics = "nhc-case-metrics" in html and (
"自动分单" in html
or "断网断电仍可收银" in html
or "动态 BOM" in html
or "动态BOM" in html
)
res.assert_true(has_metrics, "去AI味道:具备真实可信的落地业务与架构机制")
has_emoji = bool(re.search(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]', html))
has_emoji = bool(
re.search(
r"[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]",
html,
)
)
res.assert_true(not has_emoji, "案例页严禁使用任何 emoji 表情符号")
res.assert_true('#2563EB' in css or '#2563eb' in css, "沿用科技蓝 #2563EB 主色规范")
res.assert_true('SimSun' in css or 'Songti' in css or 'Noto Serif SC' in css, "沿用宋体标题规范")
res.assert_true("#2563EB" in css or "#2563eb" in css, "沿用科技蓝 #2563EB 主色规范")
res.assert_true(
"SimSun" in css or "Songti" in css or "Noto Serif SC" in css, "沿用宋体标题规范"
)
res.assert_true(bool(mobile_html), "移动端案例模板 list_e.html 必须存在")
if mobile_html:
res.assert_true('纳海川' in mobile_html, "移动端模板必须包含品牌名【纳海川】")
res.assert_true('nhc-case-filter' in mobile_html, "移动端模板必须包含多维案例筛选器")
res.assert_true('CHALLENGE' in mobile_html or '业务挑战' in mobile_html, "移动端模板必须包含标杆案例挑战/方案/结果")
res.assert_true('nhc-case-metrics' in mobile_html, "移动端模板必须包含标杆案例量化指标")
res.assert_true("纳海川" in mobile_html, "移动端模板必须包含品牌名【纳海川】")
res.assert_true(
"nhc-case-filter" in mobile_html, "移动端模板必须包含多维案例筛选器"
)
res.assert_true(
"遇到的问题" in mobile_html
or "CHALLENGE" in mobile_html
or "业务挑战" in mobile_html,
"移动端模板必须包含标杆案例挑战/方案/结果",
)
res.assert_true(
"nhc-case-metrics" in mobile_html, "移动端模板必须包含标杆案例量化指标"
)
return res.summary()
def test_services_page():
res = TestResult("服务独立页 (ServicesPage)")
svc_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'service_page.html')
list_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'list.html')
css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css')
html = ''
svc_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_product",
"service_page.html",
)
list_path = os.path.join(
BASE_DIR, "addons", "official", "view", "web", "official_product", "list.html"
)
html = ""
if os.path.exists(svc_path):
html += open(svc_path, 'r', encoding='utf-8').read() + '\n'
html += _read(svc_path) + "\n"
if os.path.exists(list_path):
html += open(list_path, 'r', encoding='utf-8').read() + '\n'
css = open(css_path, 'r', encoding='utf-8').read() if os.path.exists(css_path) else ''
html += _read(list_path) + "\n"
res.assert_true('纳海川' in html, "服务页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r'纳川(?!海)', html), "服务页严禁错误简称为【纳川】")
res.assert_true('软件开发' in html and 'APP' in html and '智能体' in html, "服务页必须涵盖软件开发、APP定制、智能体开发")
res.assert_true("纳海川" in html, "服务页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r"纳川(?!海)", html), "服务页严禁错误简称为【纳川】")
res.assert_true(
"软件开发" in html and "APP" in html and "智能体" in html,
"服务页必须涵盖软件开发、APP定制、智能体开发",
)
has_cat = 'nhc-services-categories' in html or '服务分类' in html or '服务矩阵' in html
has_cat = (
"nhc-services-categories" in html or "服务分类" in html or "服务矩阵" in html
)
res.assert_true(has_cat, "包含【分类】板块")
has_cap = 'nhc-tech-capabilities' in html or '技术能力' in html or '技术底座' in html
has_cap = (
"nhc-tech-capabilities" in html or "技术能力" in html or "技术底座" in html
)
res.assert_true(has_cap, "包含【能力】板块")
has_proc = 'nhc-delivery-process' in html or '交付流程' in html or '研发流程' in html
has_proc = (
"nhc-delivery-process" in html or "交付流程" in html or "研发流程" in html
)
res.assert_true(has_proc, "包含【流程】板块")
has_deliv = 'nhc-deliverables' in html or '交付物' in html or '交付标准' in html
has_deliv = "nhc-deliverables" in html or "交付物" in html or "交付标准" in html
res.assert_true(has_deliv, "包含【交付】清单")
has_faq = 'nhc-faq' in html or '常见问答' in html or '技术问答' in html
has_faq = "nhc-faq" in html or "常见问答" in html or "技术问答" in html
res.assert_true(has_faq, "包含【FAQ】板块")
return res.summary()
def test_products_page():
res = TestResult("产品独立页 (ProductsPage)")
prd_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'product_page.html')
list_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'list.html')
html = ''
prd_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_product",
"product_page.html",
)
list_path = os.path.join(
BASE_DIR, "addons", "official", "view", "web", "official_product", "list.html"
)
html = ""
if os.path.exists(prd_path):
html += open(prd_path, 'r', encoding='utf-8').read() + '\n'
html += _read(prd_path) + "\n"
if os.path.exists(list_path):
html += open(list_path, 'r', encoding='utf-8').read() + '\n'
html += _read(list_path) + "\n"
res.assert_true('纳海川' in html, "产品页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r'纳川(?!海)', html), "产品页严禁错误简称为【纳川】")
res.assert_true('商城' in html and '收银' in html and '进销存' in html and 'SaaS' in html, "产品页必须涵盖商城、收银、进销存、SaaS版本")
res.assert_true("纳海川" in html, "产品页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r"纳川(?!海)", html), "产品页严禁错误简称为【纳川】")
res.assert_true(
"商城" in html and "收银" in html and "进销存" in html and "SaaS" in html,
"产品页必须涵盖商城、收银、进销存、SaaS版本",
)
has_matrix = 'nhc-product-matrix' in html or '产品矩阵' in html or '商业矩阵' in html
has_matrix = (
"nhc-product-matrix" in html or "产品矩阵" in html or "商业矩阵" in html
)
res.assert_true(has_matrix, "包含【矩阵】板块")
has_features = 'nhc-product-features' in html or '功能架构' in html or '核心功能' in html
has_features = (
"nhc-product-features" in html or "功能架构" in html or "核心功能" in html
)
res.assert_true(has_features, "包含【功能】板块")
has_editions = 'nhc-product-editions' in html or '版本对比' in html or '版本选型' in html
has_editions = (
"nhc-product-editions" in html or "版本对比" in html or "版本选型" in html
)
res.assert_true(has_editions, "包含【版本】板块")
has_pricing = 'nhc-product-pricing' in html or '定价' in html or '部署模式' in html or '商业授权' in html
has_pricing = (
"nhc-product-pricing" in html
or "定价" in html
or "部署模式" in html
or "商业授权" in html
)
res.assert_true(has_pricing, "包含【定价】板块")
has_demo = 'nhc-product-demo' in html or '在线演示' in html or '预约演示' in html or '申请演示' in html
has_demo = (
"nhc-product-demo" in html
or "在线演示" in html
or "预约演示" in html
or "申请演示" in html
)
res.assert_true(has_demo, "包含【演示】板块")
return res.summary()
def test_nav_megamenu():
res = TestResult("导航二级卡片面板 (NavMegaMenu)")
nav_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_common', 'pc', 'nav.html')
css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css')
html = open(nav_path, 'r', encoding='utf-8').read() if os.path.exists(nav_path) else ''
css = open(css_path, 'r', encoding='utf-8').read() if os.path.exists(css_path) else ''
nav_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_common",
"pc",
"nav.html",
)
css_path = os.path.join(
BASE_DIR, "public", "assets", "addons", "official", "css", "modern_nhc.css"
)
html = _read(nav_path) if os.path.exists(nav_path) else ""
css = _read(css_path) if os.path.exists(css_path) else ""
res.assert_true('nhc-has-dropdown' in html, "导航栏必须具备 nhc-has-dropdown 下拉菜单触发类")
res.assert_true('nhc-mega-panel' in html, "导航栏必须具备 nhc-mega-panel 二级卡片面板容器")
res.assert_true('软件开发' in html and '智能体开发' in html, "服务二级面板包含核心服务")
res.assert_true('商城' in html and '收银' in html and '进销存' in html and 'SaaS' in html, "产品二级面板包含核心产品")
res.assert_true('.nhc-mega-panel' in css, "CSS 包含 .nhc-mega-panel 卡片面板样式")
res.assert_true('.nhc-has-dropdown:hover' in css, "CSS 包含鼠标悬停触发规则")
res.assert_true(
"nhc-has-dropdown" in html, "导航栏必须具备 nhc-has-dropdown 下拉菜单触发类"
)
res.assert_true(
"nhc-mega-panel" in html, "导航栏必须具备 nhc-mega-panel 二级卡片面板容器"
)
res.assert_true(
"软件开发" in html and "智能体开发" in html, "服务二级面板包含核心服务"
)
res.assert_true(
"商城" in html and "收银" in html and "进销存" in html and "SaaS" in html,
"产品二级面板包含核心产品",
)
res.assert_true(".nhc-mega-panel" in css, "CSS 包含 .nhc-mega-panel 卡片面板样式")
res.assert_true(".nhc-has-dropdown:hover" in css, "CSS 包含鼠标悬停触发规则")
return res.summary()
def test_about_page():
res = TestResult("关于我们独立页 (AboutPage)")
single_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'single.html')
single_e_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'single_e.html')
css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css')
single_path = os.path.join(
BASE_DIR, "addons", "official", "view", "web", "official_home", "single.html"
)
single_e_path = os.path.join(
BASE_DIR, "addons", "official", "view", "web", "official_home", "single_e.html"
)
html = open(single_path, 'r', encoding='utf-8').read() if os.path.exists(single_path) else ''
mobile_html = open(single_e_path, 'r', encoding='utf-8').read() if os.path.exists(single_e_path) else ''
css = open(css_path, 'r', encoding='utf-8').read() if os.path.exists(css_path) else ''
html = _read(single_path) if os.path.exists(single_path) else ""
mobile_html = _read(single_e_path) if os.path.exists(single_e_path) else ""
res.assert_true('纳海川' in html, "PC 关于我们页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r'纳川(?!海)', html), "PC 关于我们页严禁错误简称为【纳川】")
res.assert_true("纳海川" in html, "PC 关于我们页必须明确包含品牌名称【纳海川】")
res.assert_true(
not re.search(r"纳川(?!海)", html), "PC 关于我们页严禁错误简称为【纳川】"
)
has_brand = 'nhc-about-brand' in html or '工程哲学' in html or '品牌' in html
has_brand = "nhc-about-brand" in html or "工程哲学" in html or "品牌" in html
res.assert_true(has_brand, "必须包含【品牌】(品牌渊源与东方工程哲学)板块")
has_team = 'nhc-about-team' in html or '技术委员会' in html or '核心团队' in html
has_team = "nhc-about-team" in html or "技术委员会" in html or "核心团队" in html
res.assert_true(has_team, "必须包含【团队】(技术委员会专家与核心团队)板块")
has_certs = 'nhc-about-qualifications' in html or '软件著作权' in html or '合规体系' in html
has_certs = (
"nhc-about-qualifications" in html or "软件著作权" in html or "合规体系" in html
)
res.assert_true(has_certs, "必须包含【资质】(权威资质、软著资产与安全合规体系)板块")
has_milestones = '2016' in html or '2019' in html or '2024' in html or '发展历程' in html
has_milestones = (
"2016" in html or "2019" in html or "2024" in html or "发展历程" in html
)
res.assert_true(has_milestones, "去AI味道:展示具体发展历程或里程碑")
has_tech = '架构师' in html or '全栈' in html or '智能体' in html
has_tech = "架构师" in html or "全栈" in html or "智能体" in html
res.assert_true(has_tech, "去AI味道:展示严谨技术职称与专业领域")
has_certs_concrete = 'ISO' in html or '著作权' in html or '等保' in html
has_certs_concrete = "ISO" in html or "著作权" in html or "等保" in html
res.assert_true(has_certs_concrete, "去AI味道:展示具体行业认证体系与软著资产")
has_emoji = bool(re.search(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]', html))
has_emoji = bool(
re.search(
r"[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]",
html,
)
)
res.assert_true(not has_emoji, "严禁使用任何 emoji 表情符号")
res.assert_true(bool(mobile_html), "移动端关于我们模板 single_e.html 必须存在")
if mobile_html:
res.assert_true('纳海川' in mobile_html, "移动端模板包含品牌名【纳海川】")
res.assert_true('团队' in mobile_html or '专家' in mobile_html, "移动端模板包含核心团队介绍")
res.assert_true('资质' in mobile_html or '著作权' in mobile_html, "移动端模板包含资质认证板块")
res.assert_true("纳海川" in mobile_html, "移动端模板包含品牌名【纳海川】")
res.assert_true(
"团队" in mobile_html or "专家" in mobile_html, "移动端模板包含核心团队介绍"
)
res.assert_true(
"资质" in mobile_html or "著作权" in mobile_html,
"移动端模板包含资质认证板块",
)
return res.summary()
def test_contact_page():
res = TestResult("联系我们独立页 (ContactPage)")
contact_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_online_message', 'list.html')
contact_e_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_online_message', 'list_e.html')
css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css')
contact_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_online_message",
"list.html",
)
contact_e_path = os.path.join(
BASE_DIR,
"addons",
"official",
"view",
"web",
"official_online_message",
"list_e.html",
)
html = open(contact_path, 'r', encoding='utf-8').read() if os.path.exists(contact_path) else ''
mobile_html = open(contact_e_path, 'r', encoding='utf-8').read() if os.path.exists(contact_e_path) else ''
css = open(css_path, 'r', encoding='utf-8').read() if os.path.exists(css_path) else ''
html = _read(contact_path) if os.path.exists(contact_path) else ""
mobile_html = _read(contact_e_path) if os.path.exists(contact_e_path) else ""
res.assert_true('纳海川' in html, "PC 联系我们页必须明确包含品牌名称【纳海川】")
res.assert_true(not re.search(r'纳川(?!海)', html), "PC 联系我们页严禁错误简称为【纳川】")
res.assert_true("纳海川" in html, "PC 联系我们页必须明确包含品牌名称【纳海川】")
res.assert_true(
not re.search(r"纳川(?!海)", html), "PC 联系我们页严禁错误简称为【纳川】"
)
has_form = '<form' in html and 'name="phone"' in html and 'name="title"' in html
has_form = "<form" in html and 'name="phone"' in html and 'name="title"' in html
res.assert_true(has_form, "必须包含【表单】板块")
has_map = 'nhc-contact-map' in html or '地图' in html or '园区' in html or '大厦' in html
has_map = (
"nhc-contact-map" in html or "地图" in html or "园区" in html or "大厦" in html
)
res.assert_true(has_map, "必须包含【地图】(办公地址与交通指引/地图视窗)板块")
has_phone = '13984036826' in html or 'tel:' in html
has_phone = "13984036826" in html or "tel:" in html
res.assert_true(has_phone, "必须包含【电话】板块")
has_addr = '南明区' in html or '花果园' in html or '经开区' in html
has_addr = "南明区" in html or "花果园" in html or "经开区" in html
res.assert_true(has_addr, "去AI味道:展示具体真实物理实体地址")
has_details = 'server@gynhc.com' in html or '09:00' in html or 'SLA' in html
has_details = "server@gynhc.com" in html or "09:00" in html or "SLA" in html
res.assert_true(has_details, "去AI味道:真实企业邮箱与明确响应时效承诺")
has_emoji = bool(re.search(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]', html))
has_emoji = bool(
re.search(
r"[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\u2600-\u26FF\u2700-\u27BF]",
html,
)
)
res.assert_true(not has_emoji, "严禁使用任何 emoji 表情符号")
res.assert_true(bool(mobile_html), "移动端联系我们模板 list_e.html 必须存在")
if mobile_html:
res.assert_true('纳海川' in mobile_html, "移动端模板包含品牌名【纳海川】")
res.assert_true('<form' in mobile_html, "移动端模板包含需求提交表单")
res.assert_true('13984036826' in mobile_html or 'tel:' in mobile_html, "移动端模板包含电话直拨")
res.assert_true("纳海川" in mobile_html, "移动端模板包含品牌名【纳海川】")
res.assert_true("<form" in mobile_html, "移动端模板包含需求提交表单")
res.assert_true(
"13984036826" in mobile_html or "tel:" in mobile_html,
"移动端模板包含电话直拨",
)
return res.summary()
def test_no_ai_flavor_suite():
res = TestResult("去AI味专项测试 (NoAiFlavor)")
from tests.test_no_ai_flavor import TestNoAiFlavor
suite = unittest.TestLoader().loadTestsFromTestCase(TestNoAiFlavor)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"去AI味全量断言通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"去AI味全量断言通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_client_rigor_suite():
res = TestResult("客户严谨度与大厂背书专项测试 (ClientRigor)")
from tests.test_client_rigor_enhancements import TestClientRigorEnhancements
suite = unittest.TestLoader().loadTestsFromTestCase(TestClientRigorEnhancements)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"客户视角严谨度断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"客户视角严谨度断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_ad_law_compliance_suite():
res = TestResult("中国广告法合规专项测试 (AdLawCompliance)")
from tests.test_ad_law_compliance import TestAdLawCompliance
suite = unittest.TestLoader().loadTestsFromTestCase(TestAdLawCompliance)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"中国广告法合规断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"中国广告法合规断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_natural_copywriting_suite():
res = TestResult("务实工程文案专项测试 (NaturalCopywriting)")
from tests.test_natural_copywriting import TestNaturalCopywriting
suite = unittest.TestLoader().loadTestsFromTestCase(TestNaturalCopywriting)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"务实工程文案断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"务实工程文案断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_homepage_button_links_suite():
res = TestResult("首页按钮跳转与链路专项测试 (HomepageButtonLinks)")
from tests.test_homepage_button_links import HomepageButtonLinksTest
suite = unittest.TestLoader().loadTestsFromTestCase(HomepageButtonLinksTest)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"首页所有按钮点击与跳转断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"首页所有按钮点击与跳转断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_journalism_and_articles_suite():
res = TestResult("新闻资讯与文章深度专项测试 (JournalismAndArticles)")
from tests.test_journalism_and_articles import TestJournalismAndArticles
suite = unittest.TestLoader().loadTestsFromTestCase(TestJournalismAndArticles)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"新闻资讯与文章深度断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"新闻资讯与文章深度断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_dedicated_service_pages_suite():
res = TestResult("三大服务独立页专项测试 (DedicatedServicePages)")
from tests.test_dedicated_service_pages import DedicatedServicePagesTest
suite = unittest.TestLoader().loadTestsFromTestCase(DedicatedServicePagesTest)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"三大服务独立页断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"三大服务独立页断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_concise_showcase_images_suite():
res = TestResult("配图简洁性与去文字化专项测试 (ConciseShowcaseImages)")
from tests.test_concise_showcase_images import ConciseShowcaseImagesTest
suite = unittest.TestLoader().loadTestsFromTestCase(ConciseShowcaseImagesTest)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"配图简洁性与去文字化断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"配图简洁性与去文字化断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_plain_and_concise_copywriting_suite():
res = TestResult("通俗易懂与去AI味去啰嗦专项测试 (PlainAndConciseCopywriting)")
from tests.test_plain_and_concise_copywriting import TestPlainAndConciseCopywriting
suite = unittest.TestLoader().loadTestsFromTestCase(TestPlainAndConciseCopywriting)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"通俗易懂与去AI味去啰嗦断言全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"通俗易懂与去AI味去啰嗦断言全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def test_dedicated_page_illustrations_suite():
res = TestResult("独立页面精美视觉配图专项测试 (DedicatedPageIllustrations)")
from tests.test_dedicated_page_illustrations import TestDedicatedPageIllustrations
suite = unittest.TestLoader().loadTestsFromTestCase(TestDedicatedPageIllustrations)
runner = unittest.TextTestRunner(verbosity=0)
test_result = runner.run(suite)
res.assert_true(test_result.wasSuccessful(), f"独立页面精美视觉配图全部通过 (共 {test_result.testsRun} 项)")
res.assert_true(
test_result.wasSuccessful(),
f"独立页面精美视觉配图全部通过 (共 {test_result.testsRun} 项)",
)
return res.summary()
def main():
import unittest
results = [
test_cases_page(),
test_services_page(),
@@ -324,12 +539,10 @@ def main():
test_dedicated_service_pages_suite(),
test_concise_showcase_images_suite(),
test_plain_and_concise_copywriting_suite(),
test_dedicated_page_illustrations_suite()
test_dedicated_page_illustrations_suite(),
]
sys.exit(0 if all(results) else 1)
if __name__ == '__main__':
if __name__ == "__main__":
main()

查看文件

@@ -33,10 +33,9 @@ class TestClientRigorEnhancements(unittest.TestCase):
self.product_html = f.read()
def test_case_interface_preview_and_acceptance(self):
"""标杆案例必须具备微缩系统界面特征与联合终验背书"""
# 案例页必须具备界面视窗或系统交互特征
self.assertTrue('nhc-case-preview-window' in self.cases_html or '系统功能界面' in self.cases_html or '界面预览' in self.cases_html,
"案例独立页必须包含系统功能界面视窗")
"""案例提供界面资料或明确标注的业务结构示意,并说明验收方式。"""
self.assertTrue('nhc-case-preview-window' in self.cases_html or '系统功能界面' in self.cases_html or '界面预览' in self.cases_html or '业务结构示意' in self.cases_html,
"案例独立页必须提供界面资料或业务结构示意")
# 必须包含客户终验与上线运行凭证
self.assertTrue('联合终验' in self.cases_html or '平稳运行' in self.cases_html or '验收' in self.cases_html,
"案例独立页必须包含明确的验收与生产运行记录")

查看文件

@@ -63,7 +63,7 @@ class DedicatedServicePagesTest(unittest.TestCase):
self.assertTrue("能力" in content or "技术" in content or "性能规格" in content, "必须包含移动核心能力板块")
self.assertTrue("流程" in content or "研发流程" in content, "必须包含端到端交付流程板块")
self.assertTrue("交付" in content or "交付物" in content or "交付标准" in content, "必须包含交付清单板块")
self.assertTrue("FAQ" in content or "问答" in content, "必须包含常见问题解答板块")
self.assertTrue("FAQ" in content or "问答" in content or "常见问题" in content, "必须包含常见问题解答板块")
# 移动特色真实能力
self.assertTrue("iOS" in content and "Android" in content and "微信" in content, "必须覆盖 iOS / Android 与微信生态")

查看文件

@@ -81,12 +81,10 @@ class HomepageButtonLinksTest(unittest.TestCase):
"收银系统【申请演示】必须精准跳转到产品独立页演示沙箱"
)
# SaaS版本「立即开通」必须跳往演示开通沙箱或预约
# SaaS版本「咨询开通」应指向联系预约,避免承诺点击后直接开通。
self.assertTrue(
re.search(r'href="\{:addon_url\(\'official/web\.official_product/list\',\[\':pid\'=>22,\':sid\'=>22\]\)\}#demo-sandbox"[^>]*>[\s\S]*?立即开通', self.pc_html) or
("demo-sandbox" in self.pc_html and "立即开通" in self.pc_html) or
("official_online_message/list" in self.pc_html and "立即开通" in self.pc_html),
"SaaS版本【立即开通】必须跳转到产品演示沙箱或咨询开通"
re.search(r'<a\s+[^>]*href="\{:addon_url\(\'official/web\.official_online_message/list\',[^\n]*?\)\}"[^>]*>\s*咨询开通', self.pc_html),
"SaaS版本【咨询开通】必须跳转到联系留言页"
)
def test_04_pc_case_cards_clickable(self):

查看文件

@@ -137,9 +137,9 @@ class TestNaturalCopywriting(unittest.TestCase):
# 案例页务实表达
self.assertIn(
"面临类似的业务系统瓶颈?我们可以提供针对性方案",
"你的业务也遇到类似问题?",
self.cases_html,
"案例页CTA必须直面业务痛点",
"案例页CTA必须直接回应客户问题",
)
# 关于我们与联系我们
@@ -284,10 +284,15 @@ class TestNaturalCopywriting(unittest.TestCase):
# 验证新优化的务实干练文案已生效
self.assertIn("成熟商业系统 · 支撑全渠道经营与业务协同", self.products_html)
self.assertIn("动态安全库存模型与自动补货采购建议", self.products_html)
self.assertIn(
"覆盖资料问答与业务办理 · 按流程办事的专业智能体", service_agent_html
)
self.assertIn("全链路敏捷交付 · 规范推进设计与上线", service_app_html)
self.assertIn("企业知识问答", service_agent_html)
self.assertIn("业务流程辅助", service_agent_html)
self.assertIn("检索增强可以降低错误风险,但不能保证所有回答都正确", service_agent_html)
self.assertNotIn("不会自己编造", service_agent_html)
self.assertNotIn("一张或两张显卡即可", service_agent_html)
self.assertIn("根据使用方式,选择合适的终端", service_app_html)
self.assertIn("应用审核结果与排期由平台决定", service_app_html)
self.assertNotIn("上架一次通过率", service_app_html)
self.assertNotIn("全生态", service_app_html)
self.assertIn("全量规范移交客户", self.services_html)