diff --git a/addons/official/view/web/official_common/mobile/link.html b/addons/official/view/web/official_common/mobile/link.html index 088ba22..8cfb906 100644 --- a/addons/official/view/web/official_common/mobile/link.html +++ b/addons/official/view/web/official_common/mobile/link.html @@ -1,12 +1,15 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/addons/official/view/web/official_common/pc/link.html b/addons/official/view/web/official_common/pc/link.html index efbef0f..672a79c 100644 --- a/addons/official/view/web/official_common/pc/link.html +++ b/addons/official/view/web/official_common/pc/link.html @@ -1,6 +1,7 @@ + @@ -10,3 +11,5 @@ + + diff --git a/addons/official/view/web/official_common/pc/nav.html b/addons/official/view/web/official_common/pc/nav.html index fc95600..169b48b 100644 --- a/addons/official/view/web/official_common/pc/nav.html +++ b/addons/official/view/web/official_common/pc/nav.html @@ -3,45 +3,15 @@
- + -
+
菜单
diff --git a/addons/official/view/web/official_home/index.html b/addons/official/view/web/official_home/index.html index 0d1a36d..f2afc7b 100644 --- a/addons/official/view/web/official_home/index.html +++ b/addons/official/view/web/official_home/index.html @@ -1,31 +1,507 @@ -{extend name="web/official_common/pc/base" /} -{block name="css"} - - -{/block} -{block name="content"} +{extend name="web/official_common/pc/base" /} {block name="css"} + + +{/block} {block name="content"}
- -跳至服务内容 -
- 远山与庭院之间,蓝色玻璃曲线沿水面延展 -

纳海川科技 / 企业软件服务

为企业经营,
做好每一套软件。

软件定制、APP与小程序、企业智能体。
从业务梳理到上线维护,提供完整的研发服务。

-
立足贵阳 · 服务全国探索我们的服务 NAHAICHUAN TECHNOLOGY
-
-
以业务为起点先了解流程,再确定方案
以交付为依据阶段成果确认,过程有据可查
以使用为目标兼顾上线运行与后续维护
-

01 / 专业服务

系统开发与长期维护

从企业日常经营出发,
把实际业务需求转化为可用的软件。

全部服务
01

软件开发

围绕订单、库存、财务与内部协同,开发符合企业实际流程的业务系统。

业务系统定制 · 微服务架构 · 系统集成 · 旧系统改造
了解服务
02

APP与小程序定制

面向客户服务、移动办公与门店经营,连接移动终端与后台业务。

iOS / Android · 微信小程序 · 多端协同
了解服务
03

智能体开发

以企业知识与业务流程为基础,提供知识问答、资料检索和任务辅助。

企业知识库 · 流程配置 · 私有化部署
了解服务
-

02 / 产品中心

标准化业务系统

成熟功能满足共性需求,
按业务需要配置、集成与扩展。

产品详情
-
产品选型

从一笔订单,
到日常经营。

线上销售、门店收款、采购库存,
选择适合当前业务的管理工具。

预约产品演示
川经营管理工作台界面示意

经营概览 业务数据,一处查看

销售管理订单汇总
库存管理出入库记录
会员管理客户档案
销售趋势销售 / 订单
业务记录经营统计趋势分析
-
线上交易

商城

商品、订单、会员与营销管理,满足线上销售与日常运营。

查看详情
门店经营

收银

收款、退款、防重复扣款与门店对账,衔接一线操作和总部管理。

申请演示
采购与库存

进销存

关联采购、销售、库存与往来账目,记录每一笔业务流转。

查看详情
订阅使用

SaaS版本

按订阅方式使用业务功能,适合希望简化部署和维护的企业。

咨询开通
-
-

04 / 实施交付

每一步,都有明确的交付

项目推进流程
范围、进度与成果,按阶段沟通确认。

    -
  1. 01

    需求与方案

    了解业务流程、使用对象和现有系统,确认功能范围、预算与计划。

    需求说明 / 实施方案
  2. 02

    设计与开发

    确认交互原型和技术方案,分阶段开发,并及时沟通调整事项。

    交互原型 / 阶段版本
  3. 03

    测试与验收

    按约定业务场景开展测试,核对功能、数据和问题处理结果。

    测试记录 / 验收清单
  4. 04

    上线与维护

    完成部署、操作培训与资料移交,按约定提供后续维护。

    部署文档 / 使用培训
交付清楚,后续有据。

源码交付、接口文档、代码审查记录、部署资料及维护安排,在项目启动前明确,具体以合同约定为准。

咨询交付安排
-
自然光下的现代办公洽谈空间,品牌意境图
品牌意境图

05 / 关于纳海川

认真理解业务,
踏实做好研发。

贵阳纳海川科技有限公司,专注企业软件开发与业务系统建设。我们为企业提供软件定制、移动应用、智能体开发及标准化业务产品。

重视每一次需求确认、每一个阶段成果,也关注系统交付之后的日常使用。

了解我们
纳海川贵阳 · 中国

合作记录

客户反馈

“订货中台重构后,大促当天订单未出现积压,库存与财务账目一致。沟通直接,变更均有记录。”

供应链企业 · 技术负责人订货中台项目

“收银员半天即可上手。门店断网时仍可正常收银,网络恢复后单据自动补传,月底对账工作量明显减少。”

连锁零售企业 · 运营负责人门店收银项目
-

06 / 研发记录

技术与实践

更多动态
{if !empty($information['data'])}{foreach name="information.data" id="art" key="idx" offset="0" length="3"} - {php}$cover_fallbacks = ['/assets/addons/official/images/articles/article_cache.svg','/assets/addons/official/images/articles/article_mysql_page.svg','/assets/addons/official/images/articles/article_xxl_job.svg']; $img_val = !empty($art['image']) ? $art['image'] : ''; $cover_src = (empty($img_val) || strpos($img_val,'article_microservice.svg') !== false) ? (isset($cover_fallbacks[$idx]) ? $cover_fallbacks[$idx] : '/assets/addons/official/images/articles/article_microservice.svg') : $img_val;{/php} - - {/foreach}{else/}

项目与技术记录持续更新中,您也可以直接与我们讨论具体需求。

{/if}
-

合作问答

开始之前,
您可能关心

只有初步想法,可以先沟通吗?

可以。先说明使用对象、主要业务流程和希望解决的问题,我们一起梳理建设方向;涉及详细调研或原型设计的工作,再根据工作量单独约定。

项目费用和周期如何确定?

根据功能范围、流程复杂度、终端数量和接口条件进行评估,确认阶段计划和费用清单。服务器及第三方服务费用另行说明。

已有系统,可以改造或增加功能吗?

先评估现有源码、接口、数据结构与运行环境,具备条件后确定改造范围;涉及数据迁移与系统切换时,单独安排验证。

-

与纳海川谈谈您的项目

从一次沟通,
开始您的软件项目。

有具体的系统研发或产品选型需求?可以直接沟通

+ 跳至服务内容 +
+ + + + + 蓝色玻璃计算核心连接神经网络球体与数据节点,呈现人工智能与软件技术 + +
+

纳海川科技 / 企业软件服务

+

为企业经营,
做好每一套软件。

+

+ 软件定制、APP与小程序、企业智能体。
从业务梳理到上线维护,提供完整的研发服务。 +

+ +
+
+ 立足贵阳 · 服务全国探索我们的服务 NAHAICHUAN TECHNOLOGY +
+
+
+
+
以业务为起点先了解流程,再确定方案
+
以交付为依据阶段成果确认,过程有据可查
+
以使用为目标兼顾上线运行与后续维护
+
+
+
+
+
+
+

01 / 专业服务

+

系统开发与长期维护

+
+
+

从企业日常经营出发,
把实际业务需求转化为可用的软件。

+ 全部服务 +
+
+
+
+
+ 01 +
+

软件开发

+

围绕订单、库存、财务与内部协同,开发符合企业实际流程的业务系统。

+
+ 业务系统定制 · 微服务架构 · 系统集成 · 旧系统改造 +
+ 了解服务 +
+
+
+ 02 +
+

APP与小程序定制

+

面向客户服务、移动办公与门店经营,连接移动终端与后台业务。

+
iOS / Android · 微信小程序 · 多端协同
+ 了解服务 +
+
+
+ 03 +
+

智能体开发

+

以企业知识与业务流程为基础,提供知识问答、资料检索和任务辅助。

+
企业知识库 · 流程配置 · 私有化部署
+ 了解服务 +
+
+
+
+
+
+
+
+

02 / 产品中心

+

标准化业务系统

+
+
+

成熟功能满足共性需求,
按业务需要配置、集成与扩展。

+ 产品详情 +
+
+
+
+ 产品选型 +

从一笔订单,
到日常经营。

+

线上销售、门店收款、采购库存,
选择适合当前业务的管理工具。

+ 预约产品演示 +
+
+
+
+ 川经营管理工作台界面示意 +
+
+ +
+

经营概览 业务数据,一处查看

+
+
销售管理订单汇总
+
库存管理出入库记录
+
会员管理客户档案
+
+
+
销售趋势销售 / 订单
+ +
+ 业务记录经营统计趋势分析 +
+
+
+
+
+
+
+
+
+ 线上交易 +

商城

+

商品、订单、会员与营销管理,满足线上销售与日常运营。

+ 查看详情 +
+
+ 门店经营 +

收银

+

收款、退款、防重复扣款与门店对账,衔接一线操作和总部管理。

+ 申请演示 +
+
+ 采购与库存 +

进销存

+

关联采购、销售、库存与往来账目,记录每一笔业务流转。

+ 查看详情 +
+
+ 订阅使用 +

SaaS版本

+

按订阅方式使用业务功能,适合希望简化部署和维护的企业。

+ 咨询开通 +
+
+
+
+
+ +
+
+
+
+
+

04 / 实施交付

+

每一步,都有明确的交付

+
+

项目推进流程
范围、进度与成果,按阶段沟通确认。

+
+
    +
  1. + 01 +

    需求与方案

    +

    了解业务流程、使用对象和现有系统,确认功能范围、预算与计划。

    + 需求说明 / 实施方案 +
  2. +
  3. + 02 +

    设计与开发

    +

    确认交互原型和技术方案,分阶段开发,并及时沟通调整事项。

    + 交互原型 / 阶段版本 +
  4. +
  5. + 03 +

    测试与验收

    +

    按约定业务场景开展测试,核对功能、数据和问题处理结果。

    + 测试记录 / 验收清单 +
  6. +
  7. + 04 +

    上线与维护

    +

    完成部署、操作培训与资料移交,按约定提供后续维护。

    + 部署文档 / 使用培训 +
  8. +
+
+ 交付清楚,后续有据。 +

+ 源码交付、接口文档、代码审查记录、部署资料及维护安排,在项目启动前明确,具体以合同约定为准。 +

+ 咨询交付安排 +
+
+
+
+
+
+ + 自然光下的现代办公洽谈空间,品牌意境图 +
品牌意境图
+
+
+

05 / 关于纳海川

+

认真理解业务,
踏实做好研发。

+

+ 贵阳纳海川科技有限公司,专注企业软件开发与业务系统建设。我们为企业提供软件定制、移动应用、智能体开发及标准化业务产品。 +

+

重视每一次需求确认、每一个阶段成果,也关注系统交付之后的日常使用。

+ 了解我们 +
+ 纳海川贵阳 · 中国 +
+
+
+
+
+

合作记录

+

客户反馈

+
+
+
+

+ “订货中台重构后,大促当天订单未出现积压,库存与财务账目一致。沟通直接,变更均有记录。” +

+
供应链企业 · 技术负责人订货中台项目
+
+
+

+ “收银员半天即可上手。门店断网时仍可正常收银,网络恢复后单据自动补传,月底对账工作量明显减少。” +

+
连锁零售企业 · 运营负责人门店收银项目
+
+
+
+
+
+
+
+
+

06 / 研发记录

+

技术与实践

+
+ 更多动态 +
+
+ {if !empty($information['data'])}{foreach name="information.data" id="art" + key="idx" offset="0" length="3"} {php}$cover_fallbacks = + ['/assets/addons/official/images/articles/article_cache.svg','/assets/addons/official/images/articles/article_mysql_page.svg','/assets/addons/official/images/articles/article_xxl_job.svg']; + $img_val = !empty($art['image']) ? $art['image'] : ''; $cover_src = + (empty($img_val) || strpos($img_val,'article_microservice.svg') !== false) ? + (isset($cover_fallbacks[$idx]) ? $cover_fallbacks[$idx] : + '/assets/addons/official/images/articles/article_microservice.svg') : + $img_val;{/php} + + {/foreach}{else/} +

+ 项目与技术记录持续更新中,您也可以直接与我们讨论具体需求。 +

+ {/if} +
+
+
+
+
+
+

合作问答

+

开始之前,
您可能关心

+
+
+
+ + 只有初步想法,可以先沟通吗? + +

+ 可以。先说明使用对象、主要业务流程和希望解决的问题,我们一起梳理建设方向;涉及详细调研或原型设计的工作,再根据工作量单独约定。 +

+
+
+ + 项目费用和周期如何确定? + +

+ 根据功能范围、流程复杂度、终端数量和接口条件进行评估,确认阶段计划和费用清单。服务器及第三方服务费用另行说明。 +

+
+
+ + 已有系统,可以改造或增加功能吗? + +

+ 先评估现有源码、接口、数据结构与运行环境,具备条件后确定改造范围;涉及数据迁移与系统切换时,单独安排验证。 +

+
+
+
+
+
+
+
+

与纳海川谈谈您的项目

+

从一次沟通,
开始您的软件项目。

+

有具体的系统研发或产品选型需求?可以直接沟通

+
+
+ 提交项目需求 电话咨询{:__config('site_mobile','value')} +

业务场景 / 现有系统 / 期望时间

+
+
+
{/block} diff --git a/addons/official/view/web/official_home/index_e.html b/addons/official/view/web/official_home/index_e.html index d925c42..90612fe 100644 --- a/addons/official/view/web/official_home/index_e.html +++ b/addons/official/view/web/official_home/index_e.html @@ -1,32 +1,555 @@ -{extend name="web/official_common/mobile/base" /} -{block name="css"} - - - -{/block} -{block name="content"} +{extend name="web/official_common/mobile/base" /} {block name="css"} + + + +{/block} {block name="content"}
-
纳海川NAHAICHUAN联系咨询
菜单
-跳至服务内容 -
- 远山与庭院之间,蓝色玻璃曲线沿水面延展 -

纳海川科技 / 企业软件服务

为企业经营,
做好每一套软件。

软件定制、APP与小程序、企业智能体。
从业务梳理到上线维护,提供完整的研发服务。

-
立足贵阳 · 服务全国探索我们的服务 NAHAICHUAN TECHNOLOGY
-
-
以业务为起点先了解流程,再确定方案
以交付为依据阶段成果确认,过程有据可查
以使用为目标兼顾上线运行与后续维护
-

01 / 专业服务

系统开发与长期维护

从企业日常经营出发,
把实际业务需求转化为可用的软件。

全部服务
01

软件开发

围绕订单、库存、财务与内部协同,开发符合企业实际流程的业务系统。

业务系统定制 · 微服务架构 · 系统集成 · 旧系统改造
了解服务
02

APP与小程序定制

面向客户服务、移动办公与门店经营,连接移动终端与后台业务。

iOS / Android · 微信小程序 · 多端协同
了解服务
03

智能体开发

以企业知识与业务流程为基础,提供知识问答、资料检索和任务辅助。

企业知识库 · 流程配置 · 私有化部署
了解服务
-

02 / 产品中心

标准化业务系统

成熟功能满足共性需求,
按业务需要配置、集成与扩展。

产品详情
-
产品选型

从一笔订单,
到日常经营。

线上销售、门店收款、采购库存,
选择适合当前业务的管理工具。

预约产品演示
川经营管理工作台界面示意

经营概览 业务数据,一处查看

销售管理订单汇总
库存管理出入库记录
会员管理客户档案
销售趋势销售 / 订单
业务记录经营统计趋势分析
-
线上交易

商城

商品、订单、会员与营销管理,满足线上销售与日常运营。

查看详情
门店经营

收银

收款、退款、防重复扣款与门店对账,衔接一线操作和总部管理。

申请演示
采购与库存

进销存

关联采购、销售、库存与往来账目,记录每一笔业务流转。

查看详情
订阅使用

SaaS版本

按订阅方式使用业务功能,适合希望简化部署和维护的企业。

咨询开通
-
-

04 / 实施交付

每一步,都有明确的交付

项目推进流程
范围、进度与成果,按阶段沟通确认。

    -
  1. 01

    需求与方案

    了解业务流程、使用对象和现有系统,确认功能范围、预算与计划。

    需求说明 / 实施方案
  2. 02

    设计与开发

    确认交互原型和技术方案,分阶段开发,并及时沟通调整事项。

    交互原型 / 阶段版本
  3. 03

    测试与验收

    按约定业务场景开展测试,核对功能、数据和问题处理结果。

    测试记录 / 验收清单
  4. 04

    上线与维护

    完成部署、操作培训与资料移交,按约定提供后续维护。

    部署文档 / 使用培训
交付清楚,后续有据。

源码交付、接口文档、代码审查记录、部署资料及维护安排,在项目启动前明确,具体以合同约定为准。

咨询交付安排
-
自然光下的现代办公洽谈空间,品牌意境图
品牌意境图

05 / 关于纳海川

认真理解业务,
踏实做好研发。

贵阳纳海川科技有限公司,专注企业软件开发与业务系统建设。我们为企业提供软件定制、移动应用、智能体开发及标准化业务产品。

重视每一次需求确认、每一个阶段成果,也关注系统交付之后的日常使用。

了解我们
纳海川贵阳 · 中国

合作记录

客户反馈

“订货中台重构后,大促当天订单未出现积压,库存与财务账目一致。沟通直接,变更均有记录。”

供应链企业 · 技术负责人订货中台项目

“收银员半天即可上手。门店断网时仍可正常收银,网络恢复后单据自动补传,月底对账工作量明显减少。”

连锁零售企业 · 运营负责人门店收银项目
-

06 / 研发记录

技术与实践

更多动态
{if !empty($information['data'])}{foreach name="information.data" id="art" key="idx" offset="0" length="3"} - {php}$cover_fallbacks = ['/assets/addons/official/images/articles/article_cache.svg','/assets/addons/official/images/articles/article_mysql_page.svg','/assets/addons/official/images/articles/article_xxl_job.svg']; $img_val = !empty($art['image']) ? $art['image'] : ''; $cover_src = (empty($img_val) || strpos($img_val,'article_microservice.svg') !== false) ? (isset($cover_fallbacks[$idx]) ? $cover_fallbacks[$idx] : '/assets/addons/official/images/articles/article_microservice.svg') : $img_val;{/php} - - {/foreach}{else/}

项目与技术记录持续更新中,您也可以直接与我们讨论具体需求。

{/if}
-

合作问答

开始之前,
您可能关心

只有初步想法,可以先沟通吗?

可以。先说明使用对象、主要业务流程和希望解决的问题,我们一起梳理建设方向;涉及详细调研或原型设计的工作,再根据工作量单独约定。

项目费用和周期如何确定?

根据功能范围、流程复杂度、终端数量和接口条件进行评估,确认阶段计划和费用清单。服务器及第三方服务费用另行说明。

已有系统,可以改造或增加功能吗?

先评估现有源码、接口、数据结构与运行环境,具备条件后确定改造范围;涉及数据迁移与系统切换时,单独安排验证。

-

与纳海川谈谈您的项目

从一次沟通,
开始您的软件项目。

有具体的系统研发或产品选型需求?可以直接沟通

+
+ 纳海川NAHAICHUAN联系咨询 +
+ + 菜单 + + + +
+
+ 跳至服务内容 +
+ + + + + 蓝色玻璃计算核心连接神经网络球体与数据节点,呈现人工智能与软件技术 + +
+

纳海川科技 / 企业软件服务

+

为企业经营,
做好每一套软件。

+

+ 软件定制、APP与小程序、企业智能体。
从业务梳理到上线维护,提供完整的研发服务。 +

+ +
+
+ 立足贵阳 · 服务全国探索我们的服务 NAHAICHUAN TECHNOLOGY +
+
+
+
+
以业务为起点先了解流程,再确定方案
+
以交付为依据阶段成果确认,过程有据可查
+
以使用为目标兼顾上线运行与后续维护
+
+
+
+
+
+
+

01 / 专业服务

+

系统开发与长期维护

+
+
+

从企业日常经营出发,
把实际业务需求转化为可用的软件。

+ 全部服务 +
+
+
+
+
+ 01 +
+

软件开发

+

围绕订单、库存、财务与内部协同,开发符合企业实际流程的业务系统。

+
+ 业务系统定制 · 微服务架构 · 系统集成 · 旧系统改造 +
+ 了解服务 +
+
+
+ 02 +
+

APP与小程序定制

+

面向客户服务、移动办公与门店经营,连接移动终端与后台业务。

+
iOS / Android · 微信小程序 · 多端协同
+ 了解服务 +
+
+
+ 03 +
+

智能体开发

+

以企业知识与业务流程为基础,提供知识问答、资料检索和任务辅助。

+
企业知识库 · 流程配置 · 私有化部署
+ 了解服务 +
+
+
+
+
+
+
+
+

02 / 产品中心

+

标准化业务系统

+
+
+

成熟功能满足共性需求,
按业务需要配置、集成与扩展。

+ 产品详情 +
+
+
+
+ 产品选型 +

从一笔订单,
到日常经营。

+

线上销售、门店收款、采购库存,
选择适合当前业务的管理工具。

+ 预约产品演示 +
+
+
+
+ 川经营管理工作台界面示意 +
+
+ +
+

经营概览 业务数据,一处查看

+
+
销售管理订单汇总
+
库存管理出入库记录
+
会员管理客户档案
+
+
+
销售趋势销售 / 订单
+ +
+ 业务记录经营统计趋势分析 +
+
+
+
+
+
+
+
+
+ 线上交易 +

商城

+

商品、订单、会员与营销管理,满足线上销售与日常运营。

+ 查看详情 +
+
+ 门店经营 +

收银

+

收款、退款、防重复扣款与门店对账,衔接一线操作和总部管理。

+ 申请演示 +
+
+ 采购与库存 +

进销存

+

关联采购、销售、库存与往来账目,记录每一笔业务流转。

+ 查看详情 +
+
+ 订阅使用 +

SaaS版本

+

按订阅方式使用业务功能,适合希望简化部署和维护的企业。

+ 咨询开通 +
+
+
+
+
+ +
+
+
+
+
+

04 / 实施交付

+

每一步,都有明确的交付

+
+

项目推进流程
范围、进度与成果,按阶段沟通确认。

+
+
    +
  1. + 01 +

    需求与方案

    +

    了解业务流程、使用对象和现有系统,确认功能范围、预算与计划。

    + 需求说明 / 实施方案 +
  2. +
  3. + 02 +

    设计与开发

    +

    确认交互原型和技术方案,分阶段开发,并及时沟通调整事项。

    + 交互原型 / 阶段版本 +
  4. +
  5. + 03 +

    测试与验收

    +

    按约定业务场景开展测试,核对功能、数据和问题处理结果。

    + 测试记录 / 验收清单 +
  6. +
  7. + 04 +

    上线与维护

    +

    完成部署、操作培训与资料移交,按约定提供后续维护。

    + 部署文档 / 使用培训 +
  8. +
+
+ 交付清楚,后续有据。 +

+ 源码交付、接口文档、代码审查记录、部署资料及维护安排,在项目启动前明确,具体以合同约定为准。 +

+ 咨询交付安排 +
+
+
+
+
+
+ + 自然光下的现代办公洽谈空间,品牌意境图 +
品牌意境图
+
+
+

05 / 关于纳海川

+

认真理解业务,
踏实做好研发。

+

+ 贵阳纳海川科技有限公司,专注企业软件开发与业务系统建设。我们为企业提供软件定制、移动应用、智能体开发及标准化业务产品。 +

+

重视每一次需求确认、每一个阶段成果,也关注系统交付之后的日常使用。

+ 了解我们 +
+ 纳海川贵阳 · 中国 +
+
+
+
+
+

合作记录

+

客户反馈

+
+
+
+

+ “订货中台重构后,大促当天订单未出现积压,库存与财务账目一致。沟通直接,变更均有记录。” +

+
供应链企业 · 技术负责人订货中台项目
+
+
+

+ “收银员半天即可上手。门店断网时仍可正常收银,网络恢复后单据自动补传,月底对账工作量明显减少。” +

+
连锁零售企业 · 运营负责人门店收银项目
+
+
+
+
+
+
+
+
+

06 / 研发记录

+

技术与实践

+
+ 更多动态 +
+
+ {if !empty($information['data'])}{foreach name="information.data" id="art" + key="idx" offset="0" length="3"} {php}$cover_fallbacks = + ['/assets/addons/official/images/articles/article_cache.svg','/assets/addons/official/images/articles/article_mysql_page.svg','/assets/addons/official/images/articles/article_xxl_job.svg']; + $img_val = !empty($art['image']) ? $art['image'] : ''; $cover_src = + (empty($img_val) || strpos($img_val,'article_microservice.svg') !== false) ? + (isset($cover_fallbacks[$idx]) ? $cover_fallbacks[$idx] : + '/assets/addons/official/images/articles/article_microservice.svg') : + $img_val;{/php} + + {/foreach}{else/} +

+ 项目与技术记录持续更新中,您也可以直接与我们讨论具体需求。 +

+ {/if} +
+
+
+
+
+
+

合作问答

+

开始之前,
您可能关心

+
+
+
+ + 只有初步想法,可以先沟通吗? + +

+ 可以。先说明使用对象、主要业务流程和希望解决的问题,我们一起梳理建设方向;涉及详细调研或原型设计的工作,再根据工作量单独约定。 +

+
+
+ + 项目费用和周期如何确定? + +

+ 根据功能范围、流程复杂度、终端数量和接口条件进行评估,确认阶段计划和费用清单。服务器及第三方服务费用另行说明。 +

+
+
+ + 已有系统,可以改造或增加功能吗? + +

+ 先评估现有源码、接口、数据结构与运行环境,具备条件后确定改造范围;涉及数据迁移与系统切换时,单独安排验证。 +

+
+
+
+
+
+
+
+

与纳海川谈谈您的项目

+

从一次沟通,
开始您的软件项目。

+

有具体的系统研发或产品选型需求?可以直接沟通

+
+
+ 提交项目需求 电话咨询{:__config('site_mobile','value')} +

业务场景 / 现有系统 / 期望时间

+
+
+
{/block} diff --git a/addons/official/view/web/official_home/single.html b/addons/official/view/web/official_home/single.html index e004ef4..275c4ce 100644 --- a/addons/official/view/web/official_home/single.html +++ b/addons/official/view/web/official_home/single.html @@ -1,503 +1,297 @@ -{extend name="web/official_common/pc/base" /} {block name="content"} - - - -
-
-
- 首页 - / - 关于我们 -
-
- 自主可控 · 源码交付 -
-

十年技术积累 · 专注自主可控软件研发

- -

- 贵阳纳海川科技有限公司立足西南、服务全国,专注于企业级软件系统定制、全场景移动应用与小程序定制、私有化 - AI - 智能体应用及成熟商业软件研发。交付完整工程源代码与全套开发文档,实行代码审查与质量测试,为客户交付稳定可靠的软件系统。 -

+{extend name="web/official_common/pc/base" /} {block name="css"} + + +{/block} {block name="content"} +
+ 跳至公司介绍 +
+
+ +
+
+

纳海川科技 / 关于我们

+

专注企业软件研发
与业务系统建设

-
- - -
-
-
- -

- 坚持扎实工程实践 · 交付自主可控的软件资产 -

-

- 纳海川以自主可控的技术体系、统一的质量标准与行业积累,为客户交付数字化系统。 -

-
-
- - -
-
-
- - - -
-

- 自主可控研发 · 拒绝低质套壳代码 -

-

- 核心业务逻辑遵循规范自主编写,交付完整工程源代码与开发文档,支持客户自主维护与代码安全审计。 -

-
-
-
- - - -
-

- 标准化开放架构 · 对接企业现有系统 -

-

- 系统采用模块化与微服务设计,具备标准的 RESTful 与 RPC - 接口规范。可与企业既有的金蝶、用友、各类 WMS - 仓储及第三方物流、支付系统互通,保护企业既有 IT 投资。 -

-
-
-
- - - - -
-

- 严谨工程质量管理 · 支撑系统稳定运行 -

-

- 全流程实行规范化代码审查与多层级自动化测试,把控功能质量、并发性能与数据安全,推动系统在生产环境中稳定运行。 -

-
-
- - -
-
- 演进轨迹 -

- 纳海川十年技术积累与发展历程 -

-
-
-
-
2016
-
-

初创起步 · 专注基础软件

-

- 立足贵阳本地,专注于企业软件与数字化系统定制,确立自主可控的技术研发底座。 -

-
-
-
2019
-
-

- 产品成型 · 商业系统标准化 -

-

- 相继发布商业商城系统、智能收银与进销存管理系统,持续服务实体商户与供应链伙伴。 -

-
-
-
2022
-
-

- 架构升级 · 建立企业级技术底座 -

-

- 构建纳海川架构底层与业务组件库,推行规范化研发体系与质量流程。 -

-
-
-
2024~2026
-
-

- AI 应用 · 垂直私域智能体研发 -

-

- 发布支持内网私有部署的垂直领域 RAG - 智能体与私有知识库系统,帮助政企客户改善内部文档检索慢、人工初审标准不统一的问题。 -

-
-
-
+
+

贵阳纳海川科技有限公司

+

+ 立足贵阳,面向企业经营与管理需求,提供软件开发、APP + 与小程序定制、企业智能体及商业软件服务。 +

+ 了解纳海川
-
+
+
+ + 白色石材层叠成山形,蓝色玻璃水道穿行其间,表达业务与技术的连接 +
+ 业务与技术,在此相接。纳海川 / 抽象建筑示意 +
+
+ +
+
+ +
- -
-
-
- -

纳海川核心技术团队

-

- 核心架构团队具备大型系统研发与高并发调优经验,严守代码质量底线,支撑系统长期稳定运行。 -

-
-
+
+
+
+

01 / 公司介绍

+

从业务出发,
把系统建设做具体

+

贵州 · 贵阳NAHAICHUAN

+
+
+

+ 贵阳纳海川科技有限公司成立于 2016 + 年,围绕企业软件研发与业务系统建设开展服务,涵盖定制开发、现有系统改造、业务接口集成及商业软件应用。 +

+

+ 我们关注系统在实际工作中的使用方式:由谁操作、业务如何流转、数据怎样衔接,以及后续如何维护。项目从需求梳理开始,逐步确认设计、开发、测试与交付安排。 +

+
+
+
服务对象
+
有软件建设与业务管理需求的企业及机构
+
+
+
工作内容
+
需求梳理、设计研发、系统集成、部署交付
+
+
+
合作方式
+
按项目范围,确认阶段计划与验收依据
+
+
+
+
+
-
- -
-
技术总监
-
- 首席系统架构师徽章 -
-

首席系统架构师

-
- 多年大型系统架构经验 · 系统架构专家 -
-

- 曾主持分布式微服务架构设计与多活容灾改造,主导纳海川底层核心交易引擎与分库分表设计。 -

-
- 分布式架构 - 微服务治理 - 容灾多活 -
-
- - -
-
工程交付主管
-
- 全栈研发总监徽章 -
-

全栈研发总监

-
- 企业软件工程经验 · 供应链中台系统负责人 -
-

- 主导商业进销存、智能收银与私有化商城系统研发,熟悉软硬件协议对接、离线脱机记账与业务状态机。 -

-
- 业务中台 - 状态机编排 - 软硬件互联 -
-
- - -
-
前沿技术带头人
-
- AI智能体算法主管徽章 -
-

AI 智能体算法主管

-
- 计算机应用技术硕士 · 专注于企业私有 RAG 与 Agent 工作流 -
-

- 专注于开源大语言模型在政企内网环境的量化微调、向量数据库检索及多智能体协作工作流构建,支撑垂直领域业务核查与合规问答。 -

-
- 私有 RAG - LLM 微调 - Agent 协同 -
-
- - -
-
质保与合规专家
-
- 软件质量与安全合规专家徽章 -
-

软件质量与安全合规专家

-
- CISSP 认证安全专家 · ISO 9001/27001 全流程审计师 -
-

- 推行规范化代码审查与全流程测试,落实网络安全等保合规规范与数据防篡改加密,推动系统合规交付。 -

-
- 代码审查 - 等保三级 - 安全审计 -
-
-
+
+
+
+
+

02 / 服务方向

+

围绕业务需求,提供适合的建设方案

-
+

+ 根据使用场景、现有系统与部署条件,选择定制开发、产品应用或分阶段改造。 +

+
+
+ 01 +
+

软件定制开发

+

企业业务系统、现有系统改造、接口集成与共用业务模块建设。

+
+ 需求梳理 / 设计研发 / 系统集成
+ 02 +
+

APP 与小程序定制

+

结合移动端使用场景,开展应用研发、后台管理及业务系统对接。

+
+ 移动应用 / 微信生态 / 多端协作
+ 03 +
+

企业智能体开发

+

围绕知识查询、客户服务与业务辅助,建设知识库并衔接现有系统。

+
+ 知识库 / 任务流程 / 人工复核
+ 04 +
+

商业软件与产品服务

+

提供商城、收银、进销存及 SaaS 版本,按业务条件评估功能适配。

+
+ 产品选型 / 功能配置 / 部署应用
+
+ +
- -
-
-
- -

法定资质认证 · 合规资产保障

-

- 纳海川持有软件著作权与安全认证,为客户系统提供知识产权保护、合规审查依据及数据安全防护。 -

-
-
- - -
-
-
- 国家高新技术企业认证 -
-

国家高新技术企业

-

- 遵循国家科技型企业与高新技术标准体系 · - 全国高新技术企业认定管理机构备案认定 -

-
-
-
认证
-

双软企业评估认证

-

- 遵循软件产品评估与软件企业专业规范 · 规范化软件工程管理 -

-
-
-
- ISO9001质量管理体系认证 -
-

ISO9001:2015 质量管理体系认证

-

- 参照 ISO9001 质量管理体系规范 · - 全生命周期敏捷研发与质量验收交付 -

-
-
-
体系
-

ISO27001:2022 信息安全管理体系

-

- 对标 ISO27001 信息安全管理规范 · - 客户数据资产与信息安全防护标准体系 -

-
-
- - -
-
-
自主可控
-
计算机软件著作权登记证书
-
- 核心业务系统拥有自主可控知识产权,软件著作权依法登记保护,源代码自主研发,避免知识产权纠纷。 -
-
-
-
-
全量
-
完整源码交付与私有化部署
-
- 客户专属环境独立部署,提供全套开源编译指令、数据库结构字典与架构拓扑,数据不出客户内网。 -
-
-
-
-
等保合规
-
网络安全等级保护合规设计
-
- 遵循网络安全法规范与等保合规技术要求,支持防篡改、TLS 1.3 - 加密与完整的操作审计日志 -
-
-
+
+
+
+
+

03 / 团队协作

+

团队职责与项目协作

-
+

+ 围绕需求、研发、测试与交付组织协作。具体参与人员与分工,在项目计划中确认。 +

+
+
+
+ + 多组石材墙面围合成开放庭院,蓝色玻璃连接中央空间,表达团队协作 +
分工协作,共同完成项目。抽象建筑示意
+
+
    +
  1. + 01 +
    +

    需求与设计

    +

    梳理业务流程、使用角色与功能优先级,以需求说明和原型核对建设范围。

    +
    +
  2. +
  3. + 02 +
    +

    研发与集成

    +

    完成应用、数据与接口开发,记录技术约定和版本变更,推进系统联调。

    +
    +
  4. +
  5. + 03 +
    +

    测试与交付

    +

    + 依据业务用例验证功能,跟进问题处理,准备验收资料、部署说明与操作培训。 +

    +
    +
  6. +
  7. + 04 +
    +

    运行与维护

    +

    + 按约定安排使用支持、问题排查及版本维护;新增功能另行评估范围与工作量。 +

    +
    +
  8. +
+
+ +
- -
-
-
-
- 诚意合作 -

- 找懂业务、讲规范的研发团队,让软件项目平稳落地 -

-

- 无论是新项目的技术选型,还是已有系统的升级改造,纳海川技术顾问与架构团队可提供专业评估与实施规划。 -

-
- -
+
+
+
+
+

04 / 资质与项目资料

+

资料与权属,逐项核对

-
+

+ 合作所需资料按项目范围沟通,企业主体、授权范围与有效期限以核验资料为准。 +

+
+
+
+ 01 / 企业主体 +

主体信息与合作资料

+

+ 核对签约主体、经营信息及项目所需资料,使合同、实施与交付主体保持一致。 +

+
+
+ 02 / 知识产权 +

软件权属与授权范围

+

+ 定制源码、计算机软件著作权及第三方组件分别说明,使用权属和交付范围以合同与授权资料为准,便于自主可控地维护系统。 +

+
+
+ 03 / 项目要求 +

标准要求与核验依据

+

+ 涉及 ISO9001、ISO27001 + 或等保要求时,按项目要求核对适用范围、有效资料与双方责任。具体认证情况以有效证书为准。 +

+
+
+ +
+ +
+
+
+
+

合作方式

+

明确范围,按约定交付

+
+ 了解项目案例 +
+
    +
  1. + 01 +

    先了解问题

    +

    说明当前业务、现有系统和主要问题,确认调研与资料准备事项。

    +
  2. +
  3. + 02 +

    再确认安排

    +

    明确功能范围、阶段计划、费用和配合条件,发生变更时同步核对影响。

    +
  4. +
  5. + 03 +

    按清单交付

    +

    以业务用例和验收清单核对成果,移交约定的源码、文档与使用资料。

    +
  6. +
+
+
+ +
+
+
+

与纳海川建立联系

+

沟通您的软件建设需求

+

从当前的问题开始,一起确认适合的实施范围。

+
+
+ 沟通项目需求 电话咨询 {:__config('site_mobile','value')} +
+
+
+ - {/block} diff --git a/addons/official/view/web/official_home/single_e.html b/addons/official/view/web/official_home/single_e.html index 14c97d3..1864247 100644 --- a/addons/official/view/web/official_home/single_e.html +++ b/addons/official/view/web/official_home/single_e.html @@ -1,733 +1,340 @@ -{extend name="web/official_common/mobile/base" /} {block name="content"} - -
- -
+ body > .slide, + body > .navbar, + body > .sidebar-panel { + display: none; + } + + +{/block} {block name="content"} +
+
+ 纳海川NAHAICHUAN联系咨询 +
+ + 菜单 + + + +
+
+ 跳至公司介绍 +
+
+ +
+
+

纳海川科技 / 关于我们

+

专注企业软件研发
与业务系统建设

- - -
-
- 研发准则 -

- 扎实工程实践 · 交付自主可控软件 -

-
- -
-
-

- 自主可控研发 · 拒绝低质套壳代码 -

-

- 核心业务逻辑遵循规范自主编写,交付完整工程源码,支持客户自主维护与代码审计。 -

-
-
-

- 标准化开放架构 · 对接企业系统 -

-

- 具备标准 API 接口规范,对接企业既有 ERP、WMS - 仓储及第三方平台。 -

-
-
-

- 严谨工程质量管理 · 支撑系统稳定运行 -

-

- 全流程实行规范化代码审查与自动化测试,把控质量与性能,推动系统平稳上线。 -

-
-
+
+

贵阳纳海川科技有限公司

+

+ 立足贵阳,面向企业经营与管理需求,提供软件开发、APP + 与小程序定制、企业智能体及商业软件服务。 +

+ 了解纳海川
+
+
+ + 白色石材层叠成山形,蓝色玻璃水道穿行其间,表达业务与技术的连接 +
+ 业务与技术,在此相接。纳海川 / 抽象建筑示意 +
+
+
+
+ - -
+
+
+

01 / 公司介绍

+

从业务出发,
把系统建设做具体

+

贵州 · 贵阳NAHAICHUAN

+
+
+

+ 贵阳纳海川科技有限公司成立于 2016 + 年,围绕企业软件研发与业务系统建设开展服务,涵盖定制开发、现有系统改造、业务接口集成及商业软件应用。 +

+

+ 我们关注系统在实际工作中的使用方式:由谁操作、业务如何流转、数据怎样衔接,以及后续如何维护。项目从需求梳理开始,逐步确认设计、开发、测试与交付安排。 +

+
+
+
服务对象
+
有软件建设与业务管理需求的企业及机构
+
+
+
工作内容
+
需求梳理、设计研发、系统集成、部署交付
+
+
+
合作方式
+
按项目范围,确认阶段计划与验收依据
+
+
+
+
+ + +
+
+
+
+

02 / 服务方向

+

围绕业务需求,提供适合的建设方案

+
+

+ 根据使用场景、现有系统与部署条件,选择定制开发、产品应用或分阶段改造。 +

+
+
+ 01 +
+

软件定制开发

+

企业业务系统、现有系统改造、接口集成与共用业务模块建设。

+
+ 需求梳理 / 设计研发 / 系统集成
-
- 演进轨迹 -

- 十年技术积累与发展历程 -

-
-
-
-
-
- 2016 初创起步 -
-
- 专注政企与商业软件定制,确立自主可控的微服务技术体系 -
-
-
-
-
- 2019 商业系统成型 -
-
- 发布商城、智能收银与进销存管理系统,服务实体商户 -
-
-
-
-
- 2022 工程体系升级 -
-
- 推行规范化代码审查与全流程测试,建立业务中台底座 -
-
- -
-
-
- 2024~2026 AI 智能体跨越 -
-
- 推出私有化垂直大模型与 RAG 智能体平台 -
-
-
-
- - -
-
- 核心团队 -

- 纳海川核心技术团队 -

-
- -
-
-
- 首席系统架构师徽章 -
-

- 首席系统架构师 -

- 技术总监 -
-
-
- 多年大型系统架构经验 · 系统架构专家 -
-

- 主导业务中台与纳海川底层交易引擎。 -

-
- -
-
- 全栈研发总监徽章 -
-

- 全栈研发总监 -

- 工程交付主管 -
-
-
- 企业软件工程经验 · 供应链系统负责人 -
-

- 主导商业进销存、收银及供应链系统研发。 -

-
- -
-
- AI智能体算法主管徽章 -
-

- AI 智能体算法主管 -

- 前沿技术带头人 -
-
-
- 计算机硕士 · 私有 RAG 与 Agent 工作流 -
-

- 专注于政企内网环境大模型微调与多智能体工作流协同。 -

-
- -
-
- 质量与安全合规专家徽章 -
-

- 质量与安全合规专家 -

- CISSP 专家 -
-
-
- CISSP / ISO 9001/27001 审计师 -
-

- 推行规范化代码审查与全流程测试,落实等保合规要求。 -

-
-
-
- - -
02 +
+

APP 与小程序定制

+

结合移动端使用场景,开展应用研发、后台管理及业务系统对接。

+
+ 移动应用 / 微信生态 / 多端协作 -
- 资质背书 -

- 法定资质与合规资产 -

-
-
-
- 国家高新技术企业 -
- 国家高新技术企业 -
-
- 官方机构备案认定 -
-
-
-
- 专业认证 -
-
- 双软企业评估认证 -
-
- 软件专业技术评估 -
-
-
- ISO9001质量认证 -
- ISO 9001 质量认证 -
-
- 标准化交付体系 -
-
-
-
- 安全体系 -
-
- ISO 27001 安全认证 -
-
- 信息安全合规标准 -
-
-
-
- 已登记 - 国家计算机软件著作权 -
- 等保合规适配 · 完整源码交付与私有化部署 -
-
-
+ 03 +
+

企业智能体开发

+

围绕知识查询、客户服务与业务辅助,建设知识库并衔接现有系统。

+
+ 知识库 / 任务流程 / 人工复核
+ 04 +
+

商业软件与产品服务

+

提供商城、收银、进销存及 SaaS 版本,按业务条件评估功能适配。

+
+ 产品选型 / 功能配置 / 部署应用
+
+
+ - -
-

- 预约纳海川架构师方案研讨 -

-

- 24 小时内快速响应对接,量身输出数字化实施方案 -

- - 预约咨询 - +
+
+
+
+

03 / 团队协作

+

团队职责与项目协作

-
- +

+ 围绕需求、研发、测试与交付组织协作。具体参与人员与分工,在项目计划中确认。 +

+
+
+
+ + 多组石材墙面围合成开放庭院,蓝色玻璃连接中央空间,表达团队协作 +
分工协作,共同完成项目。抽象建筑示意
+
+
    +
  1. + 01 +
    +

    需求与设计

    +

    梳理业务流程、使用角色与功能优先级,以需求说明和原型核对建设范围。

    +
    +
  2. +
  3. + 02 +
    +

    研发与集成

    +

    完成应用、数据与接口开发,记录技术约定和版本变更,推进系统联调。

    +
    +
  4. +
  5. + 03 +
    +

    测试与交付

    +

    + 依据业务用例验证功能,跟进问题处理,准备验收资料、部署说明与操作培训。 +

    +
    +
  6. +
  7. + 04 +
    +

    运行与维护

    +

    + 按约定安排使用支持、问题排查及版本维护;新增功能另行评估范围与工作量。 +

    +
    +
  8. +
+
+
+ + +
+
+
+
+

04 / 资质与项目资料

+

资料与权属,逐项核对

+
+

+ 合作所需资料按项目范围沟通,企业主体、授权范围与有效期限以核验资料为准。 +

+
+
+
+ 01 / 企业主体 +

主体信息与合作资料

+

+ 核对签约主体、经营信息及项目所需资料,使合同、实施与交付主体保持一致。 +

+
+
+ 02 / 知识产权 +

软件权属与授权范围

+

+ 定制源码、计算机软件著作权及第三方组件分别说明,使用权属和交付范围以合同与授权资料为准,便于自主可控地维护系统。 +

+
+
+ 03 / 项目要求 +

标准要求与核验依据

+

+ 涉及 ISO9001、ISO27001 + 或等保要求时,按项目要求核对适用范围、有效资料与双方责任。具体认证情况以有效证书为准。 +

+
+
+
+
+ +
+
+
+
+

合作方式

+

明确范围,按约定交付

+
+ 了解项目案例 +
+
    +
  1. + 01 +

    先了解问题

    +

    说明当前业务、现有系统和主要问题,确认调研与资料准备事项。

    +
  2. +
  3. + 02 +

    再确认安排

    +

    明确功能范围、阶段计划、费用和配合条件,发生变更时同步核对影响。

    +
  4. +
  5. + 03 +

    按清单交付

    +

    以业务用例和验收清单核对成果,移交约定的源码、文档与使用资料。

    +
  6. +
+
+
+ +
+
+
+

与纳海川建立联系

+

沟通您的软件建设需求

+

从当前的问题开始,一起确认适合的实施范围。

+
+ +
+
+
+ {/block} diff --git a/addons/official/view/web/official_online_message/list.html b/addons/official/view/web/official_online_message/list.html index 58762e5..12bec04 100644 --- a/addons/official/view/web/official_online_message/list.html +++ b/addons/official/view/web/official_online_message/list.html @@ -1,508 +1,38 @@ -{extend name="web/official_common/pc/base" /} {block name="css"} - -{/block} {block name="content"} - - - -
-
-
- 首页 - / - 联系我们 -
-
- 务实沟通 · 敏捷响应 -
-

业务咨询与技术评估

-

- 告知您的业务需求或系统现状,纳海川技术与架构团队将在 2 - 小时内安排专属架构师与您沟通并输出初步评估。 -

-
-
- - -
-
-
- -
-
- 需求评估 -

预约架构师 1 对 1 方案研讨

-

- 请详细填写您的业务需求与期望指标,我们将在 2 - 小时内安排专属架构师与您对接。 -

-
- -
- {:token()} - - -
- -
- 企业级中台定制 - APP/小程序定制 - 私有 AI 智能体 - 商业产品选型 -
- -
- -
- -
- - -
- -
- - -
-
- - -
- - -
- - {if $captchaType == 'text'} -
- -
- {include file="web/official_common/pc/captcha" - event="register" type="$captchaType" /} -
-
- {/if} - -
- -
-
- 纳海川执行 ISO 27001 - 信息安全规范,对您的商业需求与业务数据长期保密。 -
-
-
- - -
- -
- 纳海川贵阳双基地拓扑与快速建联视窗 -
- - -
-
快速直联
-

业务咨询与技术支持

- -
-
- - - -
-
-
业务咨询专线
- 13984036826 -
- 工作日 09:00 - 18:00(架构师直连) -
-
-
- -
-
- - - - -
-
-
技术支持公用邮箱
-
server@gynhc.com
-
- 商务合作、技术方案咨询接收入口 -
-
-
- -
-
SLA 响应承诺
-
- 工作日 2 小时内快速响应 · 24 小时内出具方案大纲 -
-
-
- - -
-

实体办公基地

- - -
-
- 营销中心 - 花果园中环广场商务基地 -
-

- 贵州省贵阳市南明区花果园遵义中路中环广场2号楼26楼20-21号 -

-
- - -
-
- 技术中心 - 经开区大数据安全产业基地 -
-

- 贵州省贵阳市经开区数字经济产业园大数据安全产业园数楼4楼02-03号 -

-
- - -
-
-
- - 南明营销中心 -
-
- - 经开技术中心 -
-
-
- -
-
-
-
-
-
- - -
-
-
- -

初次对接常见问题

-

- 我们以务实坦诚的态度,提前解答您在商务与技术合作中重点关注的核心疑问。 -

-
-
- -
-
-

提交需求后多久能收到初步方案?

-

- 我们在收到需求后 2 小时内安排解决方案架构师电话回访,并在 24 - 小时内出具针对实际业务需求的初步技术方案与评估大纲。 -

-
-
-

- 是否支持前期签署保密协议(NDA)? -

-

- 支持。对于涉及敏感商业逻辑、政企业务规范或专属数据的项目,纳海川在深度技术交流前可先行签署具备法律效力的保密协议。 -

-
-
-

- 是否支持技术架构师现场当面交流? -

-

- 西南地区(贵阳及周边城市)可安排架构师上门沟通或邀请莅临纳海川基地;全国其他省市可安排腾讯会议/飞书视频技术研讨。 -

-
-
-

- 定制开发的项目如何保障代码归属与二次开发? -

-

- 纳海川提供完整工程源码交付协议,不设硬件锁、加密狗或暗门,交付全套源码、数据库设计字典及本地化持续集成编译指南。 -

-
-
-
-
- - -{/block} {block name="js"} - - - +{extend name="web/official_common/pc/base" /} +{block name="css"} + + +{/block} +{block name="content"} +
+ +跳至项目咨询表单 +

纳海川科技 / 联系我们

业务咨询与技术评估

说明您的业务需求、现有系统与主要问题。我们据此了解项目情况,沟通建设范围与实施条件。

两组白色石材门框由蓝色玻璃桥连接,表达交流与合作
从沟通开始,确认项目方向。抽象建筑示意
+ +

项目咨询

告诉我们您的需求

填写称呼、联系电话、需求主题和简要说明,便于后续联系。标注 * 的项目为必填。

+
+ {:token()} +
咨询方向 可选
+
+

固定电话请包含区号。

+

初次沟通无需提交账号、密码或未脱敏的业务数据。

+ {if $captchaType == 'text'} +

看不清时,可点击图片更换。

+ {/if} + +

提交后,请保持联系电话畅通。

+

您提交的信息将用于本次项目咨询与联系。涉及保密资料时,可先沟通保密安排,再提供相关材料。

+ +
+ +
+ +

到访信息

来访前,请先联系确认

请先确认接待地点、时间与交流内容。以下提供地址及地图查询入口,具体路线请以地图查询结果为准。

+ +

沟通须知

初次咨询,
您可能关心这些

只有初步想法,可以先沟通吗?

可以。先说明使用对象、当前的操作方式和主要问题,再逐步梳理功能范围与优先级。涉及详细调研、原型或专项验证时,另行确认工作内容。

何时可以确定方案、周期与费用?

需要先了解业务流程、功能范围、接口与资料条件。评估后再确认实施计划与费用清单;初次留言不等同于已完成方案评估。

涉及商业资料,如何安排沟通?

可先用脱敏资料说明业务,必要时在进一步交流前沟通保密协议、资料范围与使用方式。请勿通过留言提交账号密码或完整的敏感业务数据。

能否线上交流或当面讨论?

可先通过电话或线上会议确认需求。需要到访或现场调研时,提前沟通地点、人员、内容及相关安排。

+
+ +{/block} +{block name="js"} + {/block} diff --git a/addons/official/view/web/official_online_message/list_e.html b/addons/official/view/web/official_online_message/list_e.html index e607d9b..6788569 100644 --- a/addons/official/view/web/official_online_message/list_e.html +++ b/addons/official/view/web/official_online_message/list_e.html @@ -1,535 +1,38 @@ -{extend name="web/official_common/mobile/base" /} {block name="content"} - -
- -
-
- 务实沟通 · 敏捷响应 -
-

- 业务咨询与技术评估 -

-

- 贵阳纳海川科技有限公司技术团队立足贵阳、服务全国,提供专业的技术方案评估与 - 24 小时快速响应对接。 -

-
- - -
- -
- 纳海川贵阳双基地拓扑视窗 -
- -
-
- 快速直联通道 -
-
-
-
- 业务咨询与架构专线 -
-
- 13984036826 -
-
- - 立即拨打 - -
-
- 技术邮箱: server@gynhc.com - 响应承诺: 2小时直连 -
-
- - -
-
- 需求评估 -

- 预约架构师 1 对 1 方案研讨 -

-

- 提交您的业务需求,架构师将在 2 小时内回访 -

-
- -
- {:token()} - - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - {if $captchaType == 'text'} -
- -
- - -
-
- {/if} - - -
- 执行 ISO 27001 体系规范 · 客户商业信息与数据长期保密 -
-
-
- - -
-
- 实体办公基地 -
- -
-
- 营销中心 - 花果园中环广场商务基地 -
-
- 贵州省贵阳市南明区花果园遵义中路中环广场2号楼26楼20-21号 -
-
- -
-
- 技术中心 - 经开区大数据安全产业基地 -
-
- 贵州省贵阳市经开区数字经济产业园大数据安全产业园数楼4楼02-03号 -
-
-
-
-
- -{/block} {block name="js"} - - +{extend name="web/official_common/mobile/base" /} +{block name="css"} + + +{/block} +{block name="content"} +
+
纳海川NAHAICHUAN电话咨询
菜单
+跳至项目咨询表单 +

纳海川科技 / 联系我们

业务咨询与技术评估

说明您的业务需求、现有系统与主要问题。我们据此了解项目情况,沟通建设范围与实施条件。

两组白色石材门框由蓝色玻璃桥连接,表达交流与合作
从沟通开始,确认项目方向。抽象建筑示意
+ +

项目咨询

告诉我们您的需求

填写称呼、联系电话、需求主题和简要说明,便于后续联系。标注 * 的项目为必填。

+
+ {:token()} +
咨询方向 可选
+
+

固定电话请包含区号。

+

初次沟通无需提交账号、密码或未脱敏的业务数据。

+ {if $captchaType == 'text'} +

看不清时,可点击图片更换。

+ {/if} + +

提交后,请保持联系电话畅通。

+

您提交的信息将用于本次项目咨询与联系。涉及保密资料时,可先沟通保密安排,再提供相关材料。

+ +
+ +
+ +

到访信息

来访前,请先联系确认

请先确认接待地点、时间与交流内容。以下提供地址及地图查询入口,具体路线请以地图查询结果为准。

+ +

沟通须知

初次咨询,
您可能关心这些

只有初步想法,可以先沟通吗?

可以。先说明使用对象、当前的操作方式和主要问题,再逐步梳理功能范围与优先级。涉及详细调研、原型或专项验证时,另行确认工作内容。

何时可以确定方案、周期与费用?

需要先了解业务流程、功能范围、接口与资料条件。评估后再确认实施计划与费用清单;初次留言不等同于已完成方案评估。

涉及商业资料,如何安排沟通?

可先用脱敏资料说明业务,必要时在进一步交流前沟通保密协议、资料范围与使用方式。请勿通过留言提交账号密码或完整的敏感业务数据。

能否线上交流或当面讨论?

可先通过电话或线上会议确认需求。需要到访或现场调研时,提前沟通地点、人员、内容及相关安排。

+
+ +{/block} +{block name="js"} + {/block} diff --git a/docs/about-image-prompts.json b/docs/about-image-prompts.json new file mode 100644 index 0000000..1720bff --- /dev/null +++ b/docs/about-image-prompts.json @@ -0,0 +1,20 @@ +{ + "tool": "built-in image_gen", + "directory": "M:/2026项目/nahaichuan/public/assets/addons/official/images/about", + "images": [ + { + "files": [ + "landscape.webp", + "landscape.jpg" + ], + "prompt": "Ultra-refined abstract landscape sculpture photograph for the About page of a Chinese enterprise software company. Landscape 3:2 image designed to crop into a wide 3:1 panorama. A low continuous installation of precisely layered warm-white limestone terraces, like a restrained abstract mountain landscape, with a single translucent deep cobalt-blue glass water channel weaving smoothly through the central valley and joining two quiet courtyards. Complete low sculpture lies in middle horizontal band with broad empty space above and below; museum architectural model, real tactile stone microtexture, finely crafted edges, no ornamental patterns. Seamless warm pale-white gallery background, natural soft daylight, delicate shadows and subtle blue refraction. Contemporary Chinese spatial sensibility through negative space, clean alignment and landscape rhythm. Luxury architecture monograph editorial photography, physical material realism, calm and professional. No text, no letters, no logos, no screens, no interface, no circuitry, no robots, no spheres, no ribbons, no purple, no neon, no cartoon." + }, + { + "files": [ + "collaboration.webp", + "collaboration.jpg" + ], + "prompt": "Exquisite abstract architectural still-life photography for the About page of a refined Chinese software engineering company. Landscape 3:2. A small complete model of four finely crafted warm-white limestone wall planes meeting around one open rectangular courtyard, connected through narrow elegant doorway gaps, and one clear cobalt-blue glass sheet crossing the shared central space. All walls at different measured heights, quiet collaboration expressed through a coherent built structure, balanced oblique high camera angle, subtle joinery and fine limestone grain. Complete sculpture centered with generous margins on matte warm-white gallery ground. Soft daylight, delicate slate shadows, restrained blue refraction, physical realism, luxury architecture catalogue editorial style. Contemporary Chinese courtyard proportions through geometry and emptiness, no traditional ornament. No people, no fake office, no text, no letters, no logos, no screen, no UI, no circuitry, no neon, no purple, no robots, no spheres, no ribbons, no cartoon." + } + ] +} diff --git a/docs/about-redesign.md b/docs/about-redesign.md new file mode 100644 index 0000000..0f2d64f --- /dev/null +++ b/docs/about-redesign.md @@ -0,0 +1,38 @@ +# 关于我们页面重构 + +页面:https://www.gynhc.com/h/home/single/1/1.html + +## 规划与文案 + +以公司介绍、服务方向、团队协作、资质与资料、合作方式和项目沟通组织内容。保留原站成立于 2016 年、贵阳所在地及现有软件业务信息。服务方向连接软件开发、APP 与小程序、企业智能体和商业产品页面。 + +团队按需求设计、研发集成、测试交付、运行维护说明职责,未沿用缺少佐证的个人履历。资质板块改为企业主体、软件权属与项目标准要求,撤下示意认证徽章;具体认证以有效证书核验,未新增资质、客户、业绩或绝对化承诺。 + +## 设计与资源 + +浅色专业风,蓝色交互、1280px 容器、细线分区与紧凑排版。字体遵循网站当前的全站设置。首屏使用石材山形与蓝色玻璃水道抽象图,团队板块使用开放庭院抽象图,均注明示意性质。 + +页面模板: + +- `addons/official/view/web/official_home/single.html` +- `addons/official/view/web/official_home/single_e.html` + +独立样式:`public/assets/addons/official/css/about-nhc.css`,作用域限定在 `.about-nhc`。 + +内置 image_gen 生成两张配图,最终资产位于 `public/assets/addons/official/images/about/`:`landscape.webp`、`landscape.jpg`、`collaboration.webp`、`collaboration.jpg`,尺寸均为 1440×960。WebP 分别为 52,500 与 83,050 字节,保留 JPEG 回退;首屏优先加载、团队图片延迟加载。首屏根据宽屏与手机布局在 CSS 中调整展示比例。完整提示词见 `about-image-prompts.json`。 + +## 验证 + +文案 5 项、资料规范 3 项、图片 7 项、关于我们结构 13 项检查通过。相关旧断言已从要求示意认证徽章改为核对配图回退及资质核验措辞,保留测试文件中的其他改动。 + +浏览器验证 1440px 桌面、375px 手机、812px 横屏、125% 缩放及减少动态效果。图片加载、页内导航、键盘菜单操作正常,主要触控目标至少 44px,无横向溢出。发布后 iPhone 15 模拟环境 393px 宽度检查通过,手机菜单、咨询链接、配置电话和主视觉正常,无浏览器错误。 + +电脑、手机响应及五个静态资源均为 200,线上资源内容与本地一致。四个服务产品入口、案例入口和咨询入口均返回 200。 + +UI/UX Pro Max 本地搜索脚本为失效路径指针;依据技能正文及站点规范完成设计与可访问性检查,保留现有 ThinkPHP 技术栈。 + +## 发布与回退 + +发布 7 个文件,资产先于模板,逐文件校验 SHA-256,并清理编译模板缓存。发布前保存远端摘要,覆盖前再次核对远端状态。未触发 Git 硬重置,未修改全站样式、公共导航及其他页面。 + +服务器原版备份:`/www/backup/nhc-about-redesign-20261105-152033`。发布清单:`runtime/about-deployment.json`。本地改前模板及远端核对快照保存在 `runtime/about-backup/`。 diff --git a/docs/contact-image-prompt.json b/docs/contact-image-prompt.json new file mode 100644 index 0000000..48470e7 --- /dev/null +++ b/docs/contact-image-prompt.json @@ -0,0 +1,8 @@ +{ + "tool": "built-in image_gen", + "files": [ + "M:/2026项目/nahaichuan/public/assets/addons/official/images/contact/connection.webp", + "M:/2026项目/nahaichuan/public/assets/addons/official/images/contact/connection.jpg" + ], + "prompt": "Exquisite abstract architectural still-life photograph for the contact page of a refined Chinese enterprise software company. Landscape 3:2. Two precisely carved warm-white limestone open portal structures face each other across a narrow gap, joined by a single horizontal clear cobalt-blue glass bridge at mid height. A small quiet shared space beneath the connecting beam. Complete sculpture centered with generous margins, restrained modern Chinese spatial proportions and framed emptiness, realistic stone microtexture, elegant precision joinery. Matte warm-white seamless gallery backdrop, soft natural daylight, delicate slate shadows and subtle blue glass refraction. Museum architecture catalogue editorial photography, beautiful understated business character, physically realistic materials. No text, no letters, no logos, no screens, no interface, no phone icons, no location pins, no circuitry, no neon, no purple, no robot, no sphere, no ribbons, no cartoon." +} diff --git a/docs/contact-redesign.md b/docs/contact-redesign.md new file mode 100644 index 0000000..1c7b775 --- /dev/null +++ b/docs/contact-redesign.md @@ -0,0 +1,45 @@ +# 联系我们页面重构 + +页面:https://www.gynhc.com/official/online_message/list/18/18.html + +## 页面策划与文案 + +以业务咨询为核心,提供电话、邮箱和在线留言三种沟通方式。页面包括首屏介绍、项目需求表单、直接联系、资料准备建议、到访地址和常见问答。沿用现有电话、邮箱、工作时间与办公地址;地图按地点关键词查询,不使用未经核实的坐标或伪地图。 + +撤下两小时回访、24 小时方案等未确认承诺,改为根据需求和工作安排沟通。说明初次咨询的资料范围、脱敏建议及保密安排,不以 ISO 字样作无依据背书。电话与邮箱读取站点配置,点击即可拨号或打开邮件应用。 + +## 设计与资产 + +浅色商务风,1280px 容器、科技蓝、细线及紧凑布局。桌面采用表单与联系方式双列,手机端单列。保留站点当前字体规范。新增石材门框与蓝色玻璃桥抽象主视觉,配图明确标注示意。 + +页面模板:`addons/official/view/web/official_online_message/list.html`、`list_e.html`。 + +独立样式:`public/assets/addons/official/css/contact-nhc.css`;独立脚本:`public/assets/addons/official/js/contact-nhc.js`。未修改后端控制器、模型及全站公共样式。 + +图片使用内置 image_gen 生成,保存于 `public/assets/addons/official/images/contact/connection.webp` 与 `connection.jpg`,1440×960。WebP 66,562 字节,JPEG 151,461 字节,首屏优先加载。提示词见 `contact-image-prompt.json`。 + +## 表单行为 + +- 称呼、联系电话、主题及需求说明必填,标签与输入控件显式关联;错误显示在对应字段并聚焦首项错误。 +- 咨询方向使用按钮,支持键盘及选中状态,可快速填入主题,也可自行编辑。 +- 图片验证码支持键盘更换,继续使用原站验证码和令牌机制。 +- 使用原有 `name`、`phone`、`title`、`content`、`captcha`、`__token__` 字段及原提交接口。每次提交前从现有 `/hhome/get_token.html` 获取新令牌,避免单次令牌失效后无法重试。 +- 提交中禁用按钮,输入设为只读,避免重复提交及输入变化。仅服务端明确成功时清空内容;失败保留正文,校验返回后刷新验证码。 +- 网络异常或超时后不自动重复 POST。若无法确认提交结果,显示电话或邮箱确认提示并保留输入。 +- 移除页面对外部 Axios CDN 及专属弹层脚本的依赖,使用原生 Fetch 与内联状态反馈。公共模板依赖保持不变。 + +## 验证 + +文案 5 项、配图 2 项、联系页结构 12 项检查通过。`tests/contact_form_browser.js` 在本地真实浏览器中执行 13 项模拟检查,覆盖空表单、电话校验、方向选择、重复点击、请求字段与令牌、服务器拒绝、验证码刷新、成功重置、失败重试及网络异常。所有成功路径采用本地模拟响应,未发送真实咨询留言。 + +检查 1440px 桌面、375px 手机、812px 横屏、125% 缩放及减少动态效果,无横向溢出。发现旧移动样式以 `!important` 覆盖输入框,已在页面独立作用域内修复为 16px 字号、48px 高度,文本域至少 125px。标签、主要按钮、验证码按钮与输入控件触控尺寸通过检查,菜单和问答支持键盘操作。 + +发布后桌面和 iPhone 请求为 200,模板、脚本、样式与图片引用正确,四个资源内容与本地一致。iPhone 15 模拟环境 393px 宽度无溢出,主题选择、菜单、问答和主视觉正常,无浏览器错误。验证码接口返回图片,令牌接口返回有效响应;使用空必填字段验证线上接口拒绝缺失令牌及空内容,未创建留言。未向线上写入成功测试记录,成功反馈与重试流程通过模拟验证。 + +UI/UX Pro Max 本地搜索脚本为失效路径指针,依据技能正文完成布局、表单、可访问性与响应式检查,保留现有 ThinkPHP 技术栈。 + +## 发布与回退 + +发布 6 个文件,静态资源先于模板,上传校验 SHA-256,覆盖前检查远端未在核对后变更,清理编译模板缓存。未执行 Git reset 或修改其他业务页面。 + +服务器原版备份:`/www/backup/nhc-contact-redesign-20261105-153734`。清单:`runtime/contact-deployment.json`。本地旧模板与远端快照:`runtime/contact-backup/`。 diff --git a/docs/home-hero-ai-prompts.json b/docs/home-hero-ai-prompts.json new file mode 100644 index 0000000..f5d3e2d --- /dev/null +++ b/docs/home-hero-ai-prompts.json @@ -0,0 +1,7 @@ +{ + "mode": "Built-in ImageGen", + "desktopPrompt": "Use case: stylized-concept. Asset type: panoramic homepage hero artwork for NAHAICHUAN, a professional Chinese enterprise software and AI development company. Create a visually exceptional premium photorealistic CGI technology brand image, extremely wide 2.5:1 landscape, ideally 2400 x 960. Scene is a luminous white and ice-blue seamless environment. The RIGHT 60 percent contains an elegant large translucent sapphire-blue glass AI computing core with precision silver microprocessor layers at its base; hovering just above it is a beautifully structured neural-network sphere made from fine blue connections and tiny glass nodes, visually clear and sophisticated rather than tangled. Several fine cyan-blue data pathways flow smoothly from the core across a pale ceramic surface into a few low, precisely aligned translucent computing modules. Subtle distant layers suggest connected digital infrastructure. Make AI and advanced computing immediately recognizable. Materials are exquisitely detailed optical glass, brushed silver, matte white ceramic; convincing soft shadows and physically based reflections. Bright refined corporate technology atmosphere, blue #2563EB and restrained cyan #06B6D4 highlights, luminous without neon. MAIN SUBJECT CENTER at approximately 72 percent across the image, all important elements in the right half, sphere fully in frame and with breathing room. LEFT 42 percent is nearly empty, very pale white-blue atmospheric negative space with no objects, no prominent lines, no graphics, intended for dark Chinese heading overlay. Keep the foreground lower-left quiet. Strong spatial hierarchy, premium global enterprise technology art direction, highly polished but credible. No text, letters, numbers, watermark, logo, humanoids, robot, human brain, hands, characters, dark background, purple gradients, cyberpunk city, neon, lens flare, mountains, pagoda, courtyard, cartoon, clutter, generic floating cubes. Produce only the clean image asset, no website mockup.", + "mobilePrompt": "Use case: precise-object-edit / layout recomposition. This is the mobile homepage hero variant of the supplied technology brand image. Preserve the exact same premium photorealistic blue glass AI microprocessor, silver ceramic layers, fine neural-network sphere, small connected computing modules and the pale white-blue visual language. Recompose into a PORTRAIT image 1024x1536, 2:3 aspect ratio. The UPPER 52 percent must be almost entirely empty very pale white-blue atmosphere, smooth and quiet, reserved for dark website heading and buttons; no objects or linework in this upper region. Place the COMPLETE neural sphere and its main glass computing core together in the LOWER 48 percent, centered horizontally, with the sphere around 67 percent down and processor around 85 percent down. All of the main sphere and processor should be fully visible, scaled to fit with 10 percent side margins, smaller secondary modules near the lower corners connected by delicate blue data streams. Soft studio daylight, beautiful crisp optical glass detail, highly polished refined corporate AI aesthetic. No text, no letters, no numbers, no watermark, no logo, no humans, no robot, no brain, no neon, no dark background. This must look like the same brand artwork recomposed for mobile, not a different technology subject.", + "desktopAsset": "public/assets/addons/official/images/home/ai-computing-v4.webp", + "mobileAsset": "public/assets/addons/official/images/home/ai-computing-mobile-v4.webp" +} diff --git a/public/assets/addons/official/css/about-nhc.css b/public/assets/addons/official/css/about-nhc.css new file mode 100644 index 0000000..efbd234 --- /dev/null +++ b/public/assets/addons/official/css/about-nhc.css @@ -0,0 +1,11 @@ +.about-nhc{--ab-blue:#2563eb;--ab-ink:#0f172a;--ab-copy:#475569;--ab-muted:#64748b;--ab-line:#dce4ed;--ab-soft:#f8fafc;background:#fff;color:var(--ab-ink);font-family:var(--font-sans,"Microsoft YaHei",sans-serif);font-size:16px;line-height:1.8;overflow-wrap:break-word}.about-nhc *{box-sizing:border-box}.about-nhc :where(h1,h2,h3,p,ul,ol,dl,dd,figure){margin:0}.about-nhc :where(ul,ol){list-style:none;padding:0}.about-nhc :where(h1,h2){font-family:var(--font-serif,"SimSun",serif);font-weight:600;color:var(--ab-ink);line-height:1.5}.about-nhc h3{font-size:20px;line-height:1.5;color:var(--ab-ink);font-weight:600}.about-nhc a{color:inherit;text-decoration:none}.about-nhc a:focus-visible,.about-nhc summary:focus-visible{outline:3px solid var(--ab-blue);outline-offset:4px}.about-nhc nav{height:auto;line-height:inherit;background:transparent;color:inherit;box-shadow:none}.about-nhc [id]{scroll-margin-top:100px}.ab-wrap{max-width:1280px;width:100%;padding:0 32px;margin:auto}.ab-eyebrow{color:var(--ab-blue);font-size:12px;letter-spacing:1px}.ab-skip{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}.ab-skip:focus{position:fixed;top:80px;left:20px;z-index:1100;width:auto;height:auto;clip-path:none;background:#fff;padding:12px 20px}.about-nhc .ab-text-link{display:inline-flex;align-items:center;gap:16px;min-height:44px;color:var(--ab-copy);font-size:13px}.about-nhc .ab-text-link:hover{color:var(--ab-blue)} +.ab-hero{padding:92px 0 0}.ab-crumb{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--ab-copy);margin-bottom:22px}.ab-crumb a{display:inline-flex;align-items:center;min-height:44px}.ab-hero-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:9%;align-items:end;margin-bottom:28px}.about-nhc h1{font-size:43px;letter-spacing:.5px;margin-top:12px}.ab-hero-name{font-size:19px;font-weight:500;color:var(--ab-ink);margin-bottom:9px!important}.ab-lead{font-size:15px;color:var(--ab-copy);line-height:1.95;max-width:460px}.ab-hero-grid .ab-text-link{margin-top:9px}.ab-panorama{position:relative;background:#f1efec;overflow:hidden;border-radius:4px}.ab-panorama picture{display:block}.ab-panorama img{display:block;width:100%;height:auto;aspect-ratio:3/1;object-fit:cover}.ab-panorama figcaption{position:absolute;left:0;bottom:0;width:100%;display:flex;justify-content:space-between;gap:20px;padding:19px 24px;font-size:11px;color:var(--ab-copy);background:linear-gradient(transparent,#f8fafcf2)}.ab-panorama figcaption>span:last-child{font-size:10px}.ab-index{border-bottom:1px solid var(--ab-line);background:#fff}.ab-index nav{display:flex;justify-content:space-between;align-items:center;gap:20px}.ab-index a{display:flex;align-items:center;gap:16px;min-height:62px;font-size:13px}.ab-index a:hover{color:var(--ab-blue)}.ab-index a>span{font-size:11px;color:var(--ab-muted)} +.ab-section{padding:42px 0}.ab-soft{background:var(--ab-soft);border-top:1px solid var(--ab-line);border-bottom:1px solid var(--ab-line)}.about-nhc h2{font-size:30px;letter-spacing:.2px}.ab-heading{display:flex;align-items:end;justify-content:space-between;gap:45px;margin-bottom:26px}.ab-heading h2{margin-top:9px}.ab-heading>p{font-size:14px;line-height:1.9;color:var(--ab-copy);max-width:370px}.ab-company{display:grid;grid-template-columns:1fr 1.65fr;gap:65px}.ab-company h2{margin-top:10px}.ab-location{color:var(--ab-copy);font-size:13px;margin-top:21px!important;display:flex;flex-direction:column;gap:5px}.ab-location>span{font-size:10px;letter-spacing:2px;color:var(--ab-muted)}.ab-company-copy>p{font-size:14px;line-height:1.95;color:var(--ab-copy)}.ab-company-copy>.ab-intro{font-size:17px;color:var(--ab-ink);margin-bottom:15px}.ab-facts{margin-top:22px!important;border-top:1px solid var(--ab-line)}.ab-facts>div{display:grid;grid-template-columns:90px 1fr;gap:23px;padding-top:13px;font-size:13px}.ab-facts dt{color:var(--ab-muted)}.ab-facts dd{color:var(--ab-copy)} +.ab-services{border-top:1px solid var(--ab-line)}.ab-services>a{display:grid;grid-template-columns:35px 1fr 270px 24px;align-items:center;gap:25px;min-height:113px;padding:22px 0;border-bottom:1px solid var(--ab-line);transition:background .2s}.ab-services>a:hover{background:#eef3fa}.ab-number{color:var(--ab-blue);font-size:12px}.ab-services h3{font-size:20px;margin-bottom:7px}.ab-services p{font-size:14px;line-height:1.9;color:var(--ab-copy)}.ab-service-note{font-size:12px;color:var(--ab-muted)}.ab-arrow{font-size:22px;color:var(--ab-blue);justify-self:end}.ab-services>a:hover .ab-arrow{color:#1d4ed8} +.ab-team-grid{display:grid;grid-template-columns:.95fr 1.05fr;gap:50px;align-items:center}.ab-courtyard picture{display:block}.ab-courtyard img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;border-radius:4px}.ab-courtyard figcaption{display:flex;justify-content:space-between;gap:20px;font-size:11px;color:var(--ab-copy);padding-top:13px}.ab-courtyard figcaption>span{font-size:10px;color:var(--ab-muted)}.ab-roles li{display:grid;grid-template-columns:25px 1fr;gap:18px;padding:17px 0;border-top:1px solid var(--ab-line)}.ab-roles li:first-child{border-top:0;padding-top:0}.ab-roles li:last-child{padding-bottom:0}.ab-roles li>span{font-size:12px;color:var(--ab-blue);padding-top:3px}.ab-roles h3{font-size:17px;margin-bottom:7px}.ab-roles p{font-size:14px;line-height:1.9;color:var(--ab-copy)} +.ab-records{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}.ab-records article{border-top:1px solid var(--ab-line);padding-top:19px}.ab-records h3{font-size:18px;margin:12px 0 10px}.ab-records p{font-size:14px;color:var(--ab-copy);line-height:1.95}.ab-working{display:grid;grid-template-columns:repeat(3,1fr);gap:40px}.ab-working li{position:relative;border-top:1px solid var(--ab-line);padding:19px 0 0 36px}.ab-working li>span{position:absolute;left:0;top:20px;color:var(--ab-blue);font-size:12px}.ab-working h3{font-size:18px;margin-bottom:10px}.ab-working p{font-size:14px;color:var(--ab-copy);line-height:1.9}.ab-contact{padding:32px 0;background:var(--ab-soft);border-top:1px solid var(--ab-line)}.ab-contact>.ab-wrap{display:flex;align-items:center;justify-content:space-between;gap:50px}.ab-contact h2{margin:10px 0}.ab-contact p:not(.ab-eyebrow){font-size:14px;color:var(--ab-copy)}.ab-contact>.ab-wrap>div:last-child{display:flex;flex-direction:column;align-items:flex-start;gap:10px;flex-shrink:0}.about-nhc .ab-button{display:inline-flex;align-items:center;justify-content:center;gap:28px;min-height:50px;padding:12px 23px;color:#fff;background:var(--ab-blue);font-size:14px;border-radius:4px;transition:background .2s}.about-nhc .ab-button:hover{background:#1d4ed8}.about-nhc .ab-button:active{background:#1e40af}.ab-button>span{font-size:20px;line-height:1}.ab-contact .ab-text-link{font-size:12px} +.ab-mobile-header{position:fixed;top:0;left:0;width:100%;height:68px;z-index:1000;display:flex;align-items:center;gap:24px;padding:0 22px;background:#fffffff5;border-bottom:1px solid var(--ab-line)}.about-nhc .ab-brand{font-size:23px;line-height:1.2;font-weight:600;letter-spacing:2px;display:flex;flex-direction:column;justify-content:center;min-height:44px;margin-right:auto}.ab-brand>span{font-size:8px;letter-spacing:1.5px;font-weight:500;color:var(--ab-muted);margin-top:5px}.about-nhc .ab-header-contact{min-height:44px;display:flex;align-items:center;color:var(--ab-blue);font-size:12px}.ab-menu summary{display:flex;align-items:center;gap:7px;min-height:44px;list-style:none;cursor:pointer;font-size:12px}.ab-menu summary::-webkit-details-marker{display:none}.ab-menu svg{width:20px;height:20px;stroke:currentColor;stroke-width:1.5;fill:none}.about-nhc .ab-menu nav{position:absolute;top:67px;left:0;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:0 28px;padding:14px 22px 22px;background:#fff;border-bottom:1px solid var(--ab-line);box-shadow:0 18px 30px #0f172a0d}.ab-menu nav a{display:flex;align-items:center;min-height:52px;border-bottom:1px solid var(--ab-line);font-size:15px;color:var(--ab-copy)}.about-nhc .ab-menu nav a[aria-current]{color:var(--ab-blue)} +@media(max-width:1023px){.ab-hero-grid{gap:35px}.about-nhc h1{font-size:35px}.ab-hero-name{font-size:17px}.about-nhc h2{font-size:27px}.ab-heading{gap:30px}.ab-heading>p{max-width:300px}.ab-company{gap:35px;grid-template-columns:1fr 1.5fr}.ab-services>a{grid-template-columns:28px 1fr 24px;gap:20px}.ab-service-note{display:none}.ab-team-grid{gap:30px}.ab-records{gap:25px}.ab-working{gap:27px}.ab-contact>.ab-wrap{gap:30px}} +@media(max-width:767px){.ab-wrap{padding:0 22px}.about-nhc [id]{scroll-margin-top:85px}.ab-hero{padding:84px 0 0}.ab-crumb{margin-bottom:16px}.ab-eyebrow{font-size:11px}.ab-hero-grid{grid-template-columns:1fr;gap:20px;margin-bottom:23px}.about-nhc h1{font-size:32px;margin-top:11px;letter-spacing:0;line-height:1.5}.ab-hero-name{font-size:17px;margin-bottom:9px!important}.ab-lead{font-size:16px;line-height:1.85;max-width:none}.ab-hero-grid .ab-text-link{margin-top:7px}.ab-panorama img{aspect-ratio:1.65;object-fit:cover;object-position:center}.ab-panorama figcaption{padding:13px 16px;font-size:10px}.ab-panorama figcaption>span:last-child{display:none}.ab-index nav{justify-content:flex-start;flex-wrap:wrap;gap:0 22px;padding-top:7px;padding-bottom:7px}.ab-index a{font-size:12px;min-height:44px;gap:8px}.ab-index a>span{font-size:10px}.ab-section{padding:29px 0}.about-nhc h2{font-size:26px}.ab-heading{display:block;margin-bottom:22px}.ab-heading>p{max-width:none;font-size:16px;line-height:1.85;margin-top:13px}.ab-heading>.ab-text-link{margin-top:12px}.ab-company{grid-template-columns:1fr;gap:20px}.ab-company h2 br{display:none}.ab-location{display:none}.ab-company-copy>.ab-intro{font-size:17px;line-height:1.9;margin-bottom:14px}.ab-company-copy>p{font-size:16px;line-height:1.85}.ab-facts{margin-top:20px!important}.ab-facts>div{grid-template-columns:65px 1fr;gap:18px;font-size:14px;padding-top:13px}.ab-services>a{grid-template-columns:22px 1fr 18px;gap:13px;padding:21px 0;min-height:0}.ab-services h3{font-size:19px}.ab-services p{font-size:16px;line-height:1.85}.ab-arrow{font-size:20px}.ab-team-grid{grid-template-columns:1fr;gap:25px}.ab-courtyard figcaption{font-size:11px}.ab-roles li{gap:14px;padding:18px 0}.ab-roles h3{font-size:18px}.ab-roles p{font-size:16px;line-height:1.85}.ab-records{grid-template-columns:1fr;gap:23px}.ab-records article{padding-top:17px}.ab-records h3{font-size:19px;margin:10px 0}.ab-records p{font-size:16px;line-height:1.85}.ab-working{grid-template-columns:1fr;gap:23px}.ab-working h3{font-size:19px}.ab-working p{font-size:16px;line-height:1.85}.ab-contact{padding:28px 0}.ab-contact>.ab-wrap{display:block}.ab-contact h2{font-size:26px}.ab-contact p:not(.ab-eyebrow){font-size:16px;line-height:1.85}.ab-contact>.ab-wrap>div:last-child{margin-top:20px}.ab-contact .ab-text-link{font-size:13px}} +@media(max-width:374px){.ab-wrap{padding:0 18px}.about-nhc h1{font-size:29px}.ab-index nav{gap:0 16px}.ab-mobile-header{gap:20px}} +@media(prefers-reduced-motion:reduce){html:has(.about-nhc){scroll-behavior:auto}.about-nhc *{animation:none!important;transition:none!important;scroll-behavior:auto!important}} diff --git a/public/assets/addons/official/css/contact-nhc.css b/public/assets/addons/official/css/contact-nhc.css new file mode 100644 index 0000000..9dc2d78 --- /dev/null +++ b/public/assets/addons/official/css/contact-nhc.css @@ -0,0 +1,12 @@ +.contact-nhc{--ct-blue:#2563eb;--ct-ink:#0f172a;--ct-copy:#475569;--ct-muted:#64748b;--ct-line:#dce4ed;--ct-soft:#f8fafc;--ct-error:#b91c1c;background:#fff;color:var(--ct-ink);font-size:16px;line-height:1.8;overflow-wrap:break-word}.contact-nhc *{box-sizing:border-box}.contact-nhc :where(h1,h2,h3,p,figure,ol,dl,dd,fieldset){margin:0}.contact-nhc :where(h1,h2){font-family:var(--font-serif,"SimSun",serif);font-weight:600;line-height:1.5;color:var(--ct-ink)}.contact-nhc h3{font-size:18px;line-height:1.5;font-weight:600;color:var(--ct-ink)}.contact-nhc a{color:inherit;text-decoration:none}.contact-nhc :where(a,button,input,textarea,summary):focus-visible{outline:3px solid var(--ct-blue);outline-offset:4px}.contact-nhc nav{height:auto;line-height:inherit;box-shadow:none;background:transparent;color:inherit}.contact-nhc [hidden]{display:none!important}.contact-nhc [id]{scroll-margin-top:100px}.ct-wrap{max-width:1280px;width:100%;margin:auto;padding:0 32px}.ct-eyebrow{font-size:12px;letter-spacing:1px;color:var(--ct-blue)}.ct-skip,.ct-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}.ct-skip:focus{position:fixed;top:80px;left:20px;width:auto;height:auto;clip-path:none;background:#fff;padding:12px 20px;z-index:1100}.contact-nhc .ct-button{display:inline-flex;align-items:center;justify-content:center;gap:25px;min-height:50px;padding:12px 22px;border:1px solid var(--ct-blue);border-radius:4px;background:var(--ct-blue);color:#fff;font-size:14px;line-height:1.7;cursor:pointer;transition:background .2s;box-shadow:none;text-transform:none;letter-spacing:0}.ct-button>span{font-size:20px;line-height:1}.contact-nhc .ct-button:hover{background:#1d4ed8}.contact-nhc .ct-button:disabled{background:#64748b;border-color:#64748b;color:#fff;cursor:wait}.contact-nhc .ct-text-link{display:inline-flex;align-items:center;gap:15px;min-height:44px;color:var(--ct-copy);font-size:13px}.contact-nhc .ct-text-link:hover{color:var(--ct-blue)} +.ct-hero{padding:92px 0 30px}.ct-crumb{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--ct-copy);margin-bottom:20px}.ct-crumb a{display:inline-flex;align-items:center;min-height:44px}.ct-hero-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:70px;align-items:center}.contact-nhc h1{font-size:39px;margin:12px 0 19px;letter-spacing:.3px}.ct-lead{font-size:16px;line-height:1.95;color:var(--ct-copy);max-width:480px}.ct-actions{display:flex;flex-wrap:wrap;align-items:center;gap:15px 25px;margin-top:25px}.ct-art{border:1px solid #e8e6e2;border-radius:4px;overflow:hidden;background:#f2efea}.ct-art picture{display:block}.ct-art img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}.ct-art figcaption{display:flex;justify-content:space-between;gap:20px;font-size:11px;color:var(--ct-copy);padding:11px 16px;background:#fff;border-top:1px solid #e8e6e2}.ct-art figcaption>span:last-child{font-size:10px;color:var(--ct-muted)} +.ct-section{padding:38px 0}.ct-soft{background:var(--ct-soft);border-top:1px solid var(--ct-line);border-bottom:1px solid var(--ct-line)}.ct-main-grid{display:grid;grid-template-columns:1.45fr 1fr;gap:70px}.ct-form-panel{min-width:0}.ct-section-intro h2{font-size:29px;margin:9px 0 11px}.ct-section-intro>p:last-child{font-size:14px;color:var(--ct-copy);line-height:1.9}.ct-form{margin-top:23px}.contact-nhc .ct-direction{border:0;padding:0;margin:0 0 20px;min-width:0}.ct-direction legend{font-size:14px;font-weight:500;color:var(--ct-ink);padding:0;margin-bottom:10px}.ct-direction legend>span{font-size:12px;color:var(--ct-muted);margin-left:9px;font-weight:400}.ct-topics{display:flex;gap:8px;flex-wrap:wrap}.ct-topics button{min-height:44px;border:1px solid var(--ct-line);border-radius:4px;background:#fff;color:var(--ct-copy);padding:8px 13px;font:inherit;font-size:12px;cursor:pointer;transition:background .2s,color .2s,border-color .2s;box-shadow:none;text-transform:none;letter-spacing:0}.ct-topics button:hover{border-color:var(--ct-blue);color:var(--ct-blue)}.ct-topics button[aria-pressed=true]{background:#eff6ff;border-color:var(--ct-blue);color:#1d4ed8}.ct-field{margin-bottom:19px;min-width:0}.ct-field-row{display:grid;grid-template-columns:1fr 1fr;gap:20px}.contact-nhc .ct-field label{display:block;position:static;transform:none;font-size:14px;color:var(--ct-ink);font-weight:500;margin:0 0 8px;line-height:1.6}.ct-field label>span{color:var(--ct-error);margin-left:3px}.contact-nhc .ct-field input,.contact-nhc .ct-field textarea{display:block;width:100%;height:48px;box-sizing:border-box;min-width:0;border:1px solid #cbd5e1;border-radius:4px;background:#fff;color:var(--ct-ink);padding:11px 13px;margin:0;font:inherit;font-size:15px;line-height:1.6;box-shadow:none;transition:border-color .2s}.contact-nhc .ct-field textarea{height:auto;min-height:125px;resize:vertical}.contact-nhc .ct-field input:focus,.contact-nhc .ct-field textarea:focus{border-color:var(--ct-blue);box-shadow:0 0 0 1px var(--ct-blue)}.contact-nhc .ct-field :where(input,textarea)[aria-invalid=true]{border-color:var(--ct-error)}.contact-nhc :where(input,textarea)::placeholder{color:var(--ct-muted);opacity:1}.ct-hint{font-size:12px;color:var(--ct-muted);line-height:1.8;margin-top:7px!important}.ct-field-error{font-size:13px;color:var(--ct-error);line-height:1.8;margin-top:7px!important}.ct-captcha{display:flex;align-items:center;gap:15px}.contact-nhc .ct-captcha input{max-width:210px;flex:1}.ct-captcha-refresh{display:inline-flex;align-items:center;gap:10px;min-height:48px;border:0;padding:0;background:#fff;cursor:pointer;font-size:12px;color:var(--ct-copy);box-shadow:none;text-transform:none;letter-spacing:0}.ct-captcha-refresh img{width:110px;height:44px;object-fit:contain;display:block}.ct-submit-status{font-size:14px;line-height:1.9;padding:12px 15px;border:1px solid var(--ct-line);background:var(--ct-soft);color:var(--ct-copy);border-radius:4px;margin:0 0 17px!important}.ct-submit-status[data-state=error]{color:var(--ct-error);border-color:#fecaca;background:#fff7f7}.ct-submit-status[data-state=success]{color:#166534;border-color:#bbf7d0;background:#f0fdf4}.ct-submit-line{display:flex;align-items:center;gap:20px;flex-wrap:wrap}.ct-submit-line>p{font-size:12px;color:var(--ct-muted)}.ct-form-note,.ct-noscript{font-size:12px;color:var(--ct-copy);line-height:1.9;margin-top:16px!important}.ct-direct{align-self:start;background:var(--ct-soft);border:1px solid var(--ct-line);border-radius:4px;padding:28px}.ct-direct h2{font-size:24px;margin-top:10px}.ct-contact-list{margin-top:19px!important}.ct-contact-list>div{padding:16px 0;border-bottom:1px solid var(--ct-line)}.ct-contact-list dt{font-size:12px;color:var(--ct-muted);margin-bottom:4px}.ct-contact-list dd{font-size:14px;color:var(--ct-copy)}.ct-contact-list a{min-height:44px;display:inline-flex;align-items:center}.ct-contact-list .ct-phone{font-size:27px;letter-spacing:.5px;color:var(--ct-ink)}.ct-contact-list a:hover{color:var(--ct-blue)}.ct-prepare{padding-top:23px}.ct-prepare h3,.ct-next h3{font-size:16px}.ct-prepare ol{padding:0;list-style:none;margin-top:13px}.ct-prepare li{display:flex;gap:15px;font-size:13px;color:var(--ct-copy);margin-top:9px}.ct-prepare li>span{font-size:11px;color:var(--ct-blue);padding-top:2px}.ct-prepare p,.ct-next p{font-size:13px;color:var(--ct-copy);line-height:1.9;margin-top:13px}.ct-next{padding-top:20px;margin-top:21px;border-top:1px solid var(--ct-line)} +.ct-heading{display:flex;align-items:end;justify-content:space-between;gap:50px;margin-bottom:25px}.contact-nhc h2{font-size:29px}.ct-heading h2{margin-top:9px}.ct-heading>p{font-size:14px;line-height:1.9;color:var(--ct-copy);max-width:400px}.ct-offices{display:grid;grid-template-columns:1fr 1fr;gap:50px}.ct-offices article{border-top:1px solid var(--ct-line);padding-top:21px}.ct-offices h3{font-size:21px;margin:11px 0}.ct-offices address{font-style:normal;font-size:14px;line-height:1.95;color:var(--ct-copy);max-width:460px}.ct-offices .ct-text-link{margin-top:8px}.ct-faq-layout{display:grid;grid-template-columns:1fr 1.65fr;gap:65px}.ct-faq-layout h2{margin-top:10px}.ct-faq details{border-top:1px solid var(--ct-line)}.ct-faq details:last-child{border-bottom:1px solid var(--ct-line)}.ct-faq summary{display:flex;align-items:center;justify-content:space-between;gap:25px;min-height:63px;padding:14px 0;font-size:15px;font-weight:500;cursor:pointer;list-style:none}.ct-faq summary::-webkit-details-marker{display:none}.ct-faq summary>span{position:relative;width:16px;height:16px;flex-shrink:0}.ct-faq summary>span:before,.ct-faq summary>span:after{content:"";position:absolute;left:2px;top:8px;width:12px;height:1px;background:var(--ct-blue)}.ct-faq summary>span:after{transform:rotate(90deg);transition:transform .2s}.ct-faq details[open] summary>span:after{transform:rotate(0)}.ct-faq details>p{padding:0 25px 20px 0;font-size:14px;color:var(--ct-copy);line-height:1.95} +.ct-mobile-header{position:fixed;top:0;left:0;width:100%;height:68px;z-index:1000;background:#fffffff5;border-bottom:1px solid var(--ct-line);display:flex;align-items:center;gap:24px;padding:0 22px}.contact-nhc .ct-brand{font-size:23px;line-height:1.2;font-weight:600;letter-spacing:2px;display:flex;flex-direction:column;justify-content:center;min-height:44px;margin-right:auto}.ct-brand>span{font-size:8px;font-weight:500;letter-spacing:1.5px;margin-top:5px;color:var(--ct-muted)}.contact-nhc .ct-header-contact{min-height:44px;display:flex;align-items:center;font-size:12px;color:var(--ct-blue)}.ct-menu summary{display:flex;align-items:center;gap:7px;min-height:44px;font-size:12px;cursor:pointer;list-style:none}.ct-menu summary::-webkit-details-marker{display:none}.ct-menu svg{width:20px;height:20px;stroke:currentColor;stroke-width:1.5;fill:none}.contact-nhc .ct-menu nav{position:absolute;top:67px;left:0;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:0 28px;padding:14px 22px 22px;background:#fff;border-bottom:1px solid var(--ct-line);box-shadow:0 18px 30px #0f172a0d}.ct-menu nav a{display:flex;align-items:center;min-height:52px;border-bottom:1px solid var(--ct-line);font-size:15px;color:var(--ct-copy)}.contact-nhc .ct-menu nav a[aria-current]{color:var(--ct-blue)} +@media(max-width:1023px){.ct-hero-grid{gap:35px}.contact-nhc h1{font-size:34px}.ct-main-grid{gap:35px;grid-template-columns:1.4fr 1fr}.ct-direct{padding:22px}.contact-nhc h2{font-size:26px}.ct-direct h2{font-size:22px}.ct-captcha{gap:10px}.ct-captcha-refresh{gap:7px}.ct-captcha-refresh>span{display:none}.ct-faq-layout{gap:35px}} +@media(max-width:767px){.ct-wrap{padding:0 22px}.contact-nhc [id]{scroll-margin-top:85px}.ct-hero{padding:84px 0 24px}.ct-crumb{margin-bottom:16px}.ct-eyebrow{font-size:11px}.ct-hero-grid{grid-template-columns:1fr;gap:25px}.contact-nhc h1{font-size:30px;margin:11px 0 16px;letter-spacing:0}.ct-lead{font-size:16px;line-height:1.85}.ct-actions{gap:10px 20px;margin-top:20px}.ct-art figcaption{font-size:10px;padding:10px 13px;gap:15px}.ct-section{padding:28px 0}.ct-main-grid{grid-template-columns:1fr;gap:28px}.contact-nhc h2{font-size:26px}.ct-section-intro>p:last-child{font-size:16px;line-height:1.85}.ct-form{margin-top:20px}.ct-direction legend{font-size:15px}.ct-topics{gap:8px}.ct-topics button{font-size:12px;padding:8px 11px}.ct-field-row{grid-template-columns:1fr;gap:0}.contact-nhc .ct-field label{font-size:15px}.contact-nhc .ct-field input,.contact-nhc .ct-field textarea{font-size:16px;min-height:48px}.ct-field{margin-bottom:18px}.ct-hint{font-size:12px}.ct-field-error{font-size:14px}.ct-captcha-refresh>span{display:inline}.ct-captcha-refresh{flex-shrink:0}.contact-nhc .ct-captcha input{max-width:none;flex:1;min-width:80px}.ct-submit-line{gap:12px}.ct-submit-line>p{font-size:12px}.ct-submit-status{font-size:16px}.ct-form-note{font-size:12px}.ct-direct{padding:23px}.ct-direct h2{font-size:24px}.ct-contact-list dd{font-size:16px}.ct-contact-list .ct-phone{font-size:29px}.ct-prepare h3,.ct-next h3{font-size:17px}.ct-prepare li,.ct-prepare p,.ct-next p{font-size:16px;line-height:1.85}.ct-prepare li>span{font-size:12px}.ct-heading{display:block;margin-bottom:22px}.ct-heading>p{font-size:16px;line-height:1.85;max-width:none;margin-top:13px}.ct-offices{grid-template-columns:1fr;gap:23px}.ct-offices h3{font-size:20px}.ct-offices address{font-size:16px;line-height:1.85}.ct-faq-layout{grid-template-columns:1fr;gap:22px}.ct-faq-layout h2 br{display:none}.ct-faq summary{font-size:16px;gap:20px}.ct-faq details>p{font-size:16px;line-height:1.85;padding:0 0 20px}} +@media(max-width:374px){.ct-wrap{padding:0 18px}.contact-nhc h1{font-size:27px}.ct-captcha-refresh>span{display:none}.ct-mobile-header{gap:20px}.ct-topics button{padding:8px 10px}} +/* The legacy mobile stylesheet forces form styles with !important. */ +.contact-nhc .ct-field input,.contact-nhc .ct-field textarea{box-sizing:border-box!important;border:1px solid #cbd5e1!important;background:#fff!important;padding:11px 13px!important;font-size:16px!important;margin:0!important;box-shadow:none!important;color:var(--ct-ink)!important} +.contact-nhc .ct-field input{height:48px!important}.contact-nhc .ct-field textarea{height:auto!important;min-height:125px!important}.contact-nhc .ct-field :where(input,textarea)[aria-invalid=true]{border-color:var(--ct-error)!important}.contact-nhc .ct-field :where(input,textarea):focus{border-color:var(--ct-blue)!important;box-shadow:0 0 0 1px var(--ct-blue)!important}.contact-nhc .ct-field label{color:var(--ct-ink)!important} +@media(prefers-reduced-motion:reduce){html:has(.contact-nhc){scroll-behavior:auto}.contact-nhc *{animation:none!important;transition:none!important;scroll-behavior:auto!important}} diff --git a/public/assets/addons/official/css/header-brand.css b/public/assets/addons/official/css/header-brand.css new file mode 100644 index 0000000..a27600e --- /dev/null +++ b/public/assets/addons/official/css/header-brand.css @@ -0,0 +1,70 @@ +/* Shared brand masthead. Text follows the site-wide YaHei typography. */ +.nhc-header{background:#fffffff7;border-bottom:1px solid #dce5f0;box-shadow:0 2px 12px #0f172a04} +.nhc-header>.nhc-container{max-width:1360px;padding:0 40px} +.nhc-header .nhc-nav-inner{position:relative;height:80px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:30px} +.nhc-header .nhc-logo{gap:0;min-width:0;white-space:nowrap} +.nhc-header .nhc-brand-home{display:flex;align-items:center;gap:12px;min-height:48px;color:#0f172a} +.nhc-header .nhc-brand-symbol{display:block;width:36px;height:48px;flex-shrink:0;background:url('../images/brand/nhc-official-logo.png') center/auto 100% no-repeat} +.nhc-header .nhc-logo-brand{gap:3px;display:flex;flex-direction:column} +.nhc-header .nhc-logo-text{font-size:25px;line-height:1.2;letter-spacing:3px;font-weight:700;color:#0f172a} +.nhc-header .nhc-logo-sub{font-size:10px;line-height:1.3;letter-spacing:2px;color:#475569;font-weight:500} +.nhc-header .nhc-brand-descriptor{display:flex;flex-direction:column;gap:5px;margin-left:20px;padding-left:20px;border-left:1px solid #d7e0eb;color:#334155;font-size:12px;line-height:1.5;letter-spacing:1px} +.nhc-brand-descriptor small{font-size:9px;color:#64748b;letter-spacing:1px} +.nhc-header .nhc-main-nav{display:flex;align-items:center;height:80px} +.nhc-header .nhc-nav-menu{display:flex;align-items:center;gap:27px;margin:0;padding:0;height:100%} +.nhc-header .nhc-nav-menu>li{position:static;height:100%;display:flex;align-items:center} +.nhc-header .nhc-nav-link{font-size:14px;line-height:1.5;letter-spacing:.3px;display:inline-flex;align-items:center;gap:5px;min-height:80px;padding:0;white-space:nowrap} +.nhc-header .nhc-nav-link::after{bottom:16px;height:2px;border-radius:1px} +.nhc-header .nhc-nav-link:hover::after,.nhc-header .nhc-nav-link.active::after,.nhc-header .nhc-nav-link:focus-visible::after{width:18px} +.nhc-header .nhc-caret{width:11px;height:11px;opacity:.85} +.nhc-header .nhc-nav-actions{justify-self:end;padding-left:24px;border-left:1px solid #e2e8f0;gap:0} +.nhc-header .nhc-nav-actions .nhc-btn{min-height:42px;padding:9px 17px;border-radius:4px;font-size:12px;gap:15px;box-shadow:none;white-space:nowrap} +.nhc-header .nhc-mega-panel{top:100%;left:50%;width:1100px;max-width:100%;border-radius:0 0 6px 6px;padding:28px 30px} +.nhc-header .nhc-has-dropdown:focus-within .nhc-mega-panel{opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0)} +.nhc-header .nhc-has-dropdown:focus-within>.nhc-nav-link{color:#2563eb} +.nhc-header .nhc-compact-menu{display:none} +/* The supplied official logo is shared by desktop and mobile headers. */ +body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header){gap:18px;background:#fffffff7;border-bottom:1px solid #dce5f0;box-shadow:0 2px 12px #0f172a04} +body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand){position:relative;padding-left:36px;font-size:22px!important;letter-spacing:2px;font-weight:700!important;line-height:1.2} +body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand)::before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);width:26px;height:36px;background:url('../images/brand/nhc-official-logo.png') center/auto 100% no-repeat} +body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand)>span{display:none!important} +@media(max-width:1200px){.nhc-header .nhc-brand-descriptor{display:none}.nhc-header .nhc-nav-inner{gap:24px}.nhc-header .nhc-nav-menu{gap:24px}} +@media(min-width:769px) and (max-width:1000px){.nhc-header>.nhc-container{padding-inline:28px}.nhc-header .nhc-nav-inner{gap:18px}.nhc-header .nhc-nav-menu{gap:18px}.nhc-header .nhc-logo-text{font-size:23px}.nhc-header .nhc-logo-sub{font-size:8px;letter-spacing:1.5px}.nhc-header .nhc-brand-symbol{width:30px;height:42px}.nhc-header .nhc-brand-home{gap:10px}.nhc-header .nhc-nav-link{font-size:13px}.nhc-header .nhc-nav-actions{padding-left:18px}.nhc-header .nhc-nav-actions .nhc-btn{padding-inline:13px;gap:10px}} +@media(max-width:768px){.nhc-header>.nhc-container{padding-inline:22px}.nhc-header .nhc-nav-inner{height:68px;grid-template-columns:1fr auto;gap:18px}.nhc-header .nhc-main-nav,.nhc-header .nhc-nav-actions{display:none}.nhc-header .nhc-brand-symbol{width:26px;height:36px}.nhc-header .nhc-brand-home{gap:10px}.nhc-header .nhc-logo-text{font-size:22px;letter-spacing:2px}.nhc-header .nhc-logo-sub{font-size:7px;letter-spacing:1.1px}.nhc-header .nhc-compact-menu{display:block}.nhc-compact-menu summary{display:flex;align-items:center;gap:8px;min-height:44px;cursor:pointer;list-style:none;font-size:12px;color:#334155}.nhc-compact-menu summary::-webkit-details-marker{display:none}.nhc-compact-menu summary svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.5}.nhc-header .nhc-compact-menu nav{position:absolute;top:68px;left:-22px;width:calc(100% + 44px);height:auto;line-height:1.5;background:#fff;border-bottom:1px solid #dce5f0;box-shadow:0 12px 20px #0f172a0a;display:grid;grid-template-columns:1fr 1fr;padding:12px 22px 20px;gap:0 24px}.nhc-compact-menu nav a{display:flex;align-items:center;min-height:50px;border-bottom:1px solid #e2e8f0;color:#334155;font-size:14px}.nhc-compact-menu :is(a,summary):focus-visible{outline:2px solid #2563eb;outline-offset:3px}} +@media(max-width:360px){body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header){gap:12px;padding-inline:18px}body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand){padding-left:34px;font-size:20px!important}body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand)::before{width:24px;height:34px}} + +/* Scrolled masthead: navy ground, light type, original logo on a white tile. */ +html.nhc-nav-scrolled .nhc-header, +html.nhc-nav-scrolled body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header), +html.nhc-nav-scrolled body>.navbar { + background:#0f172af7; + border-bottom-color:#2d3b51; + box-shadow:0 5px 20px #02061726; +} +html.nhc-nav-scrolled .nhc-header :is(.nhc-brand-home,.nhc-logo-text){color:#fff} +html.nhc-nav-scrolled .nhc-header .nhc-logo-sub{color:#cbd5e1} +html.nhc-nav-scrolled .nhc-header .nhc-nav-link, +html.nhc-nav-scrolled .nhc-header .nhc-nav-link:visited{color:#e2e8f0} +html.nhc-nav-scrolled .nhc-header .nhc-nav-link:is(:hover,:focus-visible,.active), +html.nhc-nav-scrolled .nhc-header .nhc-nav-link.active:visited, +html.nhc-nav-scrolled .nhc-header .nhc-has-dropdown:focus-within>.nhc-nav-link{color:#93c5fd} +html.nhc-nav-scrolled .nhc-header .nhc-nav-link::after{background:#93c5fd} +html.nhc-nav-scrolled .nhc-header .nhc-nav-actions{border-left-color:#334155} +html.nhc-nav-scrolled .nhc-header .nhc-compact-menu summary{color:#e2e8f0} +html.nhc-nav-scrolled .nhc-header .nhc-brand-symbol, +html.nhc-nav-scrolled body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand)::before{background-color:#fff;background-size:auto 90%;border-radius:3px} +html.nhc-nav-scrolled body :is(.hn-mobile-brand,.sw2-brand,.sw-brand,.ap-brand,.av-brand,.cs-brand){color:#fff!important} +html.nhc-nav-scrolled body :is(.hn-mobile-contact,.sw2-header-contact,.sw-header-contact,.ap-header-contact,.av-header-contact,.cs-header-contact){color:#dbeafe!important} +html.nhc-nav-scrolled body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header) summary{color:#e2e8f0} +html.nhc-nav-scrolled body>.navbar :is(.content-left a,.content-center h1,.content-right a){color:#fff} + +/* Expanded mobile panels stay white, including when the masthead is dark. */ +body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header,.ab-mobile-header,.ct-mobile-header,.nhc-header) details nav{color:#334155;background:#fff} +body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header,.ab-mobile-header,.ct-mobile-header,.nhc-header) details nav a, +body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header,.ab-mobile-header,.ct-mobile-header,.nhc-header) details nav a:visited{color:#334155} +body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header,.ab-mobile-header,.ct-mobile-header,.nhc-header) details nav a:is([aria-current],:hover,:focus-visible){color:#2563eb} + +/* Mobile dropdowns retain their white panels and dark menu text. */ +html.nhc-nav-scrolled body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header) nav, +html.nhc-nav-scrolled body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header) nav a{color:#334155} +html.nhc-nav-scrolled body :is(.hn-mobile-header,.sw2-mobile-header,.sw-mobile-header,.ap-mobile-header,.av-mobile-header,.cs-mobile-header) nav a:is([aria-current],:hover,:focus-visible){color:#2563eb} diff --git a/public/assets/addons/official/images/about/collaboration.jpg b/public/assets/addons/official/images/about/collaboration.jpg new file mode 100644 index 0000000..e2080b2 Binary files /dev/null and b/public/assets/addons/official/images/about/collaboration.jpg differ diff --git a/public/assets/addons/official/images/about/collaboration.webp b/public/assets/addons/official/images/about/collaboration.webp new file mode 100644 index 0000000..c3db9cc Binary files /dev/null and b/public/assets/addons/official/images/about/collaboration.webp differ diff --git a/public/assets/addons/official/images/about/landscape.jpg b/public/assets/addons/official/images/about/landscape.jpg new file mode 100644 index 0000000..cd7ffa6 Binary files /dev/null and b/public/assets/addons/official/images/about/landscape.jpg differ diff --git a/public/assets/addons/official/images/about/landscape.webp b/public/assets/addons/official/images/about/landscape.webp new file mode 100644 index 0000000..41a7fff Binary files /dev/null and b/public/assets/addons/official/images/about/landscape.webp differ diff --git a/public/assets/addons/official/images/brand/nhc-official-logo.png b/public/assets/addons/official/images/brand/nhc-official-logo.png new file mode 100644 index 0000000..3c73f76 Binary files /dev/null and b/public/assets/addons/official/images/brand/nhc-official-logo.png differ diff --git a/public/assets/addons/official/images/contact/connection.jpg b/public/assets/addons/official/images/contact/connection.jpg new file mode 100644 index 0000000..1d4baf2 Binary files /dev/null and b/public/assets/addons/official/images/contact/connection.jpg differ diff --git a/public/assets/addons/official/images/contact/connection.webp b/public/assets/addons/official/images/contact/connection.webp new file mode 100644 index 0000000..b0d747e Binary files /dev/null and b/public/assets/addons/official/images/contact/connection.webp differ diff --git a/public/assets/addons/official/images/home/ai-computing-mobile-v4.jpg b/public/assets/addons/official/images/home/ai-computing-mobile-v4.jpg new file mode 100644 index 0000000..4006a1f Binary files /dev/null and b/public/assets/addons/official/images/home/ai-computing-mobile-v4.jpg differ diff --git a/public/assets/addons/official/images/home/ai-computing-mobile-v4.webp b/public/assets/addons/official/images/home/ai-computing-mobile-v4.webp new file mode 100644 index 0000000..930b52b Binary files /dev/null and b/public/assets/addons/official/images/home/ai-computing-mobile-v4.webp differ diff --git a/public/assets/addons/official/images/home/ai-computing-v4.jpg b/public/assets/addons/official/images/home/ai-computing-v4.jpg new file mode 100644 index 0000000..d618bb4 Binary files /dev/null and b/public/assets/addons/official/images/home/ai-computing-v4.jpg differ diff --git a/public/assets/addons/official/images/home/ai-computing-v4.webp b/public/assets/addons/official/images/home/ai-computing-v4.webp new file mode 100644 index 0000000..c9a1f5d Binary files /dev/null and b/public/assets/addons/official/images/home/ai-computing-v4.webp differ diff --git a/public/assets/addons/official/js/contact-nhc.js b/public/assets/addons/official/js/contact-nhc.js new file mode 100644 index 0000000..f1baeb6 --- /dev/null +++ b/public/assets/addons/official/js/contact-nhc.js @@ -0,0 +1,108 @@ +(function () { + 'use strict'; + var form = document.querySelector('.ct-form'); + if (!form) return; + var submit = form.querySelector('.ct-submit'); + var status = form.querySelector('.ct-submit-status'); + var topics = Array.from(form.querySelectorAll('[data-topic]')); + var refresh = form.querySelector('.ct-captcha-refresh'); + var fields = Array.from(form.querySelectorAll('input[required],textarea[required]')); + var pending = false; + var messages = {title: '请填写需求主题。', name: '请填写您的称呼。', phone: '请填写联系电话。', content: '请简要说明您的需求。', captcha: '请填写图片验证码。'}; + + function showStatus(message, state) { + status.textContent = message; + status.dataset.state = state; + status.hidden = false; + } + function validate(field) { + var value = field.value.trim(); + var message = value ? '' : messages[field.name]; + if (!message && field.name === 'phone' && (!/^[+\d\s().-]+$/.test(value) || value.replace(/\D/g, '').length < 7)) { + message = '请填写可联系的手机或固定电话,固定电话请包含区号。'; + } + var error = document.getElementById(field.id + '-error'); + field.setAttribute('aria-invalid', String(!!message)); + error.textContent = message; + error.hidden = !message; + return !message; + } + function resetCaptcha() { + if (!refresh) return; + var url = refresh.dataset.captchaUrl; + refresh.querySelector('img').src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'r=' + Date.now(); + form.elements.captcha.value = ''; + } + async function request(url, options) { + var controller = new AbortController(); + var timer = setTimeout(function () { controller.abort(); }, 20000); + try { + var response = await fetch(url, Object.assign({credentials: 'same-origin', cache: 'no-store', signal: controller.signal}, options)); + if (!response.ok) throw new Error('http'); + return await response.json(); + } finally { clearTimeout(timer); } + } + topics.forEach(function (button) { + button.addEventListener('click', function () { + if (pending) return; + form.elements.title.value = button.dataset.topic; + topics.forEach(function (item) { item.setAttribute('aria-pressed', String(item === button)); }); + validate(form.elements.title); + }); + }); + form.elements.title.addEventListener('input', function () { + topics.forEach(function (item) { item.setAttribute('aria-pressed', String(item.dataset.topic === form.elements.title.value)); }); + }); + fields.forEach(function (field) { + field.addEventListener('blur', function () { validate(field); }); + field.addEventListener('input', function () { if (field.getAttribute('aria-invalid') === 'true') validate(field); }); + }); + if (refresh) refresh.addEventListener('click', function () { if (!pending) resetCaptcha(); }); + form.addEventListener('submit', async function (event) { + event.preventDefault(); + if (pending) return; + var invalid = fields.filter(function (field) { return !validate(field); }); + if (invalid.length) { + showStatus('请检查标注的必填内容后再提交。', 'error'); + invalid[0].focus(); + return; + } + pending = true; + fields.forEach(function (field) { field.readOnly = true; }); + submit.disabled = true; + form.setAttribute('aria-busy', 'true'); + submit.textContent = '正在提交…'; + showStatus('正在提交您的项目需求,请稍候。', 'pending'); + var payload = new URLSearchParams(); + fields.forEach(function (field) { payload.set(field.name, field.value.trim()); }); + var submitted = false; + try { + // Token is single-use; obtain one for each attempt, including retries. + var token = await request(form.dataset.tokenUrl); + if (Number(token.code) !== 1 || !token.data) throw new Error('token'); + form.elements.__token__.value = token.data; + payload.set('__token__', token.data); + submitted = true; + var result = await request(form.action, {method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest'}, body: payload.toString()}); + if (Number(result.code) === 1) { + form.reset(); + topics.forEach(function (item) { item.setAttribute('aria-pressed', 'false'); }); + fields.forEach(function (field) { field.removeAttribute('aria-invalid'); document.getElementById(field.id + '-error').hidden = true; }); + showStatus('您的需求已提交。我们将根据您留下的联系方式与您沟通,请保持电话畅通。', 'success'); + } else { + var message = result.msg === '请先登录!' ? '页面校验已失效,请重试提交。' : String(result.msg || '暂未提交成功,请稍后重试或通过电话联系。'); + showStatus(message, 'error'); + } + resetCaptcha(); + } catch (error) { + showStatus(submitted ? '暂时无法确认提交结果。为避免重复提交,请稍后通过电话或邮箱确认;您填写的内容已保留。' : '暂时无法连接提交服务,请稍后重试或通过电话、邮箱联系。您填写的内容已保留。', 'error'); + } finally { + pending = false; + fields.forEach(function (field) { field.readOnly = false; }); + submit.disabled = false; + submit.textContent = '提交项目需求 ↗'; + form.setAttribute('aria-busy', 'false'); + status.focus(); + } + }); +})(); diff --git a/public/assets/addons/official/js/header-scroll.js b/public/assets/addons/official/js/header-scroll.js new file mode 100644 index 0000000..06e0289 --- /dev/null +++ b/public/assets/addons/official/js/header-scroll.js @@ -0,0 +1,22 @@ +/* Keep the public navigation readable while content passes beneath it. */ +(function () { + 'use strict'; + var root = document.documentElement; + var pending = false; + + function update() { + root.classList.toggle('nhc-nav-scrolled', window.scrollY > 40); + pending = false; + } + + function onScroll() { + if (!pending) { + pending = true; + window.requestAnimationFrame(update); + } + } + + update(); + window.addEventListener('scroll', onScroll, { passive: true }); + window.addEventListener('pageshow', update); +}()); diff --git a/tests/contact_form_browser.js b/tests/contact_form_browser.js new file mode 100644 index 0000000..c55e6b9 --- /dev/null +++ b/tests/contact_form_browser.js @@ -0,0 +1,62 @@ +// Run on the local contact preview with agent-browser eval. All requests are mocked. +(async function () { + if (!location.hostname.match(/^(127\.0\.0\.1|localhost)$/)) throw new Error('Use local preview only'); + var form = document.querySelector('.ct-form'); + var submit = form.querySelector('.ct-submit'); + var status = form.querySelector('.ct-submit-status'); + var originalFetch = window.fetch; + var calls = []; + var mode = 'reject'; + var results = []; + function assert(condition, name) { if (!condition) throw new Error(name); results.push(name); } + window.fetch = async function (url, options) { + calls.push({url: String(url), method: options.method || 'GET', body: options.body || ''}); + if (!options.method) { + if (mode === 'token-fail') throw new Error('network'); + return {ok: true, json: async function () { return {code: 1, data: 'test-single-use-token'}; }}; + } + if (mode === 'network-fail') throw new Error('network'); + await new Promise(function (resolve) { setTimeout(resolve, 10); }); + return {ok: true, json: async function () { return mode === 'success' ? {code: 1} : {code: 0, msg: '验证码不正确'}; }}; + }; + function fill() { + form.elements.title.value = '本地界面测试'; + form.elements.name.value = '测试'; + form.elements.phone.value = '0851-12345678'; + form.elements.content.value = '本地模拟数据,不会向线上发送。'; + if (form.elements.captcha) form.elements.captcha.value = 'test'; + } + function send() { form.dispatchEvent(new Event('submit', {bubbles: true, cancelable: true})); } + async function settled() { + for (var i = 0; i < 100; i++) { + if (form.getAttribute('aria-busy') !== 'true') return; + await new Promise(function (resolve) { setTimeout(resolve, 5); }); + } + throw new Error('Form did not settle'); + } + try { + form.reset(); send(); + assert(calls.length === 0 && document.activeElement === form.elements.title, 'Empty form: focus first error, no request'); + form.querySelector('[data-topic]').click(); + assert(form.elements.title.value === form.querySelector('[data-topic]').dataset.topic, 'Topic button fills title'); + fill(); form.elements.phone.value = '123'; send(); + assert(calls.length === 0 && form.elements.phone.getAttribute('aria-invalid') === 'true', 'Invalid phone blocked'); + fill(); send(); send(); + assert(submit.disabled, 'Submitting state disables button'); + await settled(); + assert(calls.filter(function (c) { return c.method === 'POST'; }).length === 1, 'Duplicate submit sends one POST'); + var body = new URLSearchParams(calls.find(function (c) { return c.method === 'POST'; }).body); + assert(body.get('__token__') === 'test-single-use-token' && body.get('phone') === '0851-12345678', 'Uses fresh token and expected backend fields'); + assert(status.dataset.state === 'error' && form.elements.content.value.length > 0 && !submit.disabled, 'Server rejection preserves fields and permits retry'); + if (form.elements.captcha) assert(form.elements.captcha.value === '', 'Rejected submission refreshes captcha'); + calls = []; fill(); mode = 'success'; send(); await settled(); + assert(status.dataset.state === 'success' && form.elements.name.value === '' && form.elements.content.value === '', 'Confirmed success clears fields and announces result'); + assert(calls.length === 2 && calls[0].method === 'GET', 'Retry obtains a new token'); + calls = []; fill(); mode = 'network-fail'; send(); await settled(); + assert(status.dataset.state === 'error' && status.textContent.includes('无法确认提交结果') && form.elements.content.value.length > 0, 'Unknown POST outcome preserves data without automatic retry'); + assert(calls.length === 2 && !submit.disabled, 'Network failure releases button'); + calls = []; fill(); mode = 'token-fail'; send(); await settled(); + assert(calls.length === 1 && status.dataset.state === 'error', 'Token fetch failure never sends POST'); + return {passed: results.length, checks: results, network: 'Mocked locally; no real messages sent'}; + } finally { window.fetch = originalFetch; } +})(); diff --git a/tests/test_ad_law_compliance.py b/tests/test_ad_law_compliance.py index 12d35e8..4f4970a 100644 --- a/tests/test_ad_law_compliance.py +++ b/tests/test_ad_law_compliance.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ 中华人民共和国广告法文案合规自动化专项测试 (Ad Law Compliance Test Suite) @@ -34,7 +33,7 @@ class TestAdLawCompliance(unittest.TestCase): self.contents = {} for key, path in self.target_files.items(): if os.path.exists(path): - with open(path, 'r', encoding='utf-8') as f: + with open(path, encoding='utf-8') as f: self.contents[key] = f.read() else: self.contents[key] = "" @@ -56,9 +55,10 @@ class TestAdLawCompliance(unittest.TestCase): # 严禁出现“国家级认定”、“国家级自主研发”等违法表述 self.assertNotIn('国家级自主研发', self.all_text, "不得使用'国家级自主研发'违规修饰") self.assertNotIn('国家级科技创新认定', self.all_text, "不得使用'国家级科技创新认定'违规表述") - # 合规的表达应当为官方备案机构或高新技术企业全称 - self.assertIn('全国高新技术企业认定管理机构备案认定', self.contents['single_pc'], - "资质表述须符合法定规范,应使用全国高新技术企业认定管理机构备案认定") + # 合规的表达应当使用法定全称,并以有效资料与证书为准 + for page_name, content in (('PC 关于我们页', self.contents['single_pc']), ('移动端关于我们页', self.contents['single_m'])): + self.assertIn('计算机软件著作权', content, f"{page_name}资质表述应使用法定全称") + self.assertIn('以有效证书为准', content, f"{page_name}资质表述应以有效证书为准") def test_no_absolute_guarantee_and_exaggeration(self): """广告法第四条/第二十八条:严禁绝对化与夸大免责承诺""" @@ -73,7 +73,7 @@ class TestAdLawCompliance(unittest.TestCase): clean_text = re.sub(r'[\'\"a-zA-Z0-9_\-:]*\s*:\s*100%', '', self.all_text) clean_text = re.sub(r'width\s*=\s*[\'\"]100%[\'\"]', '', clean_text) clean_text = re.sub(r'height\s*=\s*[\'\"]100%[\'\"]', '', clean_text) - + self.assertNotIn('准确率: 100%', clean_text, "分账准确率不得夸大承诺100%") self.assertNotIn('自动对账率: 100%', clean_text, "对账率不得夸大承诺100%") self.assertNotIn('100% 完整源码', clean_text, "应表述为完整工程源码交付,避免100%绝对词") @@ -133,7 +133,7 @@ class TestAdLawCompliance(unittest.TestCase): """排查 public/assets/addons/official/images/showcases/ 目录下所有原型 SVG 是否包含虚假宣传数据""" svg_dir = os.path.join(ROOT_DIR, 'public/assets/addons/official/images/showcases') self.assertTrue(os.path.exists(svg_dir), f"SVG 展示目录不存在: {svg_dir}") - + # 针对每个 SVG 定义违规关键词 svg_forbidden_rules = { 'case_distrib.svg': [ @@ -168,7 +168,7 @@ class TestAdLawCompliance(unittest.TestCase): for filename, forbidden_list in svg_forbidden_rules.items(): svg_path = os.path.join(svg_dir, filename) if os.path.exists(svg_path): - with open(svg_path, 'r', encoding='utf-8') as f: + with open(svg_path, encoding='utf-8') as f: content = f.read() for forbidden in forbidden_list: self.assertNotIn(forbidden, content, f"SVG 文件 {filename} 中严禁包含虚假宣传或夸大编造数据: '{forbidden}'") diff --git a/tests/test_client_rigor_enhancements.py b/tests/test_client_rigor_enhancements.py index 31577e4..f6f2db7 100644 --- a/tests/test_client_rigor_enhancements.py +++ b/tests/test_client_rigor_enhancements.py @@ -41,18 +41,13 @@ class TestClientRigorEnhancements(unittest.TestCase): "案例独立页必须包含明确的验收与生产运行记录") def test_authoritative_certifications_and_copyright_numbers(self): - """关于我们资质板块必须展示规整的资质体系与等保合规""" - # ISO 与 等保 - self.assertIn('ISO9001', self.about_html, "PC 关于我们必须包含 ISO9001 质量认证") - self.assertIn('ISO27001', self.about_html, "PC 关于我们必须包含 ISO27001 安全认证") - self.assertTrue('等保' in self.about_html, "PC 关于我们必须包含等保合规设计") - # 软著与知识产权 - self.assertTrue('计算机软件著作权' in self.about_html and '自主可控' in self.about_html, - "PC 关于我们必须展示自主可控的计算机软件著作权与知识产权") - - # 移动端同步 - self.assertIn('ISO', self.about_mobile, "移动端关于我们必须同步展示权威资质") - self.assertTrue('等保' in self.about_mobile, "移动端关于我们必须同步展示等保合规") + """资质和软件权属应说明核验依据,不以示意徽章冒充认证。""" + for content in (self.about_html, self.about_mobile): + for label in ('企业主体', '计算机软件著作权', '第三方组件', '合同', 'ISO9001', 'ISO27001', '等保'): + self.assertIn(label, content) + self.assertIn('具体认证情况以有效证书为准', content) + self.assertNotIn('cert_hi_tech.svg', content) + self.assertNotIn('cert_iso9001.svg', content) def test_demo_sandbox_rigorous_commitment(self): """产品页演示沙箱必须具备极速建联与真实脱敏环境承诺""" diff --git a/tests/test_dedicated_page_illustrations.py b/tests/test_dedicated_page_illustrations.py index d7bbbd1..deb1874 100644 --- a/tests/test_dedicated_page_illustrations.py +++ b/tests/test_dedicated_page_illustrations.py @@ -5,6 +5,7 @@ 2. 验证新版服务页摄影配图真实存在、尺寸满足首屏展示要求,并提供 WebP 兼容版本; 3. 验证联系我们页矢量配图符合浅色专业风规范。 """ + import os import unittest @@ -12,54 +13,86 @@ from PIL import Image ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -RASTER_ROOT = os.path.join(ROOT_DIR, 'public', 'assets', 'addons', 'official', 'images') -SHOWCASE_ROOT = os.path.join(RASTER_ROOT, 'showcases') +RASTER_ROOT = os.path.join(ROOT_DIR, "public", "assets", "addons", "official", "images") +SHOWCASE_ROOT = os.path.join(RASTER_ROOT, "showcases") SERVICE_HEROES = { - 'software': ('software/structure-v2.jpg', 1440, 960), - 'app': ('app/terminals.jpg', 1440, 960), - 'agent': ('agent/landscape-v2.jpg', 1920, 640), + "software": ("software/structure-v2.jpg", 1440, 960), + "app": ("app/terminals.jpg", 1440, 960), + "agent": ("agent/landscape-v2.jpg", 1920, 640), + "contact": ("contact/connection.jpg", 1440, 960), } class TestDedicatedPageIllustrations(unittest.TestCase): - def test_illustration_assets_exist(self): """测试专属配图文件存在、格式有效且尺寸满足展示要求""" - for key, (relative_path, minimum_width, minimum_height) in SERVICE_HEROES.items(): + for key, ( + relative_path, + minimum_width, + minimum_height, + ) in SERVICE_HEROES.items(): with self.subTest(page=key): jpg_path = os.path.join(RASTER_ROOT, relative_path) - webp_path = os.path.splitext(jpg_path)[0] + '.webp' - self.assertTrue(os.path.isfile(jpg_path), f"缺少专属精美配图: {relative_path}") - self.assertTrue(os.path.isfile(webp_path), f"缺少 WebP 兼容版本: {relative_path}") + webp_path = os.path.splitext(jpg_path)[0] + ".webp" + self.assertTrue( + os.path.isfile(jpg_path), f"缺少专属精美配图: {relative_path}" + ) + self.assertTrue( + os.path.isfile(webp_path), f"缺少 WebP 兼容版本: {relative_path}" + ) with Image.open(jpg_path) as hero: width, height = hero.size - self.assertGreaterEqual(width, minimum_width, f"{relative_path} 宽度不足首屏要求") - self.assertGreaterEqual(height, minimum_height, f"{relative_path} 高度不足首屏要求") - self.assertGreater(os.path.getsize(jpg_path), 50_000, f"{relative_path} 文件过小") + self.assertGreaterEqual( + width, minimum_width, f"{relative_path} 宽度不足首屏要求" + ) + self.assertGreaterEqual( + height, minimum_height, f"{relative_path} 高度不足首屏要求" + ) + self.assertGreater( + os.path.getsize(jpg_path), 50_000, f"{relative_path} 文件过小" + ) - contact_path = os.path.join(SHOWCASE_ROOT, 'contact_headquarters.svg') - with open(contact_path, encoding='utf-8') as stream: + contact_path = os.path.join(SHOWCASE_ROOT, "contact_headquarters.svg") + with open(contact_path, encoding="utf-8") as stream: contact_content = stream.read() - self.assertIn(']+alt="[^"]{4,}"', f"首屏图片应包含有效替代文本:{page_path}") + self.assertRegex( + html, + r']+alt="[^"]{4,}"', + f"首屏图片应包含有效替代文本:{page_path}", + ) if __name__ == "__main__":