main
huyuanxiang 4 weeks ago
parent a8e562c9f6
commit d46195d9f4

40
.gitignore vendored

@ -0,0 +1,40 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
wp-admin/
wp-includes/
wp-content/languages/
wp-content/mu-plugins/
wp-content/plugins/
wp-content/uploads/
wp-content/themes/backup
wp-content/cache
.idea
.agent
.claude
.codex
.cursor
.gemini
.github
.idea
.kiro
.roo
.shared
.vscode
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
.idea
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.

@ -0,0 +1,11 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

@ -1,3 +0,0 @@
# official-website-abroad
海外网站

@ -0,0 +1,83 @@
<?php
/**
* WordPress站点URL修复脚本
* 用于在数据库迁移后更新站点URL配置
*/
// 加载WordPress环境
require_once __DIR__ . '/wp-load.php';
// 获取当前配置的本地URL
$local_url = 'http://localhost:82';
echo "=== WordPress站点URL修复工具 ===\n\n";
// 1. 获取当前数据库中的siteurl和home值
$current_siteurl = get_option('siteurl');
$current_home = get_option('home');
echo "当前数据库中的配置:\n";
echo "siteurl: " . $current_siteurl . "\n";
echo "home: " . $current_home . "\n\n";
// 2. 更新为本地URL
echo "正在更新为本地URL: " . $local_url . "\n\n";
update_option('siteurl', $local_url);
update_option('home', $local_url);
// 3. 验证更新结果
$new_siteurl = get_option('siteurl');
$new_home = get_option('home');
echo "更新后的配置:\n";
echo "siteurl: " . $new_siteurl . "\n";
echo "home: " . $new_home . "\n\n";
// 4. 清除缓存
if (function_exists('wp_cache_flush')) {
wp_cache_flush();
echo "缓存已清除\n\n";
}
// 5. 检查是否需要修复其他URL
echo "检查是否需要修复其他URL...\n";
// 修复文章内容中的URL可选
global $wpdb;
$old_url = $current_siteurl;
$count = $wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->posts}
SET post_content = REPLACE(post_content, %s, %s)",
$old_url,
$local_url
)
);
if ($count > 0) {
echo "已修复 {$count} 篇文章中的URL链接\n\n";
} else {
echo "文章内容URL无需修复\n\n";
}
// 6. 修复选项表中的其他URL
$options_to_fix = [
'upload_path',
'upload_url_path',
'widget_text',
'sidebars_widgets',
];
foreach ($options_to_fix as $option_name) {
$option_value = get_option($option_name);
if ($option_value && is_string($option_value) && strpos($option_value, $old_url) !== false) {
$new_value = str_replace($old_url, $local_url, $option_value);
update_option($option_name, $new_value);
echo "已修复选项: {$option_name}\n";
}
}
echo "\n=== 修复完成! ===\n";
echo "现在可以访问: http://localhost:82wp-admin\n";
echo "请使用原有的管理员账号登录\n";

@ -0,0 +1 @@
google-site-verification: googleb9a847eee76af35d.html

@ -0,0 +1,17 @@
<?php
/**
* Front to the WordPress application. This file doesn't do anything, but loads
* wp-blog-header.php which does and tells WordPress to load the theme.
*
* @package WordPress
*/
/**
* Tells WordPress to load the WordPress theme and output it.
*
* @var bool
*/
define( 'WP_USE_THEMES', true );
/** Loads the WordPress Environment and Template */
require __DIR__ . '/wp-blog-header.php';

@ -0,0 +1,214 @@
<?php
/**
* Confirms that the activation key that is sent in an email after a user signs
* up for a new site matches the key for that user and then displays confirmation.
*
* @package WordPress
*/
define( 'WP_INSTALLING', true );
/** Sets up the WordPress Environment. */
require __DIR__ . '/wp-load.php';
require __DIR__ . '/wp-blog-header.php';
if ( ! is_multisite() ) {
wp_redirect( wp_registration_url() );
die();
}
$valid_error_codes = array( 'already_active', 'blog_taken' );
list( $activate_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
$activate_cookie = 'wp-activate-' . COOKIEHASH;
$key = '';
$result = null;
if ( isset( $_GET['key'] ) && isset( $_POST['key'] ) && $_GET['key'] !== $_POST['key'] ) {
wp_die( __( 'A key value mismatch has been detected. Please follow the link provided in your activation email.' ), __( 'An error occurred during the activation' ), 400 );
} elseif ( ! empty( $_GET['key'] ) ) {
$key = sanitize_text_field( $_GET['key'] );
} elseif ( ! empty( $_POST['key'] ) ) {
$key = sanitize_text_field( $_POST['key'] );
}
if ( $key ) {
$redirect_url = remove_query_arg( 'key' );
if ( remove_query_arg( false ) !== $redirect_url ) {
setcookie( $activate_cookie, $key, 0, $activate_path, COOKIE_DOMAIN, is_ssl(), true );
wp_safe_redirect( $redirect_url );
exit;
} else {
$result = wpmu_activate_signup( $key );
}
}
if ( null === $result && isset( $_COOKIE[ $activate_cookie ] ) ) {
$key = $_COOKIE[ $activate_cookie ];
$result = wpmu_activate_signup( $key );
setcookie( $activate_cookie, ' ', time() - YEAR_IN_SECONDS, $activate_path, COOKIE_DOMAIN, is_ssl(), true );
}
if ( null === $result || ( is_wp_error( $result ) && 'invalid_key' === $result->get_error_code() ) ) {
status_header( 404 );
} elseif ( is_wp_error( $result ) ) {
$error_code = $result->get_error_code();
if ( ! in_array( $error_code, $valid_error_codes, true ) ) {
status_header( 400 );
}
}
nocache_headers();
// Fix for page title.
$wp_query->is_404 = false;
/**
* Fires before the Site Activation page is loaded.
*
* @since 3.0.0
*/
do_action( 'activate_header' );
/**
* Adds an action hook specific to this page.
*
* Fires on {@see 'wp_head'}.
*
* @since MU (3.0.0)
*/
function do_activate_header() {
/**
* Fires within the `<head>` section of the Site Activation page.
*
* Fires on the {@see 'wp_head'} action.
*
* @since 3.0.0
*/
do_action( 'activate_wp_head' );
}
add_action( 'wp_head', 'do_activate_header' );
/**
* Loads styles specific to this page.
*
* @since MU (3.0.0)
*/
function wpmu_activate_stylesheet() {
?>
<style type="text/css">
.wp-activate-container { width: 90%; margin: 0 auto; }
.wp-activate-container form { margin-top: 2em; }
#submit, #key { width: 100%; font-size: 24px; box-sizing: border-box; }
#language { margin-top: 0.5em; }
.wp-activate-container .error { background: #f66; color: #333; }
span.h3 { padding: 0 8px; font-size: 1.3em; font-weight: 600; }
</style>
<?php
}
add_action( 'wp_head', 'wpmu_activate_stylesheet' );
add_action( 'wp_head', 'wp_strict_cross_origin_referrer' );
add_filter( 'wp_robots', 'wp_robots_sensitive_page' );
get_header( 'wp-activate' );
$blog_details = get_site();
?>
<div id="signup-content" class="widecolumn">
<div class="wp-activate-container">
<?php if ( ! $key ) { ?>
<h2><?php _e( 'Activation Key Required' ); ?></h2>
<form name="activateform" id="activateform" method="post" action="<?php echo esc_url( network_site_url( $blog_details->path . 'wp-activate.php' ) ); ?>">
<p>
<label for="key"><?php _e( 'Activation Key:' ); ?></label>
<br /><input type="text" name="key" id="key" value="" size="50" autofocus="autofocus" />
</p>
<p class="submit">
<input id="submit" type="submit" name="Submit" class="submit" value="<?php esc_attr_e( 'Activate' ); ?>" />
</p>
</form>
<?php
} else {
if ( is_wp_error( $result ) && in_array( $result->get_error_code(), $valid_error_codes, true ) ) {
$signup = $result->get_error_data();
?>
<h2><?php _e( 'Your account is now active!' ); ?></h2>
<?php
echo '<p class="lead-in">';
if ( '' === $signup->domain . $signup->path ) {
printf(
/* translators: 1: Login URL, 2: Username, 3: User email address, 4: Lost password URL. */
__( 'Your account has been activated. You may now <a href="%1$s">log in</a> to the site using your chosen username of &#8220;%2$s&#8221;. Please check your email inbox at %3$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can <a href="%4$s">reset your password</a>.' ),
esc_url( network_site_url( $blog_details->path . 'wp-login.php', 'login' ) ),
esc_html( $signup->user_login ),
esc_html( $signup->user_email ),
esc_url( wp_lostpassword_url() )
);
} else {
printf(
/* translators: 1: Site URL, 2: Username, 3: User email address, 4: Lost password URL. */
__( 'Your site at %1$s is active. You may now log in to your site using your chosen username of &#8220;%2$s&#8221;. Please check your email inbox at %3$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can <a href="%4$s">reset your password</a>.' ),
sprintf( '<a href="http://%1$s">%1$s</a>', esc_url( $signup->domain . $blog_details->path ) ),
esc_html( $signup->user_login ),
esc_html( $signup->user_email ),
esc_url( wp_lostpassword_url() )
);
}
echo '</p>';
} elseif ( null === $result || is_wp_error( $result ) ) {
?>
<h2><?php _e( 'An error occurred during the activation' ); ?></h2>
<?php if ( is_wp_error( $result ) ) : ?>
<p><?php echo esc_html( $result->get_error_message() ); ?></p>
<?php endif; ?>
<?php
} else {
$url = isset( $result['blog_id'] ) ? esc_url( get_home_url( (int) $result['blog_id'] ) ) : '';
$user = get_userdata( (int) $result['user_id'] );
?>
<h2><?php _e( 'Your account is now active!' ); ?></h2>
<div id="signup-welcome">
<p><span class="h3"><?php _e( 'Username:' ); ?></span> <?php echo esc_html( $user->user_login ); ?></p>
<p><span class="h3"><?php _e( 'Password:' ); ?></span> <?php echo esc_html( $result['password'] ); ?></p>
</div>
<?php
if ( $url && network_home_url( '', 'http' ) !== $url ) :
switch_to_blog( (int) $result['blog_id'] );
$login_url = wp_login_url();
restore_current_blog();
?>
<p class="view">
<?php
/* translators: 1: Site URL, 2: Login URL. */
printf( __( 'Your account is now activated. <a href="%1$s">View your site</a> or <a href="%2$s">Log in</a>' ), esc_url( $url ), esc_url( $login_url ) );
?>
</p>
<?php else : ?>
<p class="view">
<?php
printf(
/* translators: 1: Login URL, 2: Network home URL. */
__( 'Your account is now activated. <a href="%1$s">Log in</a> or go back to the <a href="%2$s">homepage</a>.' ),
esc_url( network_site_url( $blog_details->path . 'wp-login.php', 'login' ) ),
esc_url( network_home_url( $blog_details->path ) )
);
?>
</p>
<?php
endif;
}
}
?>
</div>
</div>
<?php
get_footer( 'wp-activate' );

@ -0,0 +1,21 @@
<?php
/**
* Loads the WordPress environment and template.
*
* @package WordPress
*/
if ( ! isset( $wp_did_header ) ) {
$wp_did_header = true;
// Load the WordPress library.
require_once __DIR__ . '/wp-load.php';
// Set up the WordPress query.
wp();
// Load the theme template.
require_once ABSPATH . WPINC . '/template-loader.php';
}

@ -0,0 +1,81 @@
<?php
/**
* Handles Comment Post to WordPress and prevents duplicate comment posting.
*
* @package WordPress
*/
if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
$protocol = $_SERVER['SERVER_PROTOCOL'];
if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0', 'HTTP/3' ), true ) ) {
$protocol = 'HTTP/1.0';
}
header( 'Allow: POST' );
header( "$protocol 405 Method Not Allowed" );
header( 'Content-Type: text/plain' );
exit;
}
/** Sets up the WordPress Environment. */
require __DIR__ . '/wp-load.php';
nocache_headers();
$comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
if ( is_wp_error( $comment ) ) {
$data = (int) $comment->get_error_data();
if ( ! empty( $data ) ) {
wp_die(
'<p>' . $comment->get_error_message() . '</p>',
__( 'Comment Submission Failure' ),
array(
'response' => $data,
'back_link' => true,
)
);
} else {
exit;
}
}
$user = wp_get_current_user();
$cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) );
/**
* Fires after comment cookies are set.
*
* @since 3.4.0
* @since 4.9.6 The `$cookies_consent` parameter was added.
*
* @param WP_Comment $comment Comment object.
* @param WP_User $user Comment author's user object. The user may not exist.
* @param bool $cookies_consent Comment author's consent to store cookies.
*/
do_action( 'set_comment_cookies', $comment, $user, $cookies_consent );
$location = empty( $_POST['redirect_to'] ) ? get_comment_link( $comment ) : $_POST['redirect_to'] . '#comment-' . $comment->comment_ID;
// If user didn't consent to cookies, add specific query arguments to display the awaiting moderation message.
if ( ! $cookies_consent && 'unapproved' === wp_get_comment_status( $comment ) && ! empty( $comment->comment_author_email ) ) {
$location = add_query_arg(
array(
'unapproved' => $comment->comment_ID,
'moderation-hash' => wp_hash( $comment->comment_date_gmt ),
),
$location
);
}
/**
* Filters the location URI to send the commenter after posting.
*
* @since 2.0.5
*
* @param string $location The 'redirect_to' URI sent via $_POST.
* @param WP_Comment $comment Comment object.
*/
$location = apply_filters( 'comment_post_redirect', $location, $comment );
wp_safe_redirect( $location );
exit;

@ -0,0 +1,102 @@
<?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don't have to use the website, you can copy this file to "wp-config.php"
* and fill in the values.
*
* This file contains the following configurations:
*
* * Database settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/
*
* @package WordPress
*/
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'database_name_here' );
/** Database username */
define( 'DB_USER', 'username_here' );
/** Database password */
define( 'DB_PASSWORD', 'password_here' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'put your unique phrase here' );
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
define( 'NONCE_KEY', 'put your unique phrase here' );
define( 'AUTH_SALT', 'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
define( 'NONCE_SALT', 'put your unique phrase here' );
/**#@-*/
/**
* WordPress database table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*
* At the installation time, database tables are created with the specified prefix.
* Changing this value after WordPress is installed will make your site think
* it has not been installed.
*
* @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/#table-prefix
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the documentation.
*
* @link https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/
*/
define( 'WP_DEBUG', false );
/* Add any custom values between this line and the "stop editing" line. */
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

@ -0,0 +1,104 @@
<?php
define( 'WP_CACHE', true ); // Added by WP Rocket
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don't have to use the website, you can copy this file to "wp-config.php"
* and fill in the values.
*
* This file contains the following configurations:
*
* * Database settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/
*
* @package WordPress
*/
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'nenghui_sql_new' );
/** Database username */
define( 'DB_USER', 'root' );
/** Database password */
define( 'DB_PASSWORD', 'root123' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define('AUTH_KEY', 'hcu`M50gkGcDc-*w dkOvcX?a(>U[yzWEWnx)uoWpSVyn8rsrNmC>$l#.$Fw<o;3');
define('SECURE_AUTH_KEY', '>5|nA+he~Xy6wd#I|Plj3u+)-lQeH:LJmAKA7paw`$:g/,VA`K{Q=}dFYr~-zUv]');
define('LOGGED_IN_KEY', '/DCK24<Q+[92 ?LmkMYur9.|cP^Noxpj5)^!.c[H#_]L1l`o?Qs|HWz|.nz1h`]}');
define('NONCE_KEY', 'yh:C9Yv>H2U{>eri&W)1;}Cnv:8Q|]RpUnymRQ6x~}3|Q[wy0yC+|CaZ@-Y=btZD');
define('AUTH_SALT', '8WA$moce-{uA$+*84z}8bS);Ei;hedt13a+tpR:/}UNA{0u!^.Hw,SbE,)<q8%p<');
define('SECURE_AUTH_SALT', '+jiE7u*x$Bz`-6lr3oWmL+ul(uhA^lAsfKzk=ampakbIYC.zeE:}]BhV0z9ll<9N');
define('LOGGED_IN_SALT', '}4W$FK(5n/i<4YA*HE^D_7,%LS<>a(0*d>Zki62CD_HAmY=77sA^AD%HgJ::rXt<');
define('NONCE_SALT', 'fs/WpNr<8yo6iRDS&hgru2i0w@K5tC/0T6gxk(f1}XsxfnBX@|pid^<q o98@v:v');
/**#@-*/
/**
* WordPress database table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*
* At the installation time, database tables are created with the specified prefix.
* Changing this value after WordPress is installed will make your site think
* it has not been installed.
*
* @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/#table-prefix
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the documentation.
*
* @link https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/
*/
define( 'WP_DEBUG', false);
/* Add any custom values between this line and the "stop editing" line. */
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

@ -0,0 +1,2 @@
<?php
// Silence is golden.

@ -0,0 +1,269 @@
# 上海能辉科技定制前端主题
**Theme Name:** 上海能辉科技定制前端-安全增强版本
**Theme URI:** https://www.nenghui.com/
**Author:** 上海能辉科技
**Description:** 上海能辉科技,基于 WordPress 定制的专用前端主题,修复安全问题,提升系统安全性。
**Version:** 1.6.0
## 项目介绍
上海能辉科技定制前端是一个专为上海能辉科技公司开发的现代化 WordPress 主题。该主题采用模块化架构设计,具有高性能、安全性和可扩展性,专注于能源科技行业的展示需求。
## 核心特性
### 🎨 现代化设计
- 响应式布局,完美适配各种设备
- 现代化 UI 设计,符合能源科技行业特色
- 支持 WebP 和 SVG 格式图片
- 内置动画效果和交互体验
### 🚀 高性能优化
- 模块化代码架构,按需加载
- 图片压缩和 WebP 自动生成
- 内存使用监控和优化
- 临时文件自动清理
- 服务器资源智能管理
### 🔒 安全防护
- PHP 木马防护和文件扫描
- 文件上传安全检查
- 恶意代码检测和清理
- 安全日志记录
### 📱 功能模块
- **Banner 轮播**:支持多图轮播,可自定义内容和样式
- **Futures 展示**:特性项目展示区块
- **新闻模块**:动态新闻展示,支持分类筛选
- **选项卡系统**:多选项卡内容展示
- **自定义器集成**:可视化配置界面
## 文件结构
```
nenghui-energy-theme-2/
├── 404.php # 404错误页面
├── README.md # 项目说明文档
├── archive.php # 归档页面模板
├── assets/ # 静态资源目录
│ ├── css/ # 样式文件
│ │ ├── admin.css # 后台管理样式
│ │ ├── animate.min.css # 动画效果库
│ │ └── index.css # 主要样式文件
│ ├── images/ # 图片资源
│ │ ├── NaN-img.png # 默认占位图片
│ │ ├── futures-bg.webp # Futures背景图
│ │ ├── logo-1.svg # Logo图标1
│ │ └── logo-2.svg # Logo图标2
│ └── js/ # JavaScript文件
│ ├── customizer-controls.js # 自定义器控制脚本
│ ├── customizer-preview.js # 自定义器预览脚本
│ ├── index.js # 主要交互脚本
│ ├── jquery.min.js # jQuery库
│ └── tinytyper.min.js # 打字机效果库
├── comments.php # 评论模板
├── docs/ # 文档目录
│ ├── architecture_issues.md # 架构问题分析
│ ├── banner_shortcode.md # Banner短代码说明
│ ├── futures_shortcode.md # Futures短代码说明
│ ├── home_news_shortcode.md # 新闻短代码说明
│ ├── home_tabs_shortcode.md # 选项卡短代码说明
│ ├── product_swiper_shortcode.md # 产品轮播短代码说明
│ └── project_evaluation_report.md # 项目评分报告文档
├── footer.php # 页脚模板
├── functions.php # 主题功能文件(模块化入口)
├── header.php # 页头模板
├── inc/ # 功能模块目录
│ ├── init-config.php # 初始化配置(服务器资源、图片压缩等)
│ ├── theme-setup.php # 主题设置和功能支持
│ ├── admin-config.php # 后台管理配置
│ ├── assets-loader.php # 脚本和样式加载器
│ ├── media-config.php # 媒体和文件上传配置
│ ├── cleanup.php # 清理和优化功能
│ ├── customizer.php # 主题自定义器设置
│ ├── performance-config.php # 性能配置和安全防护
│ └── shortcode.php # 短代码功能
├── index.php # 主页模板
├── page-full-width.php # 全宽页面模板
├── page.php # 页面模板
├── screenshot.png # 主题截图
├── search.php # 搜索结果页面
├── sidebar.php # 侧边栏模板
├── single.php # 单篇文章模板
├── style.css # 主题样式表
├── template-parts/ # 模板片段目录
│ ├── blocks/ # 区块模板
│ │ ├── block-banner.php # Banner区块模板
│ │ ├── block-futures.php # Futures区块模板
│ │ ├── block-home-news.php # 新闻区块模板
│ │ └── block-tabs.php # 选项卡区块模板
│ ├── content-none.php # 无内容模板
│ └── content-search.php # 搜索内容模板
├── theme-options.php # 主题选项页面
└── widgets/ # 小部件目录
└── widgets-config.php # 小部件配置
```
## 短代码功能
### Banner 轮播
```
[nenghui_banner]
[nenghui_banner id="custom-banner" class="my-banner" autoplay="true"]
```
### Futures 展示
```
[nenghui_futures]
[nenghui_futures title="我们的优势" show_animation="true"]
```
### 新闻模块
```
[nenghui_news]
[nenghui_news title="最新动态" category_id="1,2" posts_count="5"]
```
### 选项卡系统
```
[nenghui_tabs]
[nenghui_tabs id="custom-tabs" class="my-tabs"]
```
## 安装和使用
### 系统要求
- WordPress 5.0 或更高版本
- PHP 7.4 或更高版本
- MySQL 5.6 或更高版本
### 安装步骤
1. 下载主题文件
2. 上传到 WordPress 的 `/wp-content/themes/` 目录
3. 在 WordPress 后台激活主题
4. 进入「外观」→「自定义」配置主题设置
### 配置说明
1. **Banner 设置**:在自定义器中配置轮播图片和内容
2. **Futures 设置**:配置特性项目的图标、标题和描述
3. **新闻设置**:设置新闻模块的显示方式和数量
4. **选项卡设置**:配置选项卡的内容和样式
## 开发说明
### 模块化架构
主题采用模块化设计,各功能模块独立管理:
- `inc/init-config.php` - 系统初始化和性能配置
- `inc/theme-setup.php` - 主题基础功能设置
- `inc/admin-config.php` - 后台管理功能
- `inc/assets-loader.php` - 资源加载管理
- `inc/media-config.php` - 媒体文件处理
### 自定义开发
1. 新增功能模块请在 `inc/` 目录下创建对应文件
2. 在 `functions.php` 中引用新模块
3. 遵循 WordPress 编码标准
4. 添加适当的安全检查和数据验证
## 性能优化
- ✅ 图片自动压缩和 WebP 生成
- ✅ 内存使用监控和优化
- ✅ 临时文件自动清理
- ✅ 服务器资源智能管理
- ✅ 延迟加载和缓存优化
## 安全特性
- ✅ PHP 木马检测和清理
- ✅ 文件上传安全验证
- ✅ 恶意代码扫描
- ✅ 安全日志记录
- ✅ 输入数据过滤和验证
## SMTP连接故障排除
### 连接超时问题
如果遇到 "Connection timed out" 错误,请按以下步骤排查:
#### 1. 网络连通性检查
- 使用系统诊断工具检查服务器网络状态
- 确认服务器可以访问外部网络
- 检查DNS解析是否正常
#### 2. 防火墙设置
- 确认服务器防火墙允许SMTP端口25、465、587的出站连接
- 检查云服务商的安全组设置
- 联系主机提供商确认端口限制
#### 3. SMTP服务器配置
- 验证SMTP服务器地址和端口是否正确
- 确认加密方式设置SSL/TLS/STARTTLS
- 检查SMTP服务器是否正常运行
#### 4. 端口25被封禁问题
**⚠️ 重要提示大多数云服务商默认封禁端口25**
**问题现象:**
- 连接超时错误:"Connection timed out (110)"
- 所有连接方式都失败
- 诊断显示无法连接到端口25
**解决方案:**
- **立即更换端口**改用587TLS或465SSL
- **更新加密设置**:配合端口使用相应的加密方式
- **避免使用端口25**:即使在自建服务器上也建议避免
**云服务商政策:**
- **阿里云ECS**永久封禁25端口无法申请解封
- **腾讯云CVM**默认封禁25端口企业用户可申请解封
- **华为云ECS**默认封禁25端口
- **AWS EC2**需要申请解除25端口限制
#### 5. 其他常见解决方案
- **防火墙设置**确保安全组开放587/465端口
- **自建服务器**检查iptables或ufw防火墙规则
- **共享主机**联系主机商开启SMTP功能
- **网络问题**检查DNS解析和网络连通性
#### 6. 诊断工具使用
1. 进入WordPress后台 → 工具 → SMTP诊断
2. 点击"运行诊断"查看详细报告
3. 根据诊断结果进行相应调整
#### 7. 替代方案
如果无法解决连接问题,可以考虑:
- 使用第三方邮件服务如SendGrid、阿里云邮件推送
- 配置邮件中继服务
- 联系主机提供商获取技术支持
## 更新记录
### v1.5.0 (2025-12-11)
- 🔒 修复安全问题,提升系统安全性
- ✅ 更新版本号为 1.5.0
### v1.4.1 (2025-01-XX)
- ✅ 增强SMTP诊断功能添加DNS解析测试
- ✅ 新增网络连通性测试,检测服务器网络状态
- ✅ 改进端口连接测试,支持多种连接方式
- ✅ 优化诊断结果显示,提供详细的故障排除建议
- ✅ 增强连接超时处理和错误诊断
- ✅ 添加端口25被封禁的专门检测和警告
- ✅ 在管理界面增加端口25使用警告提示
- ✅ 完善云服务商端口限制说明文档
### v1.4.0 (2025-07-17)
- ✅ 创建项目评分报告文档完成WordPress最佳实践和性能评估
- ✅ 重构代码架构,实现模块化设计
- ✅ 优化性能配置和安全防护
- ✅ 完善文档和使用说明
- ✅ 修复已知问题和优化用户体验
### v1.0.0
- 🎉 初始版本发布
---
**更新时间:** 2025-12-11 14:31:14
**版权所有:** © 2025 上海能辉科技有限公司

@ -0,0 +1,18 @@
<?php
/**
* 案例归档页面模板
* 用于显示 cases 自定义文章类型的归档页面
*/
?>
<?php get_header();?>
<div class="page-full-width">
<div class="row">
<div class="col-md-12">
<?php echo do_shortcode('[nenghui_banner_title bg_image="https://nenghui.com/wp-content/uploads/2025/07/cases-bg.webp" title="CASES" description="Nenghui Energy Cases Successful solar & storage renewable project examples." overlay_opacity="0.5"]'); ?>
<?php echo do_shortcode('[nenghui_cases posts_per_page="6" default_category="power-station" columns="3" show_tabs="true" show_pagination="true"]'); ?>
</div>
</div>
</div>
<?php get_footer();?>

@ -0,0 +1,19 @@
<?php
/**
* FAQ归档页面模板
* 用于显示 FAQ 自定义文章类型的归档页面
*/
?>
<?php get_header();?>
<div class="page-full-width">
<div class="row">
<div class="col-md-12">
<?php echo do_shortcode('[nenghui_banner_title title="FAQ" bg_image="https://nenghui.com/wp-content/uploads/2025/07/SUPPORT.webp" description="Nenghui Energy FAQs Answers on renewable solutions services sustainability and support for solar wind storage" overlay_opacity="0.5"]'); ?>
<?php echo do_shortcode('[nenghui_about_nav menu_id="7"]'); ?>
<?php echo do_shortcode('[nenghui_faq title="FREQUENTLY ASKED QUESTIONS" show_animation]'); ?>
</div>
</div>
</div>
<?php get_footer();?>

@ -0,0 +1,29 @@
<?php
/**
* 新闻列表页
*/
?>
<?php get_header();?>
<div class="page-full-width">
<div class="row">
<div class="col-md-12">
<?php
// 获取分类图片作为banner背景
$banner_bg_image = 'https://nenghui.com/wp-content/uploads/2025/07/News-top-bg.webp'; // 默认背景图片
if (is_category()) {
$category = get_queried_object();
$category_image_url = get_category_image_url($category->term_id, 'full');
if ($category_image_url) {
$banner_bg_image = $category_image_url;
}
}
echo do_shortcode('[nenghui_banner_title bg_image="' . esc_url($banner_bg_image) . '" title="NEWS" description="Nenghui has been awarded excellent honors in the industry and is committed to providing prompt service for all of our current and potential customers." overlay_opacity="0.5"]');
?>
<?php echo do_shortcode('[nenghui_about_nav menu_id="4"]'); ?>
<?php echo do_shortcode('[nenghui_news_grid title="NEWS" posts_per_page="12" enable_pagination="true" order_by="date" order="DESC"]'); ?>
</div>
</div>
</div>
<?php get_footer();?>

File diff suppressed because one or more lines are too long

@ -0,0 +1,278 @@
.black-about-company-banner {
background-color: #fff;
color: #333;
padding: 60px 0;
overflow: hidden;
margin: 0 auto;
width: 90%;
}
.banner-content {
display: flex;
gap: 40px;
align-items: flex-start;
width: 100%;
}
.banner-left {
flex: 1;
max-width: 50%;
}
.main-image {
width: 100%;
height: auto !important;;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.main-image img {
width: 100%;
height: auto;
display: block;
transition: transform 0.3s ease;
}
.main-image:hover img {
transform: scale(1.02);
}
.banner-right {
flex: 1;
max-width: 50%;
display: flex;
flex-direction: column;
padding-left: 20px;
}
.content-text h2 {
font-size: 26px;
color: #007cba;
line-height: 1;
}
.content-text p {
font-size: 14px;
line-height: 1.6;
color: #000;
}
.mass-production h3 {
font-size: 1.1rem;
font-weight: bold;
color: #000;
}
.mass-production p {
font-size: 14px;
line-height: 1.6;
color: #000;
}
/* Swiper轮播容器样式 */
.production-carousel-container {
width: 100%;
border-radius: 6px;
background: #f8f9fa;
padding: 4px;
border: 1px solid #e9ecef;
position: relative;
}
.production-swiper {
width: 100%;
height: 88px;
overflow: hidden;
}
.production-swiper .swiper-wrapper {
align-items: center;
transition-timing-function: linear;
}
.production-swiper .swiper-slide {
display: flex;
align-items: center;
justify-content: center;
height: 80px;
width: auto !important;
flex-shrink: 0;
transition: transform 0.3s ease;
}
.production-swiper .swiper-slide img {
width: auto;
height: auto;
max-height: 80px;
max-width: 120px;
min-width: 80px;
object-fit: contain;
border-radius: 2px;
transition: transform 0.3s ease;
background: #fff;
margin: 0 8px;
}
.production-swiper .swiper-slide:hover img {
transform: scale(1.05);
}
/* Swiper导航按钮样式 */
.production-swiper .swiper-button-next,
.production-swiper .swiper-button-prev {
width: 24px;
height: 24px;
margin-top: -12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
color: #333;
transition: all 0.3s ease;
}
.production-swiper .swiper-button-next:hover,
.production-swiper .swiper-button-prev:hover {
background: #2196F3;
color: white;
transform: scale(1.1);
}
.production-swiper .swiper-button-next::after,
.production-swiper .swiper-button-prev::after {
font-size: 12px;
font-weight: 600;
}
.production-swiper .swiper-button-next {
right: -12px;
}
.production-swiper .swiper-button-prev {
left: -12px;
}
/* Swiper分页器样式 */
.production-swiper .swiper-pagination {
bottom: -20px;
position: relative;
margin-top: 8px;
}
.production-swiper .swiper-pagination-bullet {
width: 20px;
height: 3px;
background: #ddd;
opacity: 1;
transition: all 0.3s ease;
border-radius: 2px;
margin: 0 2px;
}
.production-swiper .swiper-pagination-bullet-active {
background: #2196F3;
transform: none;
}
/* 响应式设计 */
@media (min-width: 768px) {
.production-swiper {
height: 88px;
}
.production-swiper .swiper-slide {
height: 80px;
}
.production-swiper .swiper-slide img {
max-height: 80px;
}
.production-swiper .swiper-button-next,
.production-swiper .swiper-button-prev {
width: 28px;
height: 28px;
margin-top: -14px;
}
.production-swiper .swiper-button-next::after,
.production-swiper .swiper-button-prev::after {
font-size: 14px;
}
}
@media (max-width: 767px) {
.banner-content {
flex-direction: column;
text-align: center;
gap: 1rem;
}
.banner-left,
.banner-right {
max-width: 100%;
}
.banner-right {
padding-left: 0;
}
.content-text h2 {
font-size: 1.5rem;
}
.content-text p,
.mass-production p {
font-size: 0.9rem;
}
.production-swiper {
height: 68px;
}
.production-swiper .swiper-slide {
height: 60px;
}
.production-swiper .swiper-slide img {
max-height: 60px;
max-width: 100px;
min-width: 60px;
margin: 0 6px;
}
.production-swiper .swiper-button-next,
.production-swiper .swiper-button-prev {
width: 20px;
height: 20px;
margin-top: -10px;
}
.production-swiper .swiper-button-next::after,
.production-swiper .swiper-button-prev::after {
font-size: 10px;
}
.production-swiper .swiper-button-next {
right: -8px;
}
.production-swiper .swiper-button-prev {
left: -8px;
}
}
@media (max-width: 480px) {
.black-about-company-banner {
padding: 40px 0;
}
.content-text h2 {
font-size: 1.5rem;
}
.content-text p,
.mass-production p {
font-size: 0.85rem;
}
}

@ -0,0 +1,109 @@
/**
* Black Maps Block Styles
* WordPress
*/
.black-maps-wrapper {
background-size: 100% 100%;
background-color: #f5f5f5;
display: flex;
width: 100%;
height: 100vh;
align-items: center;
justify-content: center;
position: relative;
}
.black-maps-container {
width: 100%;
height: 100vh;
position: relative;
}
#echartsMap {
width: 100%;
height: 100vh;
}
/* 响应式设计 */
@media (max-width: 768px) {
.black-maps-wrapper,
.black-maps-container,
#echartsMap {
height: 60vh;
min-height: 400px;
}
}
@media (max-width: 480px) {
.black-maps-wrapper,
.black-maps-container,
#echartsMap {
height: 50vh;
min-height: 350px;
}
}
/* 加载状态样式 */
.black-maps-loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #666;
}
.black-maps-loading::after {
content: '';
width: 20px;
height: 20px;
margin-left: 10px;
border: 2px solid #f3f3f3;
border-top: 2px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 错误状态样式 */
.black-maps-error {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #e74c3c;
text-align: center;
padding: 20px;
}
/* 自定义器预览模式样式 */
.customize-preview .black-maps-wrapper {
transition: all 0.3s ease;
}
/* 地图标题样式覆盖 */
.black-maps-wrapper .echarts-title {
font-family: inherit;
font-weight: bold;
}
/* 地图工具提示样式 */
.black-maps-wrapper .echarts-tooltip {
background-color: rgba(0, 0, 0, 0.8);
border: none;
border-radius: 4px;
color: #fff;
font-size: 12px;
padding: 8px 12px;
}
/* 确保地图容器不会溢出 */
.black-maps-wrapper * {
box-sizing: border-box;
}

@ -0,0 +1,326 @@
/**
*
* Business Process Block Styles
*/
.business-process-block {
padding: 80px 0;
background: #f8f9fa;
position: relative;
overflow: hidden;
}
.business-process-block .container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 头部样式 */
.process-header {
text-align: left;
margin-bottom: 60px;
}
.process-title {
font-size: 2.5rem;
font-weight: 700;
color: #2c3e50;
margin-bottom: 16px;
line-height: 1.2;
}
.process-subtitle {
font-size: 1.125rem;
color: #6c757d;
margin: 0;
line-height: 1.6;
}
/* 主要内容区域 */
.process-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 60px;
align-items: center;
}
/* 左侧Tab标签区域 */
.process-tabs {
display: flex;
flex-direction: column;
border-radius: 8px;
}
.process-tab {
display: flex;
align-items: center;
padding: 24px 0;
background: transparent;
cursor: pointer;
transition: all 0.3s ease;
border-bottom: 1px solid #e9ecef;
position: relative;
}
.process-tab:hover {
background: rgba(0, 149, 123, 0.02);
}
.process-tab.active {
background: rgba(0, 149, 123, 0.05);
border-left: 4px solid #00957b;
padding-left: 16px;
}
.tab-number {
font-size: 2.5rem;
font-weight: 700;
color: #00957b;
margin-right: 24px;
min-width: 70px;
text-align: left;
transition: color 0.3s ease;
line-height: 1;
}
.process-tab.active .tab-number {
color: #00957b;
}
.process-tab:last-child {
border-bottom: none;
}
.tab-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.tab-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
color: #2c3e50;
transition: color 0.3s ease;
}
.process-tab.active .tab-title {
color: #00957b;
}
.tab-description {
font-size: 0.9rem;
color: #6c757d;
margin: 0;
line-height: 1.6;
transition: color 0.3s ease;
}
.process-tab.active .tab-description {
color: #6c757d;
}
.tab-arrow {
margin-left: 20px;
color: #00957b;
transition: all 0.3s ease;
opacity: 0.7;
font-size: 1.1rem;
transform: translateX(-14px);
}
.process-tab.active .tab-arrow {
color: #00957b;
opacity: 1;
transform: translateX(-14px);
}
/* 右侧图片显示区域 */
.process-images {
position: relative;
height: 500px;
}
.process-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.5s ease;
display: flex;
align-items: center;
justify-content: center;
}
.process-image.active {
opacity: 1;
}
.process-image img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
object-position: center;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.business-process-block {
padding: 60px 0;
}
.process-content {
gap: 40px;
}
.process-images {
height: 400px;
}
}
@media (max-width: 768px) {
.business-process-block {
padding: 40px 0;
}
.business-process-block .container {
padding: 0 16px;
}
.process-header {
margin-bottom: 40px;
text-align: left;
}
.process-title {
font-size: 2rem;
}
.process-subtitle {
font-size: 1rem;
}
.process-content {
grid-template-columns: 1fr;
gap: 30px;
}
.process-tabs {
gap: 16px;
}
.process-tab {
padding: 20px;
}
.tab-number {
font-size: 1.5rem;
margin-right: 16px;
min-width: 50px;
}
.tab-title {
font-size: 1.125rem;
}
.tab-description {
font-size: 0.8125rem;
}
.process-images {
height: 300px;
}
}
@media (max-width: 480px) {
.process-tab {
padding: 16px;
flex-direction: column;
text-align: center;
}
.tab-number {
margin-right: 0;
margin-bottom: 12px;
}
.tab-arrow {
margin-left: 0;
margin-top: 12px;
transform: rotate(90deg);
}
.process-tab.active .tab-arrow {
transform: rotate(90deg) translateX(4px);
}
.process-images {
height: 250px;
}
}
/* 动画效果 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.business-process-block.animate-in .process-header,
.business-process-block.animate-in .process-tab,
.business-process-block.animate-in .process-images {
animation: fadeInUp 0.6s ease forwards;
}
.business-process-block.animate-in .process-tab:nth-child(1) {
animation-delay: 0.1s;
}
.business-process-block.animate-in .process-tab:nth-child(2) {
animation-delay: 0.2s;
}
.business-process-block.animate-in .process-tab:nth-child(3) {
animation-delay: 0.3s;
}
.business-process-block.animate-in .process-tab:nth-child(4) {
animation-delay: 0.4s;
}
.business-process-block.animate-in .process-images {
animation-delay: 0.5s;
}
/* 打印样式 */
@media print {
.business-process-block {
background: #ffffff;
padding: 20px 0;
}
.process-content {
grid-template-columns: 1fr;
gap: 20px;
}
.process-tab {
box-shadow: none;
border: 1px solid #ddd;
}
.process-images {
height: 300px;
box-shadow: none;
}
}

@ -0,0 +1,67 @@
/* 组件EPC 解决方案横幅 — 外层布局容器 */
.epc-hero {
max-width: 1200px;
margin: 32px auto;
padding: 0 16px;
}
/* 组件:横幅主体(负责背景图、圆角与投影) */
.epc-banner {
position: relative;
height: 260px;
border-radius: var(--radius);
overflow: hidden;
/* 背景图片:与项目同级,使用相对路径,便于兼容 */
background: url("../images/epc-bg.jpg") center/cover no-repeat;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
}
/* 组件:可读性增强的渐变遮罩层 */
.epc-overlay {
position: absolute;
inset: 0;
background: linear-gradient(
180deg,
rgba(0, 0, 0, 0.20) 0%,
rgba(0, 0, 0, 0.50) 100%
);
/* 轻微饱和度与亮度调整提升层次感 */
backdrop-filter: saturate(1.05) brightness(0.95);
}
/* 组件:内容承载层(标题与副标题居中显示) */
.epc-content {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 0 24px;
color: #ffffff;
}
/* 组件:主标题样式 */
.epc-title {
margin: 0 0 10px 0;
font-size: var(--title-size);
font-weight: 700;
color: #ffffff;
letter-spacing: 0.6px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
/* 组件:副标题样式 */
.epc-subtitle {
margin: 0;
font-size: var(--subtitle-size);
opacity: 0.96;
}
/* 响应式:在较窄屏幕降低高度以保持比例 */
@media (max-width: 640px) {
.epc-banner {
height: 220px;
}
}

@ -0,0 +1,60 @@
/* feature-module 模块 */
.feature-module {
width: 100%;
max-width: 1300px;
margin: 40px auto;
overflow: hidden;
background-color: #fff;
}
.feature-inner {
display: flex;
align-items: stretch;
gap: 15px;
padding: 15px; /* 让外框与内容留出安全距离 */
}
/* 左侧文字区域 */
.feature-text {
flex: 0 0 50%;
padding: 20px;
}
.feature-text h2 {
color: #116598;
font-size: 28px;
font-weight: 400;
margin: 0 0 16px;
}
.feature-text p {
color: #808080;
font-size: 16px;
line-height: 1.5;
margin: 0;
}
.feature-divider {
width: 32px;
height: 3px;
background-color: #116598;
border-radius: 2px;
margin: 12px 0 16px 0;
}
/* 右侧图片区域(背景图) */
.feature-media {
flex: 0 0 40%;
border-radius: 15px;
background: url('../images/tgrdfrfed.jpg');
background-size: cover; /* 保持比例,填充容器 */
background-position: center;
background-repeat: no-repeat;
min-height: 280px; /* 保证在文本较少时也有可视高度 */
}
/* 响应式:小屏幕上下布局 */
@media (max-width: 768px) {
.feature-inner { flex-direction: column; }
.feature-text { flex: 1 1 auto; padding: 16px; }
.feature-media { flex: 1 1 auto; min-height: 220px; }
}

@ -0,0 +1,227 @@
.article-content h1 {
font-size: 25px;
transition: all 0.3s ease;
}
.article-content h2 {
font-size: 30px;
color: #0073aa;
font-weight: bold;
border-bottom: 2px solid #0073aa;
transition: all 0.3s ease;
}
.article-content h3 {
font-size: 26px;
color: #333;
font-weight: normal;
transition: all 0.3s ease;
}
.article-content h4 {
font-size: 22px;
color: #555;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
transition: all 0.3s ease;
}
.article-content h5 {
font-size: 18px;
color: #666;
font-weight: bold;
margin-top: 15px;
margin-bottom: 8px;
}
.article-content h6 {
font-size: 16px;
color: #777;
font-weight: bold;
margin-top: 10px;
margin-bottom: 5px;
}
/* 段落样式 */
.article-content p {
font-size: 14px;
line-height: 1.8;
color: #000000;
margin-bottom: 16px;
word-wrap: break-word;
overflow-wrap: break-word;
white-space: normal;
}
/* 链接样式 */
.article-content a {
color: #0073aa;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: all 0.3s ease;
}
.article-content a:hover {
color: #0056b3;
text-decoration: underline;
transition: all 0.3s ease;
}
/* 列表样式 */
.article-content ul,
.article-content ol {
margin: 16px 0;
padding-left: 30px;
}
.article-content ul li,
.article-content ol li {
font-size: 16px;
line-height: 1.6;
color: #333;
margin-bottom: 8px;
}
.article-content ul li {
list-style-type: disc;
}
.article-content ol li {
list-style-type: decimal;
}
/* 引用样式 */
.article-content blockquote {
background: #f9f9f9;
border-left: 4px solid #0073aa;
margin: 20px 0;
padding: 15px 20px;
font-style: italic;
color: #555;
}
.article-content blockquote p {
margin-bottom: 0;
}
/* 代码样式 */
.article-content code {
background: #f4f4f4;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 14px;
color: #d63384;
}
.article-content pre {
background: #f8f8f8;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
margin: 20px 0;
}
.article-content pre code {
background: none;
padding: 0;
color: #333;
}
/* 图片样式 */
.article-content img {
max-width: 100%;
height: auto;
border-radius: 5px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin: 20px 0;
display: block;
}
/* 表格样式 */
.article-content table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
background: #fff;
}
.article-content table th,
.article-content table td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
.article-content table th {
background: #f5f5f5;
font-weight: bold;
color: #333;
}
.article-content table tr:nth-child(even) {
background: #f9f9f9;
}
/* 分隔线样式 */
.article-content hr {
border: none;
height: 2px;
background: linear-gradient(to right, #0073aa, #2eb6aa);
margin: 30px 0;
border-radius: 1px;
}
/* 强调文本样式 */
.article-content strong,
.article-content b {
font-weight: bold;
color: #333;
transition: all 0.3s ease;
}
.article-content em,
.article-content i {
font-style: italic;
color: #555;
}
/* 文章容器整体样式 */
.article-content {
margin: 20px auto;
padding: 30px;
font-family: 'Arial', 'Microsoft YaHei', sans-serif;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
word-wrap: break-word;
overflow-wrap: break-word;
}
/* 响应式设计 */
@media (max-width: 768px) {
.article-content {
padding: 15px;
}
.article-content h1 {
font-size: 28px;
}
.article-content h2 {
font-size: 24px;
}
.article-content h3 {
font-size: 20px;
}
.article-content h4 {
font-size: 18px;
}
.article-content p {
font-size: 14px;
}
}

@ -0,0 +1,740 @@
/**
*
* Product Content Page Styles
*/
/* 产品特性样式 */
.product-features {
padding: 60px 0;
max-width: 1200px;
margin: 0 auto;
}
h2.product-title {
align-content: center;
padding: 0 20px;
}
.product-description{
color: #666;
line-height: 1.5;
padding: 10px 20px;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
padding: 0 20px;
max-width: 1200px;
margin: 0 auto;
}
.feature-card {
background: #ffffff;
border: 1px solid #e5e5e5;
border-radius: 8px;
padding: 40px 30px;
text-align: center;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.feature-card:hover {
border-radius: 0;
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.feature-card::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 5px;
background: linear-gradient(90deg, #009294 0%, #116698 100%);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.feature-card:hover::after {
transform: scaleX(1);
transition: all 0.3s ease;
}
.feature-icon {
margin-bottom: 25px;
display: flex;
justify-content: center;
align-items: center;
}
.feature-icon img {
width: 60px;
height: 60px;
object-fit: contain;
}
.feature-title {
font-size: 16px;
font-weight: 700;
color: #333333;
line-height: 1.3;
letter-spacing: 0.5px;
margin-bottom: 15px;
text-transform: uppercase;
}
.feature-description {
font-size: 14px;
color: #666666;
line-height: 1.5;
margin: 0;
}
/* 响应式设计 */
@media (max-width: 992px) {
.features-grid {
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 25px;
}
.feature-card {
padding: 35px 25px;
}
.feature-icon img {
width: 50px;
height: 50px;
}
}
@media (max-width: 768px) {
.features-grid {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
padding: 0 15px;
}
.feature-card {
padding: 30px 20px;
}
.feature-icon img {
width: 45px;
height: 45px;
}
.feature-title {
font-size: 15px;
}
.feature-description {
font-size: 13px;
}
}
@media (max-width: 576px) {
.features-grid {
grid-template-columns: 1fr;
}
.product-features {
padding: 40px 0;
}
.feature-card {
padding: 25px 15px;
}
.feature-icon {
margin-bottom: 20px;
}
.feature-icon img {
width: 40px;
height: 40px;
}
.feature-title {
font-size: 14px;
margin-bottom: 12px;
}
.feature-description {
font-size: 12px;
}
}
/* 使用场景板块样式 */
.usage-scenario-section {
padding: 20px 0;
background: #f8f9fa;
}
.usage-scenario-content {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.scenario-header {
text-align: left;
margin-bottom: 50px;
}
.scenario-title {
font-size: 36px;
font-weight: 700;
background: linear-gradient(to bottom, #30b7aa, #027da4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: 2px;
margin-bottom: 20px;
text-transform: uppercase;
}
.scenario-description {
font-size: 18px;
color: #666666;
line-height: 1.6;
margin: 0;
max-width: 600px;
}
.scenario-image {
text-align: center;
margin: 50px 0;
display: flex;
justify-content: center;
}
.scenario-image img {
max-width: 100%;
height: auto;
border-radius: 8px;
display: block;
}
.scenario-footer {
text-align: left;
margin-top: 50px;
display: flex;
justify-content: center;
}
.scenario-text {
font-size: 16px;
color: #555555;
line-height: 1.8;
margin: 0;
text-align: left;
}
/* 响应式设计 */
@media (max-width: 992px) {
.usage-scenario-section {
padding: 60px 0;
}
.scenario-title {
font-size: 30px;
}
.scenario-description {
font-size: 16px;
}
.scenario-text {
font-size: 15px;
}
}
@media (max-width: 768px) {
.usage-scenario-section {
padding: 50px 0;
margin-top: 40px;
}
.usage-scenario-content {
padding: 0 15px;
}
.scenario-header {
margin-bottom: 40px;
}
.scenario-title {
font-size: 26px;
letter-spacing: 1px;
}
.scenario-description {
font-size: 15px;
}
.scenario-image {
margin: 40px 0;
}
.scenario-footer {
margin-top: 40px;
}
.scenario-text {
font-size: 14px;
line-height: 1.7;
}
}
@media (max-width: 576px) {
.usage-scenario-section {
padding: 40px 0;
}
.scenario-title {
font-size: 22px;
margin-bottom: 15px;
}
.scenario-description {
font-size: 14px;
}
.scenario-image {
margin: 30px 0;
}
.scenario-text {
font-size: 13px;
line-height: 1.6;
}
}
/* 技术规格板块样式 */
.technical-specs-section {
padding: 20px 0;
background: #ffffff;
}
.technical-specs-content {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.specs-header {
text-align: left;
margin-bottom: 50px;
}
.specs-title {
font-size: 36px;
font-weight: 700;
background: linear-gradient(to bottom, #30b7aa, #027da4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: 2px;
margin-bottom: 20px;
text-transform: uppercase;
}
.specs-accordion {
width: 100%;
}
.accordion-item {
margin-bottom: 20px;
background: #ffffff;
border: 1px solid #e5e5e5;
border-radius: 8px;
overflow: hidden;
transition: box-shadow 0.3s ease;
}
.accordion-item:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.accordion-trigger {
width: 100%;
padding: 20px 24px;
background: none;
border: none;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
text-align: left;
transition: background-color 0.3s ease;
}
.accordion-trigger:hover {
background-color: #f8f9fa;
}
.accordion-trigger:focus {
outline: 2px solid #30b7aa;
outline-offset: -2px;
}
.accordion-title {
font-size: 18px;
font-weight: 600;
margin: 0;
color: #333333;
text-transform: uppercase;
letter-spacing: 1px;
flex: 1;
}
.accordion-icon {
width: 20px;
height: 20px;
position: relative;
flex-shrink: 0;
margin-left: 16px;
transition: transform 0.3s ease;
}
.accordion-icon::before,
.accordion-icon::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
background: #30b7aa;
transition: transform 0.3s ease;
}
.accordion-icon::before {
width: 12px;
height: 2px;
transform: translate(-50%, -50%);
}
.accordion-icon::after {
width: 2px;
height: 12px;
transform: translate(-50%, -50%);
}
.accordion-item.is-expanded .accordion-icon::after {
transform: translate(-50%, -50%) rotate(90deg);
}
.accordion-panel {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: #ffffff;
will-change: max-height;
}
.accordion-panel[hidden] {
display: none;
}
.accordion-content {
padding: 24px;
color: #555555;
line-height: 1.6;
border-top: 1px solid #f0f0f0;
}
/* 响应式设计 */
@media (max-width: 992px) {
.specs-title {
font-size: 30px;
}
.accordion-trigger {
padding: 18px 20px;
}
.accordion-title {
font-size: 16px;
}
.accordion-content {
padding: 20px;
}
}
@media (max-width: 768px) {
.technical-specs-content {
padding: 0 15px;
}
.specs-header {
margin-bottom: 40px;
}
.specs-title {
font-size: 26px;
letter-spacing: 1px;
}
.accordion-trigger {
padding: 16px 18px;
}
.accordion-title {
font-size: 15px;
}
.accordion-icon {
width: 18px;
height: 18px;
margin-left: 12px;
}
.accordion-icon::before {
width: 10px;
}
.accordion-icon::after {
height: 10px;
}
.accordion-content {
padding: 18px;
}
}
@media (max-width: 576px) {
.specs-title {
font-size: 22px;
margin-bottom: 15px;
}
.accordion-item {
margin-bottom: 16px;
}
.accordion-trigger {
padding: 14px 16px;
}
.accordion-title {
font-size: 14px;
letter-spacing: 0.5px;
}
.accordion-icon {
width: 16px;
height: 16px;
margin-left: 10px;
}
.accordion-icon::before {
width: 8px;
}
.accordion-icon::after {
height: 8px;
}
.accordion-content {
padding: 16px;
}
}
/* PDF下载板块样式 */
.pdf-downloads-section {
padding: 60px 0;
max-width: 1200px;
margin: 0 auto;
}
.pdf-downloads-content {
padding: 0 20px;
max-width: 1200px;
margin: 0;
}
.downloads-header {
text-align: left;
margin-bottom: 50px;
}
.downloads-title {
font-size: 32px;
font-weight: 700;
color: #333333;
letter-spacing: 2px;
margin: 0;
position: relative;
display: inline-block;
}
.downloads-title::after {
content: '';
position: absolute;
bottom: -10px;
left: 0;
width: 60px;
height: 3px;
background: linear-gradient(90deg, #009294 0%, #116698 100%);
}
.downloads-grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
margin: 0;
}
.download-item {
background: #ffffff;
border: 1px solid #e5e5e5;
border-radius: 8px;
padding: 25px;
display: flex;
align-items: center;
gap: 20px;
transition: all 0.3s ease;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.download-item:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
border-color: #009294;
transition: all 0.3s ease;
}
.download-icon {
flex-shrink: 0;
}
.pdf-icon {
width: 48px;
height: 48px;
object-fit: contain;
}
.download-info {
flex: 1;
min-width: 0;
}
.download-title {
font-size: 18px;
font-weight: 600;
color: #333333;
margin: 0 0 8px 0;
line-height: 1.3;
}
.download-description {
font-size: 14px;
color: #666666;
margin: 0 0 8px 0;
line-height: 1.4;
}
.download-size {
font-size: 12px;
color: #999999;
font-weight: 500;
}
.download-action {
flex-shrink: 0;
}
.download-button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
background: linear-gradient(135deg, #009294 0%, #116698 100%);
border-radius: 50%;
text-decoration: none;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 146, 148, 0.3);
}
.download-button:hover {
transform: scale(1.1);
box-shadow: 0 6px 20px rgba(0, 146, 148, 0.4);
text-decoration: none;
transition: all 0.3s ease;
}
.download-btn-icon {
width: 20px;
height: 20px;
filter: brightness(0) invert(1);
}
/* 响应式设计 */
@media (max-width: 768px) {
.pdf-downloads-section {
padding: 40px 0;
}
.pdf-downloads-content {
padding: 0 15px;
}
.downloads-title {
font-size: 24px;
}
.download-item {
padding: 20px;
gap: 15px;
}
.download-title {
font-size: 16px;
}
.download-description {
font-size: 13px;
}
.pdf-icon {
width: 40px;
height: 40px;
}
.download-button {
width: 40px;
height: 40px;
}
.download-btn-icon {
width: 16px;
height: 16px;
}
}
@media (max-width: 480px) {
.download-item {
flex-direction: column;
text-align: center;
gap: 15px;
}
.download-info {
order: 1;
}
.download-icon {
order: 2;
}
.download-action {
order: 3;
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

@ -0,0 +1,13 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 201 201" width="201" height="201">
<title>新建项目</title>
<defs>
<linearGradient id="g1" x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(142.033,214.499,-189.605,125.549,147.68,-79.185)">
<stop offset=".162" stop-color="#2cb5a9"/>
<stop offset="1" stop-color="#00699f"/>
</linearGradient>
</defs>
<style>
.s0 { fill: url(#g1) }
</style>
<path id="&lt;Compound Path&gt;" fill-rule="evenodd" class="s0" d="m178.7 36.7c1.1 1 1.6 2.4 1.6 3.7v50h20v84.9h-20v25h-135c-13.8 0-25-11.2-25-25h-20v-84.9h20v-90h95c2.8 0 5 2.2 5 5 0 2.8-2.2 5-5 5h-85v80h140v-40h-40v-45c0-2.8 2.2-5.1 5-5.1 1.1 0 1.8 0.2 2.6 0.6 0.6 0.3 1.3 0.7 2 1.2q1.8 1.3 4.9 3.9c3.5 3 8.2 7.1 13.9 12.3 0.4 0.4 0.4 0.4 0.9 0.8 4.3 3.9 8.8 8 13.2 12.1q2.4 2.2 4.3 4 1.2 1.1 1.6 1.5zm-148.4 138.6c0 8.3 6.7 15 15 15h125v-15h-140zm110-160v25.1h27.7q-1-0.9-2-1.9c-4.4-4.1-8.9-8.2-13.1-12-0.5-0.4-0.5-0.4-1-0.9-4.5-4.1-8.5-7.6-11.6-10.3zm-87.6 123.8q9.9 0 15.4-4.6 5.5-4.7 5.5-13 0-8.2-5.6-13.2-5.6-4.9-15.2-4.9h-21.7v56.9h9.9v-21.2zm-11.8-27.7h12.2q4.9 0 7.7 2.8 2.8 2.7 2.8 7.4 0 4.6-2.8 7.1-2.7 2.5-8 2.5h-11.9zm57.6 48.9q7.7 0 13.7-3.3 5.9-3.3 9.2-9.5 3.2-6.1 3.2-14.2v-2.8q0-8-3.2-14.2-3.2-6.2-9.1-9.5-5.8-3.4-13.3-3.4h-16.8v56.9zm0.4-48.9q7.6 0 11.7 4.9 4 4.9 4 14.1v3.2q-0.1 9.1-4.2 14-4.2 4.8-12 4.8h-6.4v-41zm68.2 16.9h-22.9v-16.9h26.3v-8h-36.2v56.9h9.9v-24.1h22.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

@ -0,0 +1,6 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73 59" width="73" height="59">
<style>
.s0 { fill: #2dada2}
</style>
<path fill-rule="evenodd" class="s0" d="m48.5 5.1c1.2 0.2 3.8 0.6 5.6 0.8 1.9 0.3 4.8 1.4 6.6 2.6 1.7 1.1 3.7 3.3 4.5 4.8 0.8 1.5 1.4 4.6 1.4 7 0 2.7-0.6 5.4-1.8 7.7-1 2-3.4 5.2-5.4 7.1-2 1.9-6.4 4.8-16 9.6l1.1 6.7-3.6 1.1c-2 0.6-3.7 1-3.8 0.8-0.1-0.1-0.1-10.3 0.2-44.8l2.4 14.3c1.2 7.9 2.5 15.3 3.1 18.9l4.3-2.3c2.4-1.3 5.6-3.5 7.1-5 1.6-1.5 3.6-4.3 4.6-6.1 0.9-1.9 1.6-5.1 1.6-7.2 0-2.1-0.6-5.2-1.4-6.9-0.8-1.7-2.8-4-4.4-5-1.7-1.1-4.4-2.3-6.1-2.6-1.7-0.4-2.9-0.9-2.7-1.3 0.2-0.3 1.4-0.4 2.7-0.2zm-14.6 2.5l0.2 23.2c0.1 12.7 0.1 23.2 0 23.4-0.1 0.1-1.9 0.1-7.8-0.3zm-22.3 12.2c0.5 0 1 0.4 1.3 0.9 0.2 0.4 0 1-0.5 1.2-0.4 0.3-1.2 0.3-1.6 0-0.5-0.2-0.7-0.8-0.4-1.2 0.2-0.5 0.8-0.9 1.2-0.9zm10.3 3.6c0.6 0.8 1.8 1.4 2.7 1.5 1.6 0 1.6 0.1 0.2 1.1-0.8 0.5-1.2 1.6-1 2.5 0.2 0.8 0.1 1.4-0.2 1.4-0.4 0.1-1.1-0.4-1.6-1-0.8-0.9-1.1-0.9-1.5 0-0.3 0.6-0.9 1-1.3 1-0.5 0-0.6-0.5-0.2-1.3 0.4-0.8 0-1.7-1.1-2.4-1.6-1.2-1.6-1.3 0.6-1.3 1.7 0 2.4-0.5 2.4-1.5 0-1.4 0.1-1.4 1 0zm-15.3 8.4c0.5 0.1 0.9 0.6 1 1 0.1 0.4-0.3 0.9-0.8 1.1-0.6 0.1-1.1-0.4-1-1.1 0.1-0.7 0.4-1.2 0.8-1zm10.7 9.3c0.1 0.8 0.8 1.5 1.6 1.5 1.1 0 1.2 0.2 0.5 1-0.5 0.6-0.7 1.6-0.4 2.3 0.4 1.1 0.2 1.1-0.9 0.2-1.2-0.8-1.7-0.8-2.8 0-1.1 0.9-1.2 0.9-0.6-0.5 0.5-1 0.3-1.7-0.6-2.3-1-0.6-1-0.7 0.2-0.7 0.8 0 1.8-0.7 2.1-1.5 0.6-1.4 0.6-1.4 0.9 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,6 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73 59" width="73" height="59">
<style>
.s0 { fill: #2dada2 }
</style>
<path fill-rule="evenodd" class="s0" d="m37.3 4.2c1.7 0.2 4.1 1.1 5.3 1.9 1.2 0.8 3 2.7 3.9 4.2 1 1.5 1.8 4.4 1.8 6.4 0 2.3-0.8 4.9-4.7 10.3l2.9 2.3c1.6 1.2 3.1 2.2 3.3 2.2 0.3 0 1.8 1.7 3.3 3.8 1.4 2 3.2 6.2 3.8 9.2 0.6 3.1 0.9 6.6-0.1 10l-42.5-0.5-0.3-4c-0.1-2.2 0.3-6 1-8.5 0.8-2.8 2.8-6 5.5-8.7 2.4-2.3 5-4.3 5.8-4.3 0.9 0 1.5-0.2 1.5-0.5 0-0.2-1.1-2.1-2.5-4.2-1.4-2.1-2.5-5-2.5-6.5 0-1.5 0.8-4.4 1.8-6.4 1-1.9 2.6-4.1 3.7-4.8 1.1-0.7 2.9-1.5 4-1.8 1.1-0.3 3.4-0.4 5-0.1zm-4.2 3c-1.2 0.3-3.4 1.8-4.7 3.4-1.4 1.6-2.6 4.1-2.6 5.4 0 1.4 0.5 3.6 1.1 4.8 0.5 1.2 2.4 3.1 4.2 4.1 2.3 1.3 4.2 1.7 6.5 1.3 1.9-0.4 4.1-1.8 5.3-3.4 1.1-1.5 2-4.2 2-6 0-1.8-0.5-4.2-1.1-5.3-0.5-1.1-2.5-2.6-4.5-3.5-1.9-0.8-3.6-1.4-3.7-1.3-0.1 0.1-1.3 0.3-2.5 0.5zm-13 1.4c0.4 0 0.9 0.3 1.2 0.7 0.2 0.4-1.1 2-3 3.5-2.6 2-3.5 3.5-3.5 5.7 0 1.9 1 4 2.5 5.5 1.4 1.4 2.5 3 2.5 3.5 0 0.6-1.2 1.4-2.6 1.8-1.5 0.4-4 2.2-5.5 4-1.6 1.8-3.1 4.3-3.3 5.5-0.3 1.2-0.6 3.6-0.8 5.2-0.1 1.7-0.7 2.9-1.3 2.8-0.5-0.1-1.1-1.7-1.3-3.5-0.1-1.8 0.4-5.2 1.3-7.5 0.9-2.4 2.9-5.3 4.8-6.7 3-2.2 3.1-2.6 2-5-0.7-1.4-1.2-4-1.2-5.8 0-1.8 0.8-4.2 1.7-5.4 1-1.1 2.6-2.6 3.7-3.2 1.1-0.6 2.4-1.1 2.8-1.1zm31.9-0.1c0.5 0 2.2 1.2 3.8 2.5 1.8 1.5 3.3 3.9 3.7 5.8 0.3 2 0 4.4-1 6.2-1.4 3-1.4 3.1 2.4 7.3 2.3 2.5 4.4 6 5 8.5 0.6 2.3 0.9 5.1 0.8 6.2-0.2 1-0.8 2-1.4 2.2-0.5 0.2-1.3-1.8-1.7-4.4-0.4-2.6-1.7-6.2-2.8-8-1.1-1.8-3.8-4.2-10-7.3l2.5-2.5c1.4-1.3 2.8-3.7 3.1-5.2 0.4-1.7 0-3.6-1-5-0.8-1.2-2.5-2.5-3.6-2.8-1.1-0.2-2-0.8-2.1-1.3-0.1-0.4 0.2-1.1 0.6-1.5 0.5-0.4 1.3-0.7 1.7-0.7zm-23.7 22.4c-1.6 0.8-4.6 3.2-6.7 5.5-2.9 3.2-3.9 5.3-4.3 8.9-0.3 2.6-0.5 4.8-0.3 4.9 0.2 0 8.6 0.4 18.6 0.7l18.2 0.6c0-6.2-0.4-9.2-1-10.7-0.6-1.5-2.1-3.8-3.3-5.1-1.2-1.3-4-3.2-6.2-4.3-2.2-1-5.8-1.8-8-1.8-2.2 0-5.3 0.6-7 1.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,6 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73 59" width="73" height="59">
<style>
.s0 { fill: #2dada2 }
</style>
<path fill-rule="evenodd" class="s0" d="m48.3 3c2.6 0 3.2 0.4 3.4 2 0.2 1.5 1.2 2.2 4.5 3.1 3.6 1 4.2 1.5 4.2 3.4 0 1.2-0.5 2.8-1.2 3.6-0.8 0.7-1.8 1.3-2.3 1.3-0.5 0-1.1-0.5-1.3-1.1-0.1-0.6-0.6-0.9-0.9-0.7-0.4 0.3-0.4 1.3-0.2 2.3 0.4 1.2 1.9 2.1 5.2 3 2.6 0.6 5.5 1.3 6.3 1.5 1.3 0.3 1.5 1.2 1.4 4.2-0.2 3.2-0.6 3.8-2.3 4-1.1 0.1-2 0.8-2 1.6 0 0.7-0.4 1.3-0.9 1.3-0.5 0-0.9-0.6-0.9-1.3 0-0.8-0.8-1.4-1.8-1.4-0.9 0-1.8 0.3-1.8 0.7 0 0.4 0.6 3.3 1.3 6.5 0.7 3.2 1.7 7.6 2.3 9.8 0.6 2.3 1.2 4.8 1.4 5.6 0.3 1-0.1 1.6-0.9 1.6-0.8 0-1.6-0.8-1.8-1.8-0.4-1.7-1.2-1.8-12.1-1.8-10.9 0-11.7 0.1-12.1 1.8-0.2 1-0.9 1.8-1.5 1.8-0.9 0-0.5-2.9 1.3-11 1.3-6 2.4-11.4 2.4-12 0-0.7-0.7-1.2-1.7-1.2-1 0-1.8 0.6-1.8 1.4 0 0.7-0.4 1.3-0.9 1.3-0.5 0-0.9-0.6-0.9-1.3 0-0.8-0.9-1.5-2-1.6-1.7-0.2-2.1-0.8-2.3-4-0.2-3.7-0.1-3.8 3.2-4.7 1.8-0.5 4.8-1.2 6.7-1.6 2.7-0.5 3.4-1 3.4-2.7-0.1-1.1-0.5-2-1-2-0.4 0-0.8 0.4-0.8 0.9 0 0.5-0.5 0.9-0.9 0.9-0.5 0-1.5-0.6-2.3-1.3-0.7-0.8-1.3-2.4-1.3-3.6 0-1.9 0.6-2.4 4.1-3.4 2.9-0.7 4.4-1.7 4.9-3.1 0.6-1.6 1.5-2 3.9-2zm-1.7 2.4c-0.4 0.3-0.7 0.9-0.6 1.3 0 0.4 0.9 0.8 1.9 0.8 1 0 1.7-0.5 1.5-1.1-0.2-0.7-0.7-1.3-1.2-1.4-0.5-0.1-1.2 0-1.6 0.4zm-1.4 5.7c0 1.4 0.6 1.7 3.2 1.7 2.6 0 3-0.2 2.6-1.7-0.3-1.3-1.2-1.8-3.1-1.8-2.1 0-2.7 0.4-2.7 1.8zm-7.1-0.3c-0.7 0.2-1.2 0.8-1.1 1.2 0.1 0.5 1.4 0.8 2.9 0.8 1.5 0 2.8-0.5 3.1-1.3 0.3-0.9-0.2-1.3-1.6-1.3-1.1 0.1-2.6 0.3-3.3 0.6zm15.2 0.7q0 1.3 2.7 1.3c1.4 0 2.6-0.4 2.6-0.9 0-0.4-0.6-1-1.3-1.3-0.7-0.2-1.9-0.4-2.7-0.4-0.7 0-1.3 0.6-1.3 1.3zm-28.6-0.4c1.6 0 1.7 0.7 1.7 7.1 0 5.8-0.2 7.2-1.3 7.2-0.7 0-2.2 0.8-3.1 1.8-1.2 1.1-1.8 2.9-1.8 4.9 0 1.9 0.6 3.8 1.8 4.9 0.9 1 2.4 1.8 3.1 1.8 1.1 0 1.3 1.4 1.3 7.1 0 6.6-0.1 7.2-1.8 7.2-1.3 0-1.7-0.6-1.7-2.2 0-1.3-0.7-2.9-1.4-3.6-1.2-1.2-1.6-1.2-6.3 2.2l-2.8-2.9c-2.9-2.9-2.9-2.9-1.2-5.1 1.2-1.6 1.4-2.7 0.8-3.8-0.4-0.9-1.9-1.7-3.2-1.8-2.3-0.2-2.5-0.6-2.7-4-0.2-3.8-0.2-3.9 2.9-4.3 1.7-0.2 3.3-0.9 3.4-1.6 0.2-0.6-0.4-2.2-3-6l5.4-5.4 2.5 1.7c1.3 0.9 2.9 1.5 3.5 1.3 0.7-0.1 1.4-1.7 1.7-3.4 0.4-2.3 1-3.1 2.2-3.1zm21.4 4.4c0 0.5 0.5 1.2 1.1 1.5 0.6 0.3 1.7-0.1 2.5-0.9 1.1-1.3 1-1.5-1.2-1.5-1.3 0-2.4 0.4-2.4 0.9zm-3 3.6c-0.3 1.2-0.5 2.8-0.6 3.6 0 1 0.5 0.8 2-0.7 1.9-1.9 2-2.1 0.6-3.6-1.4-1.4-1.5-1.4-2 0.7zm7.5-0.5c-1.2 1.3-1.1 1.7 0.6 3.5 1.1 1 2.2 1.7 2.4 1.5 0.2-0.3-0.1-1.8-0.7-3.5-0.9-2.7-1.1-2.8-2.3-1.5zm-15.6 3.6c-2.3 0.8-3.5 1.7-3.8 3-0.3 1.8 0 1.9 3.9 1.7 4-0.2 4.3-0.3 4.7-3.1 0.3-1.6 0.1-2.8-0.4-2.8-0.5 0-2.5 0.6-4.4 1.2zm20.8 0.6c0.1 0.9 0.4 2.3 0.6 3 0.3 0.9 1.7 1.4 4.5 1.4 3.6 0 4-0.2 3.8-2-0.2-1.5-1.2-2.2-4.6-3-4.1-1-4.4-1-4.3 0.6zm-9.9 0.6c-0.7 0.8-1.6 2-1.9 2.6-0.4 0.9 0.7 1.2 4.6 1.2h5.1c-4.1-4.2-5.6-5.4-5.9-5.4-0.3 0-1.1 0.7-1.9 1.6zm2 12.3l5.8-5.9h-11.6zm-9.3 2.9c-0.8 3.9-1.4 7.1-1.2 7.2 0.1 0.1 2.2-1.8 4.7-4.3l4.4-4.4c-4.1-4.2-5.6-5.4-5.9-5.4-0.3 0-1.2 3.1-2 6.9zm13.3-4.2l-2.7 2.7c7 6.9 9.1 8.8 9.2 8.7 0.1-0.1-0.3-3.3-1.1-7.2-0.7-3.8-1.6-6.9-2-6.9-0.5 0-2 1.2-3.4 2.7zm-9.4 9.4l-4.9 4.9h20.6c-7.6-7.6-10.1-9.9-10.3-9.8-0.3 0-2.7 2.2-5.4 4.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,6 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73 59" width="73" height="59">
<style>
.s0 { fill: #2dada2 }
</style>
<path fill-rule="evenodd" class="s0" d="m36.7 5c0.7 0 1.5 0.7 1.8 1.5 0.3 0.8 0.5 2.3 0.5 3.3 0 0.9-0.5 2.2-1.2 2.9-0.7 0.6-1.9 1-2.6 0.7-0.6-0.2-1.3-1.9-1.4-3.7-0.1-1.9 0.2-3.7 0.7-4 0.5-0.4 1.4-0.7 2.2-0.7zm-17.8 8c1.2 0 2.8 1 3.6 2.3 1.1 1.7 1.2 2.5 0.2 3.5-1 1-1.6 1-3.2-0.1-1.1-0.8-2.1-2.4-2.3-3.6-0.3-1.6 0.2-2.1 1.7-2.1zm35.2 0c1.1 0 1.9 0.7 1.9 1.5 0 0.8-0.9 2.4-2 3.5-1.1 1.1-2.5 2-3 2-0.6 0-1.3-0.7-1.8-1.5-0.4-0.9 0-2.3 1.2-3.5 1-1.1 2.7-2 3.7-2zm-18.1 3.1c0.3-0.1 2.7 0.7 5.5 1.6 3.9 1.4 5.5 2.7 7.7 6.3 1.6 2.5 2.8 5.7 2.8 7.3 0 2-0.5 2.7-2 2.7q-2 0-2-2c0-1.1-0.6-3.2-1.4-4.7-0.7-1.6-2.5-3.6-4-4.5-1.4-1-4.4-1.8-6.7-1.8-3.4 0-4.7 0.6-7.5 3.5-2 2.1-3.4 4.5-3.4 6 0 1.4-0.7 2.8-1.5 3.3-0.9 0.4-2 0.2-2.6-0.3-0.7-0.7-0.6-2.4 0.3-5.3 0.7-2.4 2.6-5.6 4.3-7.2 1.6-1.6 4.6-3.3 6.5-3.8 1.9-0.6 3.7-1.1 4-1.1zm-22.5 13.9c1.9 0 3.7 0.6 3.9 1.3 0.3 0.6 0 1.8-0.7 2.5-0.6 0.6-2 1.2-3.1 1.2-1.2 0-2.8-0.4-3.6-0.9-0.9-0.6-1.2-1.5-0.8-2.5 0.5-1 2-1.6 4.3-1.6zm46 0c3 0 3.5 0.3 3.2 2.3-0.1 1.5-0.9 2.3-2.7 2.5-1.4 0.1-3.2-0.2-4-0.7-0.9-0.6-1.2-1.5-0.8-2.5 0.5-1 2-1.6 4.3-1.6zm-39.5 6h5.5c3 0 5.5 0.5 5.5 1 0 0.5-1.7 4.4-7.5 16h-5.8c-3.1 0-5.7-0.2-5.7-0.5 0-0.3 1.8-4.1 4-8.5zm19.1 0c3.7 0 4.9 0.3 4.9 1.5 0 0.8-1.6 4.6-7 15.5h-12l3.6-7.3c2-4 4-7.8 4.6-8.5 0.5-0.7 3.2-1.2 5.9-1.2zm12.9 0c2.7 0 5.2 0.4 5.5 1 0.2 0.5-1.2 4.3-7 16h-5.8c-3.2 0-5.7-0.4-5.7-0.8 0-0.4 1.2-3.2 2.8-6.2 1.5-3 3.3-6.5 4-7.8 1-1.8 2.1-2.2 6.2-2.2z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2V16M12 16L8 12M12 16L16 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 18V19C4 19.5304 4.21071 20.0391 4.58579 20.4142C4.96086 20.7893 5.46957 21 6 21H18C18.5304 21 19.0391 20.7893 19.4142 20.4142C19.7893 20.0391 20 19.5304 20 19V18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 283.46 105.79"><defs><style>.cls-1{fill:#0069a0;}.cls-2{fill:#2eb6aa;}</style></defs><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M40.6,46.54,49.6,0H40.19L33.48,34.68,21.7,0H9L0,46.54H9.48l6.6-34.12L28.47,46.54ZM89.14,8.3,90.74,0H74.07a28.55,28.55,0,0,0-8,.92A19.07,19.07,0,0,0,60,4.12Q51.25,10.89,48.89,23q-2.12,11,2,17.38,2.82,4.47,8.9,5.51a57.22,57.22,0,0,0,9.09.63H81.74l1.61-8.31H70.93q-7.19,0-9.74-2.33c-1.7-1.56-2.34-4.34-1.95-8.34H85.41L87,19.26H60.85a33.33,33.33,0,0,1,1.59-4.75,10.8,10.8,0,0,1,2-2.79A9.75,9.75,0,0,1,68.77,9a29.44,29.44,0,0,1,7.45-.7Zm36.94,38.24,9-46.54h-9.41L119,34.68,107.18,0H94.49l-9,46.54H95l6.61-34.12L114,46.54ZM179.74,8.3l1.6-8.3H161a31.18,31.18,0,0,0-12,2,20.24,20.24,0,0,0-8.29,6.41,34.94,34.94,0,0,0-6.39,15Q131.72,37.26,138,42.91a12,12,0,0,0,5.2,2.82,34.12,34.12,0,0,0,8.4.81h20.79l5.35-27.63H154.87l-1.61,8.3h13l-2.13,11h-9a19.16,19.16,0,0,1-5.62-.69,5.78,5.78,0,0,1-3.22-2.23,9.7,9.7,0,0,1-1.43-5.09,30.76,30.76,0,0,1,.61-7.68Q147.06,14.25,151,11q3.32-2.73,9.53-2.73Zm11.32,10.33L194.66.05h-9.44l-9,46.34h9.44L189,29.27h-8.1Zm25.6,27.76,9-46.34h-9.44L212.8,17.53h6.62l-8.3,8.69-3.91,20.17Zm47.9-19.17L269.76,0h-9.83l-5.29,27.69c-.64,3.33-1.4,5.63-2.29,6.93a9.07,9.07,0,0,1-4,3.08,15.14,15.14,0,0,1-6,1.14c-3.46,0-6-1-7.55-2.84a6,6,0,0,1-1.27-3.15,18.87,18.87,0,0,1,.43-5.16L239.23,0h-9.76l-5.34,27.91a28.82,28.82,0,0,0-.66,8.47A10.31,10.31,0,0,0,226,41.83q4,4.71,14.73,4.71,10,0,16.43-4.78a16.71,16.71,0,0,0,4.57-5.65,33,33,0,0,0,2.85-8.89M283.46,0h-9.9l-8.9,46.54h9.9Z"/><path class="cls-2" d="M191,42.93c.91-1.93,7.59-15.73,7.59-15.73h-12.5L210,3.91l-7.62,15.68H215Z"/><path class="cls-2" d="M41,67.55l1.61-8.3H25.91a28.68,28.68,0,0,0-8,.92,19.07,19.07,0,0,0-6.09,3.2Q3.08,70.13.73,82.27q-2.13,11,1.94,17.38,2.83,4.47,8.91,5.51a57.08,57.08,0,0,0,9.08.63H33.58l1.6-8.31H22.76q-7.19,0-9.74-2.34t-1.94-8.33H37.25l1.6-8.3H12.69a35,35,0,0,1,1.58-4.75,10.85,10.85,0,0,1,2-2.79,9.75,9.75,0,0,1,4.37-2.72,29.38,29.38,0,0,1,7.45-.7Zm37,38.24,9-46.54H77.58L70.87,93.93,59.08,59.25H46.39l-9,46.54h9.48l6.6-34.12,12.39,34.12Zm48.64-38.24,1.6-8.3H111.55a28.55,28.55,0,0,0-8,.92,19.07,19.07,0,0,0-6.09,3.2q-8.79,6.76-11.13,18.9-2.12,11,1.95,17.38,2.82,4.47,8.9,5.51a57.13,57.13,0,0,0,9.09.63h12.91l1.61-8.31H108.4q-7.17,0-9.73-2.34t-2-8.33h26.17l1.61-8.3H98.33a33.33,33.33,0,0,1,1.59-4.75,10.8,10.8,0,0,1,2-2.79,9.75,9.75,0,0,1,4.37-2.72,29.44,29.44,0,0,1,7.45-.7Zm33.63,5.87A7.56,7.56,0,0,1,157,78.78a9.79,9.79,0,0,1-5.16,1.06H137.94l2.38-12.29H154.2A11.58,11.58,0,0,1,158,68c2.08.78,2.85,2.6,2.3,5.44m11.12-1.19a11.91,11.91,0,0,0-.27-6,8.52,8.52,0,0,0-3.22-4.43q-3.36-2.52-13.13-2.52H132l-9,46.54h9.9l3.41-17.65h7.95c3.46,0,6,.42,7.62,1.4A6.06,6.06,0,0,1,154.48,93a16.07,16.07,0,0,1,.23,6.19c-.28,3.36-.89,6.64-.89,6.64h11.1s.53-3.7.89-7.05a27.12,27.12,0,0,0,.29-4.54,13.16,13.16,0,0,0-.59-3.2,7.47,7.47,0,0,0-1.91-3.17,12.2,12.2,0,0,0-3.72-2.07A16.75,16.75,0,0,0,166,82.49a17.87,17.87,0,0,0,5.34-10.26m47.14-4.68,1.6-8.3h-20.3a31.27,31.27,0,0,0-12,2,20.28,20.28,0,0,0-8.28,6.41,34.94,34.94,0,0,0-6.39,15q-2.68,13.81,3.56,19.46a12,12,0,0,0,5.2,2.82,34.06,34.06,0,0,0,8.4.81h20.79l5.34-27.63H193.64L192,86.46h13l-2.13,11h-9a19.24,19.24,0,0,1-5.63-.69A5.82,5.82,0,0,1,185,94.56a9.77,9.77,0,0,1-1.42-5.09,30.76,30.76,0,0,1,.61-7.68q1.6-8.3,5.58-11.51,3.31-2.73,9.53-2.73Zm50.67-8.3H257.39L242.64,77.46l-7.15-18.21H223.9l12.18,26.17-3.94,20.37H242l3.88-20Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

@ -0,0 +1,347 @@
/**
* 业务流程设计区块交互脚本
* Business Process Block Interactive Script
*/
(function($) {
'use strict';
/**
* 业务流程Tab切换类
*/
class BusinessProcessTabs {
constructor(container) {
this.container = $(container);
this.tabs = this.container.find('.process-tab');
this.images = this.container.find('.process-image');
this.currentIndex = 0;
this.isAnimating = false;
this.init();
}
/**
* 初始化
*/
init() {
this.bindEvents();
this.setupIntersectionObserver();
this.preloadImages();
// 设置初始状态
this.setActiveTab(0, false);
}
/**
* 绑定事件
*/
bindEvents() {
// Tab点击事件
this.tabs.on('click', (e) => {
e.preventDefault();
const index = this.tabs.index($(e.currentTarget));
this.switchTab(index);
});
// 键盘导航支持
this.tabs.on('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
const index = this.tabs.index($(e.currentTarget));
this.switchTab(index);
}
});
// 触摸滑动支持(移动端)
if ('ontouchstart' in window) {
this.setupTouchEvents();
}
// 窗口大小改变时重新计算
$(window).on('resize', this.debounce(() => {
this.handleResize();
}, 250));
}
/**
* 设置触摸事件移动端滑动支持
*/
setupTouchEvents() {
let startX = 0;
let startY = 0;
let isScrolling = false;
this.container.on('touchstart', (e) => {
const touch = e.originalEvent.touches[0];
startX = touch.clientX;
startY = touch.clientY;
isScrolling = false;
});
this.container.on('touchmove', (e) => {
if (isScrolling) return;
const touch = e.originalEvent.touches[0];
const deltaX = touch.clientX - startX;
const deltaY = touch.clientY - startY;
// 判断是否为水平滑动
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 30) {
isScrolling = true;
e.preventDefault();
if (deltaX > 0 && this.currentIndex > 0) {
// 向右滑动切换到上一个tab
this.switchTab(this.currentIndex - 1);
} else if (deltaX < 0 && this.currentIndex < this.tabs.length - 1) {
// 向左滑动切换到下一个tab
this.switchTab(this.currentIndex + 1);
}
}
});
}
/**
* 切换Tab
*/
switchTab(index) {
if (index === this.currentIndex || this.isAnimating || index < 0 || index >= this.tabs.length) {
return;
}
this.setActiveTab(index, true);
}
/**
* 设置活动Tab
*/
setActiveTab(index, animate = true) {
if (this.isAnimating && animate) return;
this.isAnimating = animate;
this.currentIndex = index;
// 更新Tab状态
this.tabs.removeClass('active').eq(index).addClass('active');
// 更新图片显示
if (animate) {
this.animateImageTransition(index);
} else {
this.images.removeClass('active').eq(index).addClass('active');
this.isAnimating = false;
}
// 更新ARIA属性
this.updateAccessibility(index);
// 触发自定义事件
this.container.trigger('tabChanged', [index, this.tabs.eq(index)]);
}
/**
* 图片切换动画
*/
animateImageTransition(index) {
const currentImage = this.images.filter('.active');
const nextImage = this.images.eq(index);
// 如果没有当前活动图片,直接显示新图片
if (currentImage.length === 0) {
nextImage.addClass('active');
this.isAnimating = false;
return;
}
// 淡出当前图片
currentImage.animate({ opacity: 0 }, 250, () => {
currentImage.removeClass('active');
// 淡入新图片
nextImage.addClass('active').css('opacity', 0).animate({ opacity: 1 }, 250, () => {
this.isAnimating = false;
});
});
}
/**
* 更新无障碍访问属性
*/
updateAccessibility(index) {
this.tabs.each((i, tab) => {
const $tab = $(tab);
$tab.attr('aria-selected', i === index ? 'true' : 'false');
$tab.attr('tabindex', i === index ? '0' : '-1');
});
this.images.each((i, image) => {
const $image = $(image);
$image.attr('aria-hidden', i === index ? 'false' : 'true');
});
}
/**
* 预加载图片
*/
preloadImages() {
this.images.each((index, element) => {
const $img = $(element).find('img');
if ($img.length && $img.attr('data-src')) {
const img = new Image();
img.onload = () => {
$img.attr('src', $img.attr('data-src')).removeAttr('data-src');
};
img.src = $img.attr('data-src');
}
});
}
/**
* 设置交叉观察器用于动画触发
*/
setupIntersectionObserver() {
if (!window.IntersectionObserver) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.container.addClass('animate-in');
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.2,
rootMargin: '0px 0px -50px 0px'
});
observer.observe(this.container[0]);
}
/**
* 处理窗口大小改变
*/
handleResize() {
// 重新计算布局相关的尺寸
this.container.removeClass('animate-in');
// 延迟重新添加动画类
setTimeout(() => {
this.container.addClass('animate-in');
}, 100);
}
/**
* 防抖函数
*/
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
/**
* 自动播放功能
*/
startAutoPlay(interval = 5000) {
this.stopAutoPlay();
this.autoPlayTimer = setInterval(() => {
const nextIndex = (this.currentIndex + 1) % this.tabs.length;
this.switchTab(nextIndex);
}, interval);
}
/**
* 停止自动播放
*/
stopAutoPlay() {
if (this.autoPlayTimer) {
clearInterval(this.autoPlayTimer);
this.autoPlayTimer = null;
}
}
/**
* 销毁实例
*/
destroy() {
this.stopAutoPlay();
this.tabs.off('click keydown');
this.container.off('touchstart touchmove');
$(window).off('resize');
this.container.removeClass('animate-in');
}
}
/**
* 初始化所有业务流程区块
*/
function initBusinessProcessBlocks() {
$('.business-process-block').each(function() {
const $block = $(this);
// 避免重复初始化
if ($block.data('business-process-initialized')) {
return;
}
const instance = new BusinessProcessTabs(this);
$block.data('business-process-instance', instance);
$block.data('business-process-initialized', true);
// 如果设置了自动播放,启动自动播放
const autoPlay = $block.data('auto-play');
const autoPlayInterval = $block.data('auto-play-interval') || 5000;
if (autoPlay) {
instance.startAutoPlay(autoPlayInterval);
// 鼠标悬停时暂停自动播放
$block.on('mouseenter', () => instance.stopAutoPlay());
$block.on('mouseleave', () => instance.startAutoPlay(autoPlayInterval));
}
});
}
/**
* 页面加载完成后初始化
*/
$(document).ready(function() {
initBusinessProcessBlocks();
});
/**
* 支持动态加载的内容
*/
$(document).on('DOMNodeInserted', function(e) {
const $target = $(e.target);
if ($target.hasClass('business-process-block') || $target.find('.business-process-block').length) {
setTimeout(initBusinessProcessBlocks, 100);
}
});
/**
* 自定义器预览支持
*/
if (typeof wp !== 'undefined' && wp.customize) {
wp.customize.bind('ready', function() {
// 当自定义器设置改变时重新初始化
wp.customize.bind('change', function() {
setTimeout(initBusinessProcessBlocks, 500);
});
});
}
/**
* 导出到全局作用域用于外部调用
*/
window.BusinessProcessTabs = BusinessProcessTabs;
window.initBusinessProcessBlocks = initBusinessProcessBlocks;
})(jQuery);

@ -0,0 +1,84 @@
/**
* 自定义器控制脚本
* 用于增强自定义器界面的用户体验
*/
// 立即定义全局测试函数,确保在控制台中可用
window.testGalleryControls = function() {
if (typeof $ !== 'undefined') {
var galleryWrappers = $('.gallery-control-wrapper');
var selectButtons = $('.gallery-select-button');
var clearButtons = $('.gallery-clear-button');
return {
wrappers: galleryWrappers.length,
selectButtons: selectButtons.length,
clearButtons: clearButtons.length,
mediaAvailable: typeof wp !== 'undefined' && typeof wp.media !== 'undefined',
customizeAvailable: typeof wp !== 'undefined' && typeof wp.customize !== 'undefined'
};
} else {
return { error: 'jQuery not available' };
}
};
window.triggerGallerySelect = function() {
if (typeof $ === 'undefined') {
return false;
}
var selectButton = $('.gallery-select-button').first();
if (selectButton.length > 0) {
selectButton.trigger('click');
return true;
} else {
return false;
}
};
(function($) {
'use strict';
// 当自定义器准备就绪时执行
wp.customize.bind('ready', function() {
// 确保媒体库已加载
if (typeof wp.media === 'undefined') {
// Error handling silently
}
// 强制初始化媒体库
if (typeof wp.media !== 'undefined') {
wp.media.view.settings.post.id = 0;
}
// 添加Banner面板的帮助信息
var bannerPanel = wp.customize.panel('nenghui_banner_panel');
// if (bannerPanel) {
// bannerPanel.container.find('.accordion-section-title').after(
// '<p class="description customize-panel-description">' +
// '配置完成后,您可以在任何文章或页面中使用短代码 <code>[nenghui_banner]</code> 来显示Banner轮播。' +
// '</p>'
// );
// }
// 添加Banner Title面板的帮助信息
var bannerTitlePanel = wp.customize.panel('nenghui_banner_title_panel');
// if (bannerTitlePanel) {
// bannerTitlePanel.container.find('.accordion-section-title').after(
// '<p class="description customize-panel-description">' +
// '配置完成后,您可以在任何文章或页面中使用短代码 <code>[nenghui_banner_title]</code> 来显示Banner标题区块。' +
// '</p>'
// );
// }
// 添加Futures面板的帮助信息
var futuresPanel = wp.customize.panel('nenghui_futures_panel');
// if (futuresPanel) {
// futuresPanel.container.find('.accordion-section-title').after(
// '<p class="description customize-panel-description">' +
// '配置完成后,您可以在任何文章或页面中使用短代码 <code>[nenghui_futures]</code> 来显示Futures区块。' +
// '</p>'
// );
// }
});
})(jQuery);

File diff suppressed because one or more lines are too long

@ -0,0 +1,257 @@
// 这是自定义JS文件用于覆盖主题默认JS文件
document.addEventListener('DOMContentLoaded', function() {
// 菜单切换
const menuToggle = document.querySelector('.menu-toggle');
const navMenu = document.querySelector('.nav-menu');
if (menuToggle && navMenu) {
menuToggle.addEventListener('click', function() {
navMenu.classList.toggle('active');
// 切换菜单按钮动画
const spans = this.getElementsByTagName('span');
this.classList.toggle('active');
if (this.classList.contains('active')) {
spans[0].style.transform = 'rotate(45deg) translate(5px, 5px)';
spans[1].style.opacity = '0';
spans[2].style.transform = 'rotate(-45deg) translate(7px, -7px)';
} else {
spans[0].style.transform = 'none';
spans[1].style.opacity = '1';
spans[2].style.transform = 'none';
}
});
}
// 移动端下拉菜单点击切换
function initMobileDropdown() {
const menuItems = document.querySelectorAll('.menu-item-has-children');
// 简单的节流函数
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
// 处理菜单切换逻辑
const toggleMenu = function(e, item) {
// 只在移动端处理
if (window.innerWidth > 768) return;
e.preventDefault();
e.stopPropagation();
// 如果正在动画中则忽略点击可选依赖CSS过渡时间
// 这里使用简单的类切换由CSS控制动画
const isOpening = !item.classList.contains('mobile-open');
// 关闭同级其他菜单项
const siblings = item.parentNode.children;
for (let sibling of siblings) {
if (sibling !== item && sibling.classList.contains('menu-item-has-children')) {
sibling.classList.remove('mobile-open');
}
}
// 切换当前菜单状态
item.classList.toggle('mobile-open');
};
// 创建节流版本的切换函数300ms内只响应一次
const throttledToggle = throttle(toggleMenu, 300);
menuItems.forEach(function(item) {
const link = item.querySelector('a');
const arrow = item.querySelector('.dropdown-arrow');
if (link) {
// 如果有箭头,优先使用箭头触发
if (arrow) {
arrow.addEventListener('click', function(e) {
throttledToggle(e, item);
});
// 同时也为箭头添加触摸事件监听,提高响应速度
arrow.addEventListener('touchend', function(e) {
// 防止触发 click
e.preventDefault();
throttledToggle(e, item);
});
}
// 链接点击处理
link.addEventListener('click', function(e) {
const href = link.getAttribute('href');
// 如果是在移动端,且链接是空或者#,或者没有箭头(只能点链接),则触发菜单切换
if (window.innerWidth <= 768) {
if (!href || href === '#' || href === 'javascript:void(0);') {
throttledToggle(e, item);
}
}
});
}
});
}
// 初始化移动端下拉菜单
initMobileDropdown();
// 窗口大小改变时重新初始化
window.addEventListener('resize', function() {
// 如果切换到桌面端,关闭所有移动端展开的菜单
if (window.innerWidth > 768) {
const openItems = document.querySelectorAll('.menu-item-has-children.mobile-open');
openItems.forEach(function(item) {
item.classList.remove('mobile-open');
});
}
});
// 滚动时改变导航栏样式
let lastScroll = 0;
const nav = document.querySelector('.main-nav');
window.addEventListener('scroll', function() {
const currentScroll = window.pageYOffset;
// 到顶部时显示导航栏并清除背景和阴影
if (currentScroll <= 0) {
nav.classList.remove('scrolled');
nav.style.transform = 'translateY(0)';
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
// 设置主菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
} else if (currentScroll > 80) {
// 滚动超过80px时添加背景和阴影
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 1)';
// 设置主菜单项颜色为黑色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
if (currentScroll > lastScroll) {
// 向下滚动时显示导航栏
nav.style.transform = 'translateY(0)';
} else {
// 向上滚动时隐藏导航栏
nav.style.transform = 'translateY(-100%)';
}
} else {
// 滚动在0-80px之间时清除背景和阴影
nav.classList.remove('scrolled');
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
nav.style.transform = 'translateY(0)';
// 设置主菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
}
lastScroll = currentScroll;
});
// 鼠标移入移出导航栏效果
nav.addEventListener('mouseenter', function() {
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
// 设置菜单项颜色为黑色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
});
nav.addEventListener('mouseleave', function() {
const currentScroll = window.pageYOffset;
// 根据当前滚动位置决定是否保持背景色
if (currentScroll <= 80) {
nav.classList.remove('scrolled');
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
// 设置菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
}
});
// 为有子菜单的项目添加特殊处理
const menuItemsWithChildren = nav.querySelectorAll('.menu-item-has-children');
menuItemsWithChildren.forEach(function(item) {
item.addEventListener('mouseenter', function() {
// 确保导航栏有背景色以便下拉菜单显示
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
});
});
// 窗口大小改变时重置菜单状态
window.addEventListener('resize', function() {
if (window.innerWidth > 768) {
// 桌面端时隐藏所有移动端展开的子菜单
document.querySelectorAll('.sub-menu').forEach(menu => {
menu.style.display = '';
});
}
});
});
// Banner轮播现在使用原生JavaScript实现无需Swiper初始化
// 轮播逻辑已集成在block-banner.php模板中

File diff suppressed because one or more lines are too long

@ -0,0 +1,208 @@
/**
* 产品详情页JavaScript功能
*/
// 确保底部文字宽度与图片宽度一致
function adjustScenarioTextWidth() {
const scenarioImages = document.querySelectorAll('.scenario-image img');
const scenarioTexts = document.querySelectorAll('.scenario-text');
scenarioImages.forEach((img, index) => {
if (scenarioTexts[index]) {
const updateWidth = () => {
const imgWidth = img.offsetWidth;
scenarioTexts[index].style.width = imgWidth + 'px';
};
// 图片加载完成后调整宽度
// if (img.complete) {
// updateWidth();
// } else {
// img.addEventListener('load', updateWidth);
// }
// 窗口大小改变时重新调整
window.addEventListener('resize', updateWidth);
}
});
}
/**
* 技术规格手风琴组件
*/
class TechnicalSpecsAccordion {
constructor(container) {
this.container = container;
this.triggers = container.querySelectorAll('.accordion-trigger');
this.init();
}
init() {
this.bindEvents();
this.setInitialStates();
}
bindEvents() {
this.triggers.forEach(trigger => {
trigger.addEventListener('click', (e) => this.handleToggle(e));
trigger.addEventListener('keydown', (e) => this.handleKeydown(e));
});
}
handleToggle(event) {
const trigger = event.currentTarget;
const item = trigger.closest('.accordion-item');
const panel = item.querySelector('.accordion-panel');
const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
this.togglePanel(trigger, panel, !isExpanded);
}
handleKeydown(event) {
const { key } = event;
const trigger = event.currentTarget;
// 支持键盘导航
if (key === 'Enter' || key === ' ') {
event.preventDefault();
this.handleToggle(event);
} else if (key === 'ArrowDown' || key === 'ArrowUp') {
event.preventDefault();
this.focusNextTrigger(trigger, key === 'ArrowDown');
}
}
togglePanel(trigger, panel, expand) {
const item = trigger.closest('.accordion-item');
// 更新ARIA属性
trigger.setAttribute('aria-expanded', expand.toString());
if (expand) {
// 展开面板
item.classList.add('is-expanded');
panel.removeAttribute('hidden');
panel.style.maxHeight = 'none'; // 先重置maxHeight
// 设置动画高度
requestAnimationFrame(() => {
const height = panel.scrollHeight;
panel.style.maxHeight = '0';
requestAnimationFrame(() => {
panel.style.maxHeight = height + 'px';
});
});
} else {
// 收起面板
const currentHeight = panel.scrollHeight;
panel.style.maxHeight = currentHeight + 'px';
// 强制重绘后设置为0
requestAnimationFrame(() => {
panel.style.maxHeight = '0';
item.classList.remove('is-expanded');
});
// 动画完成后隐藏
setTimeout(() => {
if (!item.classList.contains('is-expanded')) {
panel.setAttribute('hidden', '');
panel.style.maxHeight = ''; // 清除内联样式
}
}, 300);
}
}
focusNextTrigger(currentTrigger, forward = true) {
const triggers = Array.from(this.triggers);
const currentIndex = triggers.indexOf(currentTrigger);
let nextIndex;
if (forward) {
nextIndex = currentIndex === triggers.length - 1 ? 0 : currentIndex + 1;
} else {
nextIndex = currentIndex === 0 ? triggers.length - 1 : currentIndex - 1;
}
triggers[nextIndex].focus();
}
setInitialStates() {
this.triggers.forEach(trigger => {
const item = trigger.closest('.accordion-item');
const panel = item.querySelector('.accordion-panel');
const isExpanded = item.classList.contains('is-expanded');
// 设置初始ARIA属性
trigger.setAttribute('aria-expanded', isExpanded.toString());
// 设置初始显示状态
if (isExpanded) {
panel.removeAttribute('hidden');
// 确保展开的面板有正确的高度
requestAnimationFrame(() => {
panel.style.maxHeight = panel.scrollHeight + 'px';
});
} else {
panel.setAttribute('hidden', '');
panel.style.maxHeight = '0';
}
});
// 添加调试信息
console.log('Technical Specs Accordion initialized with', this.triggers.length, 'triggers');
}
}
// 防止重复初始化的标志
let accordionInitialized = false;
let scenarioWidthInitialized = false;
// 初始化技术规格手风琴
function initTechnicalSpecsAccordion() {
if (accordionInitialized) {
return;
}
const accordionContainer = document.querySelector('.specs-accordion');
if (accordionContainer) {
// 检查是否已经初始化过
if (!accordionContainer.hasAttribute('data-accordion-initialized')) {
new TechnicalSpecsAccordion(accordionContainer);
accordionContainer.setAttribute('data-accordion-initialized', 'true');
accordionInitialized = true;
}
}
}
// 初始化场景文字宽度调整
function initScenarioTextWidth() {
if (scenarioWidthInitialized) {
return;
}
adjustScenarioTextWidth();
scenarioWidthInitialized = true;
}
// 主初始化函数
function initProductsContent() {
initScenarioTextWidth();
initTechnicalSpecsAccordion();
}
// DOM加载完成后执行
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initProductsContent);
} else {
// DOM已经加载完成
initProductsContent();
}
// 如果是WordPress环境也在jQuery ready时执行作为备用
if (typeof jQuery !== 'undefined') {
jQuery(document).ready(function() {
// 延迟执行以避免与其他脚本冲突
setTimeout(initProductsContent, 100);
});
}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
(function webpackUniversalModuleDefinition(root,factory){if(typeof exports==='object'&&typeof module==='object')module.exports=factory();else if(typeof define==='function'&&define.amd)define("tinytyper",[],factory);else if(typeof exports==='object')exports["tinytyper"]=factory();else root["tinytyper"]=factory()})(this,function(){return(function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.loaded=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0)})([function(module,exports,__webpack_require__){'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _tinytyper=__webpack_require__(1);var _tinytyper2=_interopRequireDefault(_tinytyper);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}exports.default=_tinytyper2.default;module.exports=exports['default']},function(module,exports,__webpack_require__){'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();var _blinker=__webpack_require__(2);var _blinker2=_interopRequireDefault(_blinker);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var TinyTyper=function(){function TinyTyper(el){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};_classCallCheck(this,TinyTyper);this.element=el;this.cursor=document.createElement('span');this.textEl=document.createElement('span');this.options=options;this.text=options.text||el.innerText;this.textEl.className=options.textClass||'tiny-typer-text';this.cursor.className=options.cursorClass||'tiny-typer-cursor';this.cursor.innerHTML=options.cursor||' &#9612;';this.init()}_createClass(TinyTyper,[{key:'init',value:function init(){this.element.innerHTML='';this.element.innerText='';this.element.appendChild(this.textEl);this.element.appendChild(this.cursor);if(!this.options.staticCursor)this.blinker=(0,_blinker2.default)(this.cursor,this.options.blinkSpeed||0.05);if(!this.options.staticText){this.animate()}else{this.redraw(this.text)}}},{key:'animate',value:function animate(){var _this=this;var symbols=this.text.split('');var result=[];var animation=function animation(){return setTimeout(tick,_this.options.textSpeed||95)};var tick=function tick(){result.push(symbols.shift());_this.redraw(result.join(''));if(symbols.length)animation()};animation()}},{key:'redraw',value:function redraw(text){this.textEl.innerText=text}}]);return TinyTyper}();exports.default=TinyTyper;module.exports=exports['default']},function(module,exports){'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.fadeOut=fadeOut;exports.fadeIn=fadeIn;var requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60)};window.requestAnimationFrame=requestAnimationFrame;function fadeOut(el,speed,callback){el.style.opacity=1;var fade=function fade(){if((el.style.opacity-=speed)<0){el.style.opacity=0;callback()}else{requestAnimationFrame(fade)}};fade()}function fadeIn(el,speed,callback){el.style.opacity=0;var fade=function fade(){var val=parseFloat(el.style.opacity);if(!((val+=speed)>1)){el.style.opacity=val;requestAnimationFrame(fade)}else{el.style.opacity=1;callback()}};fade()}var blink=function blink(el,speed){var isStopped=false;el.style.opacity=1;var tick=function tick(){if(!isStopped){fadeIn(el,speed,function(){fadeOut(el,speed,function(){return tick()})})}};var start=function start(){isStopped=false;tick()};var stop=function stop(){return isStopped=true};tick();return{stop:stop,start:start}};exports.default=blink}])});

File diff suppressed because one or more lines are too long

@ -0,0 +1,115 @@
<footer class="main-footer">
<div class="footer-container">
<!-- 主要内容区域 -->
<div class="footer-main">
<!-- Logo 和公司信息 -->
<div class="footer-brand">
<div class="footer-logo">
<img src="https://nenghui.com/wp-content/uploads/2025/11/logo-2.png" alt="<?php bloginfo('name'); ?>" style=" height: 32px;" class="logo-img">
</div>
<div class="footer-social">
<a href="https://www.linkedin.com/company/nenghuitech" class="social-link linkedin" aria-label="LinkedIn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
<a href="https://www.facebook.com/nenghuitech" class="social-link facebook" aria-label="Facebook">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
</svg>
</a>
<a href="https://x.com/NenghuiTech" class="social-link twitter" aria-label="Twitter">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
</a>
</div>
</div>
<!-- 导航菜单区域 -->
<div class="footer-nav">
<div class="footer-nav-column">
<h3 class="footer-nav-title">Products</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/products/ne418l/">NB418L</a></li>
<li><a href="https://nenghui.com/products/ne233l/">NE233L</a></li>
<li><a href="https://nenghui.com/products/ne261l/">NE261L</a></li>
<li><a href="https://nenghui.com/products/n20hc5000/">N20HC5000</a></li>
<li><a href="https://nenghui.com/products/nh-ics180-261/">NH-ICS180-261</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">Support</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/download-center/">Download Center</a></li>
<li><a href="https://nenghui.com/support/">Service</a></li>
<li><a href="https://nenghui.com/faq/">FAQ</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">ABOUT US</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/about-us/">Company Profile</a></li>
<li><a href="https://nenghui.com/honor/">Certifications & Accreditations</a></li>
<li><a href="https://nenghui.com/oem/">OEM</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">Contact us</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/contact-us/">Contact us</a></li>
</ul>
</div>
</div>
<!-- 订阅区域 -->
<div class="footer-subscribe">
<?php echo do_shortcode('[fluentform id="3"]'); ?>
</div>
</div>
<!-- 分隔线 -->
<div class="footer-divider"></div>
<!-- 底部版权信息 -->
<div class="footer-bottom">
<div class="footer-copyright">
<p>&copy; <?php echo date('Y'); ?> Shanghai Nenghui Technology Co.,Ltd. All rights reserved.</p>
</div>
<div class="footer-links">
<?php
$cookie_options = get_option('nenghui_cookie_options');
$privacy_page_id = isset($cookie_options['privacy_policy_page']) ? $cookie_options['privacy_policy_page'] : '';
$cookie_page_id = isset($cookie_options['cookie_policy_page']) ? $cookie_options['cookie_policy_page'] : '';
if ($privacy_page_id) : ?>
<a href="<?php echo get_permalink($privacy_page_id); ?>">Privacy Policy</a>
<?php endif; ?>
<?php if ($cookie_page_id) : ?>
<a href="<?php echo get_permalink($cookie_page_id); ?>">Cookie Policy</a>
<?php endif; ?>
</div>
</div>
</div>
<?php wp_footer(); ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.js"></script>
<script>
AOS.init({
duration: 800, // 动画持续时间
once: true, // 动画只触发一次,防止回滚时重复触发
offset: 100, // 触发偏移量
easing: 'ease-out-cubic', // 缓动函数
});
</script>
</footer>
</body>
</html>

@ -0,0 +1,337 @@
<?php
/**
* 主题核心文件
* 负责加载各个功能模块
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 导入错误处理配置(优先加载)
require_once 'inc/error-handler.php';
// 导入主题初始化配置
require_once 'inc/init-config.php';
// 导入主题基础设置
require_once 'inc/theme-setup.php';
// 导入后台管理配置
require_once 'inc/admin-config.php';
// 导入资源加载配置
require_once 'inc/assets-loader.php';
// 导入媒体配置
require_once 'inc/media-config.php';
// 导入清理和优化功能
require_once 'inc/cleanup.php';
// 导入性能优化配置文件
require_once 'inc/performance-config.php';
// 导入自定义器配置
require_once 'inc/customizer.php';
// 导入短代码功能
require_once 'inc/shortcode.php';
// 导入SEO配置功能
require_once 'inc/seo-config.php';
// 导入自定义代码管理功能
require_once 'inc/custom-code-config.php';
// 导入Header/Footer自定义代码功能暂时注释掉以避免冲突
// require_once 'inc/custom-code.php';
// 导入SMTP邮件配置
require_once 'inc/smtp/smtp-config.php';
require_once 'inc/smtp/smtp-admin.php';
// 导入维护模式功能
require_once 'inc/maintenance-mode.php';
// 导入Cookie Consent功能
require_once 'inc/cookie-consent.php';
// 导入FAQ自定义文章类型
require_once 'inc/cpt-faq.php';
// 导入文章浏览量统计功能
require_once 'inc/post-views.php';
// 导入调试工具(仅在调试模式下)
// if (defined('WP_DEBUG') && WP_DEBUG) {
// require_once 'test-menu-debug.php';
// }
/**
* 增强编辑角色权限
* 为编辑角色添加外观管理的全部功能
*/
function enhance_editor_capabilities() {
// 获取编辑角色对象
$role = get_role('editor');
if ($role) {
// 添加外观相关的权限
$role->add_cap('edit_theme_options'); // 编辑主题选项
$role->add_cap('customize'); // 自定义器
$role->add_cap('switch_themes'); // 切换主题
$role->add_cap('edit_themes'); // 编辑主题
$role->add_cap('update_themes'); // 更新主题
$role->add_cap('install_themes'); // 安装主题
$role->add_cap('delete_themes'); // 删除主题
$role->add_cap('upload_themes'); // 上传主题
}
}
// 在主题激活时运行一次
add_action('after_switch_theme', 'enhance_editor_capabilities');
// 确保在插件加载后运行一次
add_action('init', 'enhance_editor_capabilities');
// 在导航菜单管理页面显示菜单ID
function nenghui_show_menu_id_in_nav_menus() {
// 只在nav-menus.php页面加载
global $pagenow;
if ($pagenow !== 'nav-menus.php') {
return;
}
// 获取所有菜单
$menus = wp_get_nav_menus();
if (empty($menus)) {
return;
}
?>
<style>
.nenghui-menu-id-info {
background: #f1f1f1;
border: 1px solid #ccc;
border-radius: 4px;
padding: 10px;
margin: 10px 0;
font-size: 13px;
}
.nenghui-menu-id-info h4 {
margin: 0 0 8px 0;
color: #23282d;
}
.nenghui-menu-list {
margin: 0;
padding: 0;
list-style: none;
}
.nenghui-menu-list li {
margin: 4px 0;
padding: 4px 8px;
background: #fff;
border-radius: 2px;
display: flex;
justify-content: space-between;
align-items: center;
}
.nenghui-menu-name {
font-weight: 500;
}
.nenghui-menu-id {
color: #666;
font-family: monospace;
background: #f9f9f9;
padding: 2px 6px;
border-radius: 2px;
font-size: 12px;
}
</style>
<script>
jQuery(document).ready(function($) {
// 在页面顶部添加菜单ID信息
var menuInfo = '<div class="nenghui-menu-id-info">' +
'<h4>📋 可用菜单及其ID</h4>' +
'<ul class="nenghui-menu-list">';
<?php foreach ($menus as $menu): ?>
menuInfo += '<li>' +
'<span class="nenghui-menu-name"><?php echo esc_js($menu->name); ?></span>' +
'<span class="nenghui-menu-id">ID: <?php echo esc_js($menu->term_id); ?></span>' +
'</li>';
<?php endforeach; ?>
menuInfo += '</ul>' +
'<p style="margin: 8px 0 0 0; color: #666; font-size: 12px;">' +
'💡 提示:在短代码中使用 <code>[nenghui_about_nav menu_id="菜单ID"]</code> 来指定菜单' +
'</p></div>';
// 将信息插入到页面顶部
$('#nav-menus-frame').prepend(menuInfo);
// 为现有的菜单标题添加ID显示
$('.menu-edit').each(function() {
var $menuEdit = $(this);
var menuId = $menuEdit.find('input[name="menu"]').val();
if (menuId) {
var $title = $menuEdit.find('.menu-name-label');
if ($title.length > 0) {
var currentText = $title.text();
if (currentText && !currentText.includes('(ID:')) {
$title.text(currentText + ' (ID: ' + menuId + ')');
}
}
}
});
// 为主题位置的下拉菜单添加ID显示
$('.menu-theme-locations select option').each(function() {
var $option = $(this);
var optionValue = $option.val();
var optionText = $option.text();
if (optionValue && optionText && !optionText.includes('(ID:')) {
$option.text(optionText + ' (ID: ' + optionValue + ')');
}
});
});
</script>
<?php
}
add_action('admin_footer-nav-menus.php', 'nenghui_show_menu_id_in_nav_menus');
// 在菜单管理页面添加帮助信息
function nenghui_add_menu_help_info() {
$screen = get_current_screen();
if ($screen && $screen->id === 'nav-menus') {
$screen->add_help_tab(array(
'id' => 'nenghui-menu-ids',
'title' => '菜单ID使用',
'content' => '<h3>如何使用菜单ID</h3>' .
'<p>每个菜单都有一个唯一的数字ID您可以在短代码中使用这些ID来指定特定的菜单。</p>' .
'<h4>About导航短代码示例</h4>' .
'<ul>' .
'<li><code>[nenghui_about_nav]</code> - 使用自定义器中设置的默认菜单</li>' .
'<li><code>[nenghui_about_nav menu_id="2"]</code> - 使用ID为2的菜单</li>' .
'<li><code>[nenghui_about_nav menu_id="5"]</code> - 使用ID为5的菜单</li>' .
'</ul>' .
'<p><strong>注意:</strong>菜单ID在页面顶部的信息框中显示请使用正确的ID。</p>'
));
}
}
add_action('current_screen', 'nenghui_add_menu_help_info');
// 导入主题配置文件
// require_once 'theme-options.php'; // 暂时注释掉,文件不存在
// 导入小工具配置
require_once 'widgets/widgets-config.php';
// 刷新重写规则以确保FAQ归档页面正常工作
function nenghui_flush_rewrite_rules() {
// 只在主题激活时执行一次
if (get_option('nenghui_rewrite_rules_flushed') !== '1') {
flush_rewrite_rules();
update_option('nenghui_rewrite_rules_flushed', '1');
}
}
add_action('after_switch_theme', 'nenghui_flush_rewrite_rules');
// 当FAQ文章类型注册后刷新重写规则
function nenghui_flush_rewrite_rules_on_init() {
static $flushed = false;
if (!$flushed && get_option('nenghui_faq_rewrite_flushed') !== '1') {
flush_rewrite_rules();
update_option('nenghui_faq_rewrite_flushed', '1');
$flushed = true;
}
}
add_action('init', 'nenghui_flush_rewrite_rules_on_init', 999);
// 所有功能已拆分到独立的配置文件中:
// - 主题设置: inc/theme-setup.php
// - 后台管理: inc/admin-config.php
// - 资源加载: inc/assets-loader.php
// - 媒体配置: inc/media-config.php
// - 初始化配置: inc/init-config.php
// - 清理优化: inc/cleanup.php
// - 性能配置: inc/performance-config.php
// - 自定义器: inc/customizer.php
// - 短代码: inc/shortcode.php
/**
* 自定义导航菜单Walker类支持多级下拉菜单
*/
class Nenghui_Walker_Nav_Menu extends Walker_Nav_Menu {
// 开始输出子菜单
function start_lvl(&$output, $depth = 0, $args = null) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<ul class=\"sub-menu\">\n";
}
// 结束输出子菜单
function end_lvl(&$output, $depth = 0, $args = null) {
$indent = str_repeat("\t", $depth);
$output .= "$indent</ul>\n";
}
// 显示元素
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
$id_field = $this->db_fields['id'];
if (is_object($args[0])) {
$args[0]->has_children = !empty($children_elements[$element->$id_field]);
}
return parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
// 开始输出菜单项
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
$indent = ($depth) ? str_repeat("\t", $depth) : '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
// 检查是否有子菜单
$has_children = !empty($args->has_children);
if ($has_children) {
$classes[] = 'menu-item-has-children';
}
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
$class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';
$id = apply_filters('nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args);
$id = $id ? ' id="' . esc_attr($id) . '"' : '';
$output .= $indent . '<li' . $id . $class_names .'>';
$attributes = ! empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) .'"' : '';
$attributes .= ! empty($item->target) ? ' target="' . esc_attr($item->target ) .'"' : '';
$attributes .= ! empty($item->xfn) ? ' rel="' . esc_attr($item->xfn ) .'"' : '';
$attributes .= ! empty($item->url) ? ' href="' . esc_attr($item->url ) .'"' : '';
$item_output = isset($args->before) ? $args->before : '';
$item_output .= '<a' . $attributes . '>';
$item_output .= (isset($args->link_before) ? $args->link_before : '') . apply_filters('the_title', $item->title, $item->ID) . (isset($args->link_after) ? $args->link_after : '');
// 如果有子菜单,添加下拉箭头
if ($has_children) {
$item_output .= ' <span class="dropdown-arrow"></span>';
}
$item_output .= '</a>';
$item_output .= isset($args->after) ? $args->after : '';
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
// 结束输出菜单项
function end_el(&$output, $item, $depth = 0, $args = null) {
$output .= "</li>\n";
}
}
?>

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="google-site-verification" content="4-DXQwmh6Tn_4TiIaslQa4L-xJTXT0XBVn2dCB_A7F8" />
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
<?php wp_head(); ?>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700&amp;display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
},
fontFamily: {
"display": ["Space Grotesk", "sans-serif"],
"sans": ["Space Grotesk", "sans-serif"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out'
}
},
},
}
</script>
</head>
<body <?php body_class(); ?>>
<nav class="main-nav">
<div class="nav-container">
<div class="nav-logo">
<a href="<?php echo home_url(); ?>">
<?php
$logo = get_theme_mod('site_logo');
if ($logo): ?>
<img src="<?php echo esc_url($logo); ?>" alt="<?php bloginfo('name'); ?>">
<?php else: ?>
<img src="https://nenghui.com/wp-content/uploads/2025/11/logo-2.png" alt="logo">
<?php endif; ?>
</a>
</div>
<button class="menu-toggle" aria-label="菜单">
<span></span>
<span></span>
<span></span>
</button>
<div class="nav-menu">
<?php
wp_nav_menu(array(
'theme_location' => 'primary-menu',
'container' => false,
'menu_class' => 'menu-items',
'walker' => new Nenghui_Walker_Nav_Menu(),
'fallback_cb' => function() {
echo '<ul class="menu-items"><li><a href="' . admin_url('nav-menus.php') . '">添加菜单</a></li></ul>';
}
));
?>
</div>
</div>
</nav>

@ -0,0 +1,281 @@
<?php
/**
* 后台管理配置文件
* 包含评论禁用、后台菜单管理、管理员样式等功能
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 加载后台样式
*/
function nenghui_admin_style() {
wp_enqueue_style('nenghui-admin-style', get_template_directory_uri() . '/assets/css/admin.css');
}
add_action('admin_enqueue_scripts', 'nenghui_admin_style');
/**
* 禁用评论功能 - 移除评论菜单
* 从后台管理菜单中移除评论管理页面
*/
function disable_comments_admin_menu() {
// 确保全局菜单变量是数组防止foreach错误
global $menu, $submenu;
if (!is_array($menu)) {
$menu = array();
}
if (!is_array($submenu)) {
$submenu = array();
}
remove_menu_page('edit-comments.php');
}
add_action('admin_init', 'disable_comments_admin_menu');
/**
* 禁用评论功能 - 重定向评论页面访问
* 如果用户直接访问评论管理页面,重定向到仪表盘
*/
function disable_comments_admin_menu_redirect() {
global $pagenow;
if ($pagenow === 'edit-comments.php') {
wp_redirect(admin_url());
exit;
}
}
add_action('admin_init', 'disable_comments_admin_menu_redirect');
/**
* 禁用评论功能 - 移除文章类型的评论支持
* 从所有支持评论的文章类型中移除评论和引用通告支持
*/
function disable_comments_post_types_support() {
// 确保在正确的时机调用,避免过早执行
if (!function_exists('get_post_types') || !function_exists('post_type_supports')) {
return;
}
try {
$post_types = get_post_types();
// 增强的数组验证
if (!is_array($post_types)) {
// 记录错误并使用安全的默认值
if (function_exists('nenghui_log_foreach_error')) {
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'get_post_types() returned non-array value: ' . gettype($post_types),
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'admin',
'user_agent' => 'disable_comments_post_types_support'
));
}
$post_types = array('post', 'page'); // 安全的默认值
}
if (empty($post_types)) {
return; // 如果没有文章类型,直接返回
}
// 使用安全的 foreach 循环
foreach ($post_types as $post_type) {
// 验证 post_type 是有效的字符串
if (!is_string($post_type) || empty($post_type)) {
continue;
}
// 检查函数是否存在并且文章类型支持评论
if (function_exists('post_type_supports') && post_type_supports($post_type, 'comments')) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
}
} catch (Exception $e) {
// 捕获任何异常并记录
if (function_exists('nenghui_log_foreach_error')) {
nenghui_log_foreach_error(array(
'error_type' => E_ERROR,
'error_message' => 'Exception in disable_comments_post_types_support: ' . $e->getMessage(),
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'admin',
'user_agent' => 'disable_comments_post_types_support'
));
}
}
}
add_action('admin_init', 'disable_comments_post_types_support');
/**
* 禁用评论功能 - 移除工具栏菜单
*/
function disable_comments_admin_bar() {
if (is_admin_bar_showing()) {
remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
}
}
add_action('init', 'disable_comments_admin_bar');
/**
* 禁用评论功能 - 过滤器
*/
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
add_filter('comments_array', '__return_empty_array', 10, 2);
/**
* 分类图片支持
*/
// 添加分类图片字段
function category_image_add_form_fields($taxonomy) {
?>
<div class="form-field term-group">
<label for="category-image-id">分类图片</label>
<input type="hidden" id="category-image-id" name="category-image-id" class="custom_media_url" value="">
<div id="category-image-wrapper"></div>
<p>
<input type="button" class="button button-secondary ct_tax_media_button" id="ct_tax_media_button" name="ct_tax_media_button" value="添加图片" />
<input type="button" class="button button-secondary ct_tax_media_remove" id="ct_tax_media_remove" name="ct_tax_media_remove" value="移除图片" />
</p>
</div>
<?php
}
add_action('category_add_form_fields', 'category_image_add_form_fields', 10, 2);
// 编辑分类图片字段
function category_image_edit_form_fields($term, $taxonomy) {
$image_id = get_term_meta($term->term_id, 'category-image-id', true);
?>
<tr class="form-field term-group-wrap">
<th scope="row">
<label for="category-image-id">分类图片</label>
</th>
<td>
<input type="hidden" id="category-image-id" name="category-image-id" value="<?php echo esc_attr($image_id); ?>">
<div id="category-image-wrapper">
<?php if ($image_id) { echo wp_get_attachment_image($image_id, 'thumbnail'); } ?>
</div>
<p>
<input type="button" class="button button-secondary ct_tax_media_button" id="ct_tax_media_button" name="ct_tax_media_button" value="添加图片" />
<input type="button" class="button button-secondary ct_tax_media_remove" id="ct_tax_media_remove" name="ct_tax_media_remove" value="移除图片" />
</p>
</td>
</tr>
<?php
}
add_action('category_edit_form_fields', 'category_image_edit_form_fields', 10, 2);
// 保存分类图片
function save_category_image($term_id, $tt_id) {
if (isset($_POST['category-image-id']) && '' !== $_POST['category-image-id']){
$image = $_POST['category-image-id'];
update_term_meta($term_id, 'category-image-id', $image);
} else if (isset($_POST['category-image-id']) && '' === $_POST['category-image-id']){
update_term_meta($term_id, 'category-image-id', '');
}
}
add_action('created_category', 'save_category_image', 10, 2);
add_action('edited_category', 'save_category_image', 10, 2);
// 加载分类图片脚本
function category_image_script() {
// 只在分类编辑页加载
$screen = get_current_screen();
if ($screen && ($screen->base === 'term' || $screen->base === 'edit-tags')) {
wp_enqueue_media();
} else {
return;
}
?>
<script>
jQuery(document).ready(function($) {
function initMediaUploader() {
var _custom_media = true,
_orig_send_attachment = wp.media.editor.send.attachment;
$('body').on('click','.ct_tax_media_button',function(e) {
var send_attachment_bkp = wp.media.editor.send.attachment;
var button = $(this);
var id = button.attr('id').replace('_button', '');
_custom_media = true;
wp.media.editor.send.attachment = function(props, attachment) {
if (_custom_media) {
$('#category-image-id').val(attachment.id);
$('#category-image-wrapper').html('<img class="custom_media_image" src="" style="margin:0;padding:0;max-height:100px;float:none;" />');
$('#category-image-wrapper .custom_media_image').attr('src',attachment.url).css('display','block');
} else {
return _orig_send_attachment.apply(this, [props, attachment]);
}
}
wp.media.editor.open(button);
return false;
});
$('.add_media').on('click', function() {
_custom_media = false;
});
// 修复上传按钮点击
if(typeof ct_media_upload === 'function') {
ct_media_upload('.ct_tax_media_button.button');
}
$('body').on('click','.ct_tax_media_remove',function(){
$('#category-image-id').val('');
$('#category-image-wrapper').html('');
$('#ct_tax_media_button').val('添加图片');
});
// 页面加载时显示现有图片
$(document).ajaxComplete(function(event, xhr, settings) {
if (settings.data && settings.data.indexOf('action=add-tag') !== -1) {
var xml = xhr.responseXML;
if (xml) {
var response = $(xml).find('term_id').text();
if (response !== "") {
// 清空表单
$('#category-image-wrapper').html('');
$('#category-image-id').val('');
$('#ct_tax_media_button').val('添加图片');
}
}
}
});
}
// 延迟初始化,确保所有脚本都已加载
setTimeout(initMediaUploader, 500);
});
</script>
<?php
}
add_action('admin_footer', 'category_image_script');
// 获取分类图片的辅助函数
function get_category_image($category_id, $size = 'full') {
$image_id = get_term_meta($category_id, 'category-image-id', true);
if ($image_id) {
return wp_get_attachment_image_src($image_id, $size);
}
return false;
}
// 获取分类图片URL的辅助函数
function get_category_image_url($category_id, $size = 'full') {
$image = get_category_image($category_id, $size);
return $image ? $image[0] : '';
}
/**
* 集成区域跳转管理器 (Region Redirect Manager)
*/
require_once get_template_directory() . '/inc/redirect-manager/class-redirect-manager.php';
// 注册跳转管理器的自定义设置
add_action('customize_register', array('Nenghui_Redirect_Manager', 'register_customizer_settings'));

@ -0,0 +1,246 @@
<?php
/**
* 资源加载配置文件
* 管理前端脚本和样式的加载包含jQuery管理和性能优化
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 前端脚本和样式加载
* 正确管理jQuery版本和主题资源文件的加载顺序
*/
function nenghui_enqueue_scripts() {
// 确保不在管理后台执行jQuery替换
if (is_admin()) {
return;
}
// 获取文件路径和版本号
$jquery_file = get_template_directory() . '/assets/js/jquery.min.js';
$main_js_file = get_template_directory() . '/assets/js/index.js';
$main_css_file = get_template_directory() . '/assets/css/index.css';
// 检查文件是否存在
if (!file_exists($jquery_file) || !file_exists($main_js_file) || !file_exists($main_css_file)) {
return;
}
$jquery_version = filemtime($jquery_file);
$main_js_version = filemtime($main_js_file);
$main_css_version = filemtime($main_css_file);
// 安全地移除和重新注册jQuery
if (wp_script_is('jquery', 'registered')) {
wp_deregister_script('jquery');
}
// 注册并加载jQuery本地化
wp_register_script('jquery', get_template_directory_uri() . '/assets/js/jquery.min.js', array(), $jquery_version, true);
wp_enqueue_script('jquery');
// 添加jQuery fallback机制
wp_add_inline_script('jquery', 'window.jQuery || document.write(\'<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"><\/script>\');');
// 加载主题自定义JSBanner轮播现在使用原生JavaScript实现
wp_enqueue_script('nenghui-main-js', get_template_directory_uri() . '/assets/js/index.js', array('jquery'), $main_js_version, true);
// 按正确的依赖顺序加载样式文件避免CSS阻塞渲染
// 只加载必要的CSS文件
wp_enqueue_style('nenghui-main-css', get_template_directory_uri() . '/assets/css/index.css', array(), $main_css_version);
// 添加滚动动画样式和平滑滚动
$scroll_animation_css = '
/* 平滑滚动 */
html {
scroll-behavior: smooth;
}
/* 滚动动画基础样式 */
.fade-in-block {
opacity: 0;
transform: translateY(20px);
transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.fade-in-block.animate {
opacity: 1;
transform: translateY(0);
}
/* 为所有区块添加动画类 */
.about-company-section,
.banner-section,
.cases-section,
.certification-section,
.contact-map-section,
.development-history-section,
.download-center-section,
.ess-scenarios-section,
.faq-section,
.futures-section,
.home-news-section,
.map-section,
.news-section,
.overseas-services-section,
.tabs-section,
.technical-service-section,
.warehousing-distribution-section,
.about-info-section,
.products-banner-section,
.about-nav-section,
.black-about-company-banner {
opacity: 0;
transform: translateY(20px);
transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.about-company-section.animate,
.banner-section.animate,
.cases-section.animate,
.certification-section.animate,
.contact-map-section.animate,
.development-history-section.animate,
.download-center-section.animate,
.ess-scenarios-section.animate,
.faq-section.animate,
.futures-section.animate,
.home-news-section.animate,
.map-section.animate,
.news-section.animate,
.overseas-services-section.animate,
.tabs-section.animate,
.technical-service-section.animate,
.warehousing-distribution-section.animate,
.about-info-section.animate,
.products-banner-section.animate,
.about-nav-section.animate,
.black-about-company-banner.animate {
opacity: 1;
transform: translateY(0);
}
/* 延迟动画效果 */
.fade-in-block:nth-child(1) { transition-delay: 0.1s; }
.fade-in-block:nth-child(2) { transition-delay: 0.2s; }
.fade-in-block:nth-child(3) { transition-delay: 0.3s; }
.fade-in-block:nth-child(4) { transition-delay: 0.4s; }
.fade-in-block:nth-child(5) { transition-delay: 0.5s; }
/* 响应式优化 */
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.fade-in-block,
.about-company-section,
.banner-section,
.cases-section,
.certification-section,
.contact-map-section,
.development-history-section,
.download-center-section,
.ess-scenarios-section,
.faq-section,
.futures-section,
.home-news-section,
.map-section,
.news-section,
.overseas-services-section,
.tabs-section,
.technical-service-section,
.warehousing-distribution-section,
.about-info-section,
.products-banner-section,
.about-nav-section,
.black-about-company-banner {
opacity: 1;
transform: none;
transition: none;
}
}
';
wp_add_inline_style('nenghui-main-css', $scroll_animation_css);
// 添加滚动动画JavaScript
$scroll_animation_js = '
document.addEventListener("DOMContentLoaded", function() {
// 创建Intersection Observer
const observerOptions = {
root: null,
rootMargin: "0px 0px -100px 0px",
threshold: 0.1
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add("animate");
// 一旦动画触发,就停止观察该元素
observer.unobserve(entry.target);
}
});
}, observerOptions);
// 选择所有需要动画的区块
const animatedBlocks = document.querySelectorAll(
".about-company-section, .banner-section, " +
".cases-section, .certification-section, .contact-map-section, " +
".development-history-section, .download-center-section, .ess-scenarios-section, " +
".faq-section, .futures-section, .home-news-section, " +
".map-section, .news-section, .overseas-services-section, " +
".tabs-section, .technical-service-section, .warehousing-distribution-section, " +
".about-info-section, .products-banner-section, .about-nav-section, " +
".black-about-company-banner, .fade-in-block"
);
// 开始观察所有区块
animatedBlocks.forEach(function(block) {
observer.observe(block);
});
// 优化滚动性能
let ticking = false;
function updateScrollPosition() {
// 这里可以添加额外的滚动优化逻辑
ticking = false;
}
window.addEventListener("scroll", function() {
if (!ticking) {
requestAnimationFrame(updateScrollPosition);
ticking = true;
}
}, { passive: true });
});
';
wp_add_inline_script('nenghui-main-js', $scroll_animation_js);
// 只在文章详情页和案例详情页加载post.css
if (is_single() || is_singular('cases')) {
$post_css_file = get_template_directory() . '/assets/css/post.css';
if (file_exists($post_css_file)) {
$post_css_version = filemtime($post_css_file);
wp_enqueue_style('nenghui-post-css', get_template_directory_uri() . '/assets/css/post.css', array('nenghui-main-css'), $post_css_version);
}
}
// 加载black-about-company-banner样式
$black_about_banner_css_file = get_template_directory() . '/assets/css/black-about-company-banner.css';
if (file_exists($black_about_banner_css_file)) {
$black_about_banner_css_version = filemtime($black_about_banner_css_file);
wp_enqueue_style('black-about-company-banner-style', get_template_directory_uri() . '/assets/css/black-about-company-banner.css', array('nenghui-main-css'), $black_about_banner_css_version);
}
// 加载black-about-company-banner轮播JavaScript
$black_about_banner_js_file = get_template_directory() . '/assets/js/black-about-company-banner.js';
if (file_exists($black_about_banner_js_file)) {
$black_about_banner_js_version = filemtime($black_about_banner_js_file);
wp_enqueue_script('black-about-company-banner-js', get_template_directory_uri() . '/assets/js/black-about-company-banner.js', array('jquery'), $black_about_banner_js_version, true);
}
}
add_action('wp_enqueue_scripts', 'nenghui_enqueue_scripts');
?>

@ -0,0 +1,457 @@
<?php
/**
* WordPress 清理和优化功能
* 包含头像替换、自动更新禁用、冗余代码移除等功能
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 替换 Gravatar 头像为 V2EX CDN
*/
function replace_gravatar($avatar) {
$avatar = str_replace(array(
"//gravatar.com/",
"//secure.gravatar.com/",
"//www.gravatar.com/",
"//0.gravatar.com/",
"//1.gravatar.com/",
"//2.gravatar.com/",
"//cn.gravatar.com/"
), "//cdn.v2ex.com/gr", $avatar);
return $avatar;
}
add_filter('get_avatar', 'replace_gravatar');
/**
* 修复 WordPress 上 Cravatar 头像无法显示问题
*/
if (!function_exists('get_cravatar_url')) {
function get_cravatar_url($url) {
$sources = array(
'www.gravatar.com',
'0.gravatar.com',
'1.gravatar.com',
'2.gravatar.com',
'secure.gravatar.com',
'cn.gravatar.com'
);
return str_replace($sources, 'cravatar.cn', $url);
}
add_filter('um_user_avatar_url_filter', 'get_cravatar_url', 1);
add_filter('bp_gravatar_url', 'get_cravatar_url', 1);
add_filter('get_avatar_url', 'get_cravatar_url', 1);
}
/**
* 文章插入图片自动移除 img 的 width、height、class 属性
*/
function fanly_remove_images_attribute($html) {
$html = preg_replace('/width="(\d*)"\s+height="(\d*)"\s+class="[^"]*"/', "", $html);
$html = preg_replace('/ /', "", $html);
return $html;
}
add_filter('post_thumbnail_html', 'fanly_remove_images_attribute', 10);
add_filter('image_send_to_editor', 'fanly_remove_images_attribute', 10);
/**
* 移动设备自适应图片删除 width 和 height 属性
*/
function ludou_remove_width_height_attribute($content) {
preg_match_all('/<[img|IMG].*?src=[\'"](.+?(?:[\.+gif|\.+jpg|\.+png\.webp]))[\'"].*?[\/]?>/', $content, $images);
if (!empty($images) && is_array($images) && isset($images[0]) && is_array($images[0]) && !empty($images[0])) {
foreach ($images[0] as $index => $value) {
if (isset($images[0][$index]) && is_string($images[0][$index])) {
$new_img = preg_replace('/(width|height)="\d*"\s/', "", $images[0][$index]);
$content = str_replace($images[0][$index], $new_img, $content);
}
}
}
return $content;
}
// 判断是否是移动设备浏览
if (wp_is_mobile()) {
add_filter('the_content', 'ludou_remove_width_height_attribute', 99);
}
/**
* 彻底关闭自动更新(核心程序/主题/插件/翻译自动更新)
*/
add_filter('automatic_updater_disabled', '__return_true');
// 关闭更新检查定时作业
remove_action('init', 'wp_schedule_update_checks');
// 移除已有的版本检查定时作业
wp_clear_scheduled_hook('wp_version_check');
wp_clear_scheduled_hook('wp_update_plugins');
wp_clear_scheduled_hook('wp_update_themes');
wp_clear_scheduled_hook('wp_maybe_auto_update');
// 移除后台内核更新检查
remove_action('admin_init', '_maybe_update_core');
// 移除后台插件更新检查
remove_action('load-plugins.php', 'wp_update_plugins');
remove_action('load-update.php', 'wp_update_plugins');
remove_action('load-update-core.php', 'wp_update_plugins');
remove_action('admin_init', '_maybe_update_plugins');
// 移除后台主题更新检查
remove_action('load-themes.php', 'wp_update_themes');
remove_action('load-update.php', 'wp_update_themes');
remove_action('load-update-core.php', 'wp_update_themes');
remove_action('admin_init', '_maybe_update_themes');
// 关闭程序更新提示
add_filter('pre_site_transient_update_core', function($a) { return null; });
add_filter('pre_site_transient_update_plugins', function($a) { return null; });
add_filter('pre_site_transient_update_themes', function($a) { return null; });
/**
* 关闭 WordPress 的 XML-RPC 功能
*/
add_filter('xmlrpc_enabled', '__return_false');
/**
* 关闭 XML-RPC 的 pingback 端口
*/
function remove_xmlrpc_pingback_ping($methods) {
// 确保 $methods 是数组
if (!is_array($methods)) {
return $methods;
}
unset($methods['pingback.ping']);
return $methods;
}
add_filter('xmlrpc_methods', 'remove_xmlrpc_pingback_ping');
/**
* 移除前端网页源代码内的头部冗余代码
*/
remove_action('wp_head', 'feed_links_extra', 3);
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'index_rel_link');
remove_action('wp_head', 'start_post_rel_link', 10, 0);
remove_action('wp_head', 'wp_generator');
/**
* 禁止新版文章编辑器加载前端样式
*/
function wpassist_remove_block_library_css() {
wp_dequeue_style('wp-block-library');
wp_dequeue_style('wp-block-library-theme');
wp_dequeue_style('wc-block-style'); // WooCommerce
wp_dequeue_style('global-styles'); // WordPress 5.9+
}
add_action('wp_enqueue_scripts', 'wpassist_remove_block_library_css', 100);
/**
* 移除前后台顶部工具栏指定菜单
*/
function admin_bar_item(WP_Admin_Bar $admin_bar) {
$admin_bar->remove_menu('wp-logo'); // 移除 wp 的 logo
$admin_bar->remove_menu('updates'); // 移除更新提示
$admin_bar->remove_menu('comments'); // 移除评论提示
}
add_action('admin_bar_menu', 'admin_bar_item', 500);
/**
* 移除后台仪表盘菜单:活动、新闻
*/
function bzg_remove_dashboard_widgets() {
global $wp_meta_boxes;
// 确保 $wp_meta_boxes 是数组且包含必要的键
if (!is_array($wp_meta_boxes)) {
return;
}
// 安全地移除 "活动"
if (isset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'])) {
unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity']);
}
// 安全地移除 "WordPress 新闻"
if (isset($wp_meta_boxes['dashboard']['side']['core']['dashboard_primary'])) {
unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_primary']);
}
}
add_action('wp_dashboard_setup', 'bzg_remove_dashboard_widgets');
/**
* 移除 login 页面的版权信息
*/
function yqd_login_logo_url() {
return home_url();
}
add_filter('login_headerurl', 'yqd_login_logo_url');
/**
* 自定义登录页面logo
*/
function custom_login_logo() {
echo '<style type="text/css">
#login h1 a {
background-image: url(' . get_template_directory_uri() . '/assets/images/logo.svg) !important;
background-size: contain !important;
background-repeat: no-repeat !important;
background-position: center !important;
width: 200px !important;
height: 80px !important;
margin: 0 auto 25px !important;
}
</style>';
}
add_action('login_enqueue_scripts', 'custom_login_logo');
/**
* 自定义登录页面logo标题
*/
function custom_login_logo_title() {
return get_bloginfo('name');
}
add_filter('login_headertitle', 'custom_login_logo_title');
/**
* 删除 WordPress 后台底部版权信息
*/
function _admin_footer_right_text($text) {
$text = '';
return $text;
}
add_filter('update_footer', '_admin_footer_right_text', 11);
/**
* 移除后台仪表盘菜单:帮助
*/
function bzg_remove_help() {
$screen = get_current_screen();
if ($screen && method_exists($screen, 'remove_help_tabs')) {
$screen->remove_help_tabs();
}
}
add_action('admin_head', 'bzg_remove_help');
/**
* 禁用 pingbacks, enclosures, trackbacks
*/
remove_action('do_pings', 'do_all_pings', 10);
remove_action('publish_post', '_publish_post_hook', 5);
/**
* 禁止加载 s.w.org 获取表情和头像
*/
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles');
/**
* 移除 DNS 预取
*/
function remove_dns_prefetch($hints, $relation_type) {
// 确保 $hints 是数组
if (!is_array($hints)) {
return $hints;
}
if ('dns-prefetch' === $relation_type) {
$unique_hosts = wp_dependencies_unique_hosts();
if (is_array($unique_hosts)) {
return array_diff($hints, $unique_hosts);
}
}
return $hints;
}
add_filter('wp_resource_hints', 'remove_dns_prefetch', 10, 2);
/**
* 替换评论用户头像链接为国内镜像加速源访问
*/
add_filter('get_avatar', function ($avatar) {
return str_replace([
'www.gravatar.com/avatar/',
'0.gravatar.com/avatar/',
'1.gravatar.com/avatar/',
'2.gravatar.com/avatar/',
'secure.gravatar.com/avatar/',
'cn.gravatar.com/avatar/'
], 'cravatar.cn/', $avatar);
});
/**
* 禁止查询网站静态资源连接版本字符
*/
function _remove_script_version($src) {
$parts = explode('?', $src);
return $parts[0];
}
add_filter('script_loader_src', '_remove_script_version', 15, 1);
add_filter('style_loader_src', '_remove_script_version', 15, 1);
/**
* 支持 WebP 格式
*/
function add_webp_mime_type($mimes) {
$mimes['webp'] = 'image/webp';
return $mimes;
}
add_filter('mime_types', 'add_webp_mime_type');
/**
* 支持 SVG 格式
*/
function add_svg_mime_type($mimes) {
$mimes['svg'] = 'image/svg+xml';
return $mimes;
}
add_filter('upload_mimes', 'add_svg_mime_type');
/**
* 优化CSS加载 - 延迟加载非关键CSS
*/
function optimize_css_loading() {
// 仅在前端执行
if (is_admin()) {
return;
}
// 延迟加载非关键CSS
add_filter('style_loader_tag', function($html, $handle, $href, $media) {
// 定义非关键CSS样式表
$non_critical_styles = array(
'wp-block-library',
'wp-block-library-theme',
'wc-block-style',
'global-styles'
);
if (in_array($handle, $non_critical_styles)) {
// 使用preload + onload技术延迟加载
$html = str_replace("rel='stylesheet'", "rel='preload' as='style' onload=\"this.onload=null;this.rel='stylesheet'\"", $html);
// 添加noscript fallback
$html .= '<noscript>' . str_replace("rel='preload' as='style' onload=\"this.onload=null;this.rel='stylesheet'\"", "rel='stylesheet'", $html) . '</noscript>';
}
return $html;
}, 10, 4);
}
add_action('wp_enqueue_scripts', 'optimize_css_loading', 1);
/**
* 优化JavaScript加载
*/
function optimize_js_loading() {
// 仅在前端执行
if (is_admin()) {
return;
}
// 为非关键JS添加defer属性
add_filter('script_loader_tag', function($tag, $handle, $src) {
// 定义需要defer的脚本
$defer_scripts = array(
'jquery-migrate',
'wp-embed',
'comment-reply'
);
if (in_array($handle, $defer_scripts)) {
return str_replace(' src', ' defer src', $tag);
}
return $tag;
}, 10, 3);
}
add_action('wp_enqueue_scripts', 'optimize_js_loading', 1);
/**
* 移除不必要的CSS和JS
*/
function remove_unnecessary_assets() {
// 仅在前端执行
if (is_admin()) {
return;
}
// 移除WordPress默认样式
wp_dequeue_style('dashicons'); // 仅后台需要
// 移除不必要的JS
wp_dequeue_script('wp-embed');
// 如果不使用评论功能,移除评论相关脚本
if (!is_single() && !is_page()) {
wp_dequeue_script('comment-reply');
}
}
add_action('wp_enqueue_scripts', 'remove_unnecessary_assets', 100);
/**
* 添加关键CSS内联
*/
function add_critical_css() {
// 仅在前端执行
if (is_admin()) {
return;
}
// 添加关键CSS到head中
echo '<style id="critical-css">';
echo 'body{margin:0;padding:0;font-family:sans-serif;}';
echo '.site-header{position:relative;z-index:999;}';
echo '.main-content{min-height:50vh;}';
echo '</style>';
}
add_action('wp_head', 'add_critical_css', 1);
/**
* 优化资源提示
*/
function add_resource_hints() {
// 仅在前端执行
if (is_admin()) {
return;
}
// 添加DNS预连接
echo '<link rel="preconnect" href="//fonts.googleapis.com" crossorigin>';
echo '<link rel="preconnect" href="//cdn.v2ex.com" crossorigin>';
echo '<link rel="preconnect" href="//cravatar.cn" crossorigin>';
}
add_action('wp_head', 'add_resource_hints', 1);
/**
* 压缩HTML输出
*/
function compress_html_output($buffer) {
// 仅在前端压缩
if (is_admin()) {
return $buffer;
}
// 移除HTML注释保留IE条件注释
$buffer = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $buffer);
// 移除多余的空白字符
$buffer = preg_replace('/\s+/', ' ', $buffer);
// 移除行首行尾空白
$buffer = preg_replace('/^\s+|\s+$/m', '', $buffer);
return $buffer;
}
// 启用HTML压缩可选可能影响某些插件
// add_action('template_redirect', function() {
// if (!is_admin()) {
// ob_start('compress_html_output');
// }
// });

@ -0,0 +1,252 @@
<?php
/**
* Cookie Consent & Policy Module
*/
if (!defined('ABSPATH')) {
exit;
}
class Nenghui_Cookie_Consent {
private $options;
public function __construct() {
add_action('admin_menu', array($this, 'add_plugin_page'));
add_action('admin_init', array($this, 'page_init'));
add_action('wp_footer', array($this, 'render_frontend_assets'));
}
public function add_plugin_page() {
add_options_page(
'Cookie Consent & Policies',
'Cookie Consent',
'manage_options',
'nenghui-cookie-consent',
array($this, 'create_admin_page')
);
}
public function create_admin_page() {
$this->options = get_option('nenghui_cookie_options');
?>
<div class="wrap">
<h1>Cookie同意与政策设置</h1>
<form method="post" action="options.php">
<?php
settings_fields('nenghui_cookie_group');
do_settings_sections('nenghui-cookie-consent');
submit_button();
?>
</form>
</div>
<?php
}
public function page_init() {
register_setting(
'nenghui_cookie_group',
'nenghui_cookie_options'
);
add_settings_section(
'nenghui_cookie_section_main',
'Cookie同意与政策设置',
null,
'nenghui-cookie-consent'
);
add_settings_field(
'cookie_notice_text',
'Cookie同意通知文本',
array($this, 'cookie_notice_text_callback'),
'nenghui-cookie-consent',
'nenghui_cookie_section_main'
);
add_settings_field(
'cookie_accept_label',
'“同意”按钮文本',
array($this, 'cookie_accept_label_callback'),
'nenghui-cookie-consent',
'nenghui_cookie_section_main'
);
add_settings_field(
'cookie_decline_label',
'“拒绝”按钮文本',
array($this, 'cookie_decline_label_callback'),
'nenghui-cookie-consent',
'nenghui_cookie_section_main'
);
add_settings_section(
'nenghui_cookie_section_pages',
'相关政策页面设置',
null,
'nenghui-cookie-consent'
);
add_settings_field(
'privacy_policy_page',
'隐私政策页面 (Privacy Policy)',
array($this, 'privacy_policy_page_callback'),
'nenghui-cookie-consent',
'nenghui_cookie_section_pages'
);
add_settings_field(
'cookie_policy_page',
'Cookie政策页面 (Cookie Policy)',
array($this, 'cookie_policy_page_callback'),
'nenghui-cookie-consent',
'nenghui_cookie_section_pages'
);
}
public function cookie_notice_text_callback() {
$text = isset($this->options['cookie_notice_text']) ? $this->options['cookie_notice_text'] : 'We use cookies to improve your experience on our website. By browsing this website, you agree to our use of cookies.';
echo '<textarea name="nenghui_cookie_options[cookie_notice_text]" rows="3" class="large-text">' . esc_textarea($text) . '</textarea>';
}
public function cookie_accept_label_callback() {
$text = isset($this->options['cookie_accept_label']) ? $this->options['cookie_accept_label'] : 'Accept';
echo '<input type="text" name="nenghui_cookie_options[cookie_accept_label]" value="' . esc_attr($text) . '" class="regular-text">';
}
public function cookie_decline_label_callback() {
$text = isset($this->options['cookie_decline_label']) ? $this->options['cookie_decline_label'] : 'Decline';
echo '<input type="text" name="nenghui_cookie_options[cookie_decline_label]" value="' . esc_attr($text) . '" class="regular-text">';
}
public function privacy_policy_page_callback() {
$selected = isset($this->options['privacy_policy_page']) ? $this->options['privacy_policy_page'] : '';
wp_dropdown_pages(array(
'name' => 'nenghui_cookie_options[privacy_policy_page]',
'selected' => $selected,
'show_option_none' => '选择页面'
));
}
public function cookie_policy_page_callback() {
$selected = isset($this->options['cookie_policy_page']) ? $this->options['cookie_policy_page'] : '';
wp_dropdown_pages(array(
'name' => 'nenghui_cookie_options[cookie_policy_page]',
'selected' => $selected,
'show_option_none' => '选择页面'
));
}
public function render_frontend_assets() {
$options = get_option('nenghui_cookie_options');
$notice_text = isset($options['cookie_notice_text']) ? $options['cookie_notice_text'] : 'We use cookies to improve your experience on our website. By browsing this website, you agree to our use of cookies.';
$accept_label = isset($options['cookie_accept_label']) ? $options['cookie_accept_label'] : 'Accept';
$decline_label = isset($options['cookie_decline_label']) ? $options['cookie_decline_label'] : 'Decline';
$cookie_url = isset($options['cookie_policy_page']) && !empty($options['cookie_policy_page']) ? get_permalink($options['cookie_policy_page']) : '#';
?>
<!-- Cookie Consent Banner -->
<div id="nh-cookie-banner" class="nh-cookie-banner" style="display: none;">
<div class="nh-cookie-content">
<p><?php echo esc_html($notice_text); ?></p>
<div class="nh-cookie-links">
<?php if($cookie_url !== '#'): ?><a href="<?php echo esc_url($cookie_url); ?>" class="nh-policy-link">Cookie Policy</a><?php endif; ?>
</div>
</div>
<div class="nh-cookie-actions">
<button id="nh-cookie-accept" class="nh-cookie-btn nh-accept"><?php echo esc_html($accept_label); ?></button>
<button id="nh-cookie-decline" class="nh-cookie-btn nh-decline"><?php echo esc_html($decline_label); ?></button>
</div>
</div>
<style>
.nh-cookie-banner {
position: fixed;
bottom: 20px;
left: 20px;
max-width: 400px;
background: #fff;
padding: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.15);
border-radius: 8px;
z-index: 9999;
font-family: inherit;
border-left: 5px solid #0056b3;
}
.nh-cookie-content p {
margin: 0 0 10px;
font-size: 14px;
color: #333;
line-height: 1.5;
}
.nh-cookie-links {
margin-bottom: 15px;
font-size: 12px;
}
.nh-cookie-links a {
color: #0056b3;
text-decoration: underline;
margin-right: 10px;
cursor: pointer;
}
.nh-cookie-actions {
display: flex;
gap: 10px;
}
.nh-cookie-btn {
flex: 1;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: all 0.3s ease;
text-align: center;
}
.nh-cookie-btn.nh-accept {
background: #0056b3;
color: white;
}
.nh-cookie-btn.nh-accept:hover {
background: #004494;
}
.nh-cookie-btn.nh-decline {
background: #f1f1f1;
color: #666;
}
.nh-cookie-btn.nh-decline:hover {
background: #e1e1e1;
color: #333;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var cookieBanner = document.getElementById('nh-cookie-banner');
var acceptBtn = document.getElementById('nh-cookie-accept');
var declineBtn = document.getElementById('nh-cookie-decline');
// Check for cookie consent
if (!localStorage.getItem('nh_cookie_consent')) {
cookieBanner.style.display = 'block';
}
// Accept button
acceptBtn.addEventListener('click', function() {
localStorage.setItem('nh_cookie_consent', 'accepted');
cookieBanner.style.display = 'none';
});
// Decline button
declineBtn.addEventListener('click', function() {
localStorage.setItem('nh_cookie_consent', 'declined');
cookieBanner.style.display = 'none';
});
});
</script>
<?php
}
}
new Nenghui_Cookie_Consent();

@ -0,0 +1,62 @@
<?php
/**
* FAQ Custom Post Type Registration
*/
if (!defined('ABSPATH')) {
exit;
}
function nenghui_register_faq_cpt() {
$labels = array(
'name' => _x('FAQs', 'Post Type General Name', 'nenghui'),
'singular_name' => _x('FAQ', 'Post Type Singular Name', 'nenghui'),
'menu_name' => __('FAQs', 'nenghui'),
'name_admin_bar' => __('FAQ', 'nenghui'),
'archives' => __('FAQ Archives', 'nenghui'),
'attributes' => __('FAQ Attributes', 'nenghui'),
'parent_item_colon' => __('Parent FAQ:', 'nenghui'),
'all_items' => __('All FAQs', 'nenghui'),
'add_new_item' => __('Add New FAQ', 'nenghui'),
'add_new' => __('Add New', 'nenghui'),
'new_item' => __('New FAQ', 'nenghui'),
'edit_item' => __('Edit FAQ', 'nenghui'),
'update_item' => __('Update FAQ', 'nenghui'),
'view_item' => __('View FAQ', 'nenghui'),
'view_items' => __('View FAQs', 'nenghui'),
'search_items' => __('Search FAQ', 'nenghui'),
'not_found' => __('Not found', 'nenghui'),
'not_found_in_trash' => __('Not found in Trash', 'nenghui'),
'featured_image' => __('Featured Image', 'nenghui'),
'set_featured_image' => __('Set featured image', 'nenghui'),
'remove_featured_image' => __('Remove featured image', 'nenghui'),
'use_featured_image' => __('Use as featured image', 'nenghui'),
'insert_into_item' => __('Insert into FAQ', 'nenghui'),
'uploaded_to_this_item' => __('Uploaded to this FAQ', 'nenghui'),
'items_list' => __('FAQs list', 'nenghui'),
'items_list_navigation' => __('FAQs list navigation', 'nenghui'),
'filter_items_list' => __('Filter FAQs list', 'nenghui'),
);
$args = array(
'label' => __('FAQ', 'nenghui'),
'description' => __('Frequently Asked Questions', 'nenghui'),
'labels' => $labels,
'supports' => array('title', 'editor', 'page-attributes'), // page-attributes for menu_order
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 20,
'menu_icon' => 'dashicons-format-chat',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true, // Enable Gutenberg editor
);
register_post_type('faq', $args);
}
add_action('init', 'nenghui_register_faq_cpt');

@ -0,0 +1,530 @@
<?php
/**
* 自定义代码管理配置文件
* 提供后台管理界面来添加自定义JS和CSS代码
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 添加自定义代码管理菜单
*/
function nenghui_add_custom_code_menu() {
add_theme_page(
'自定义代码管理', // 页面标题
'自定义代码', // 菜单标题
'edit_theme_options', // 权限要求
'nenghui-custom-code', // 菜单slug
'nenghui_custom_code_page' // 回调函数
);
// 添加Header/Footer代码管理子菜单
add_theme_page(
'Header/Footer代码管理',
'Header/Footer代码',
'edit_theme_options',
'nenghui-header-footer-code',
'nenghui_header_footer_admin_page'
);
}
add_action('admin_menu', 'nenghui_add_custom_code_menu');
/**
* 自定义代码管理页面
*/
function nenghui_custom_code_page() {
// 处理表单提交
if (isset($_POST['submit']) && wp_verify_nonce($_POST['nenghui_custom_code_nonce'], 'nenghui_custom_code_action')) {
// 保存自定义CSS
if (isset($_POST['custom_css'])) {
update_option('nenghui_custom_css', wp_unslash($_POST['custom_css']));
}
// 保存自定义HTML/JS
if (isset($_POST['custom_html'])) {
update_option('nenghui_custom_html', wp_unslash($_POST['custom_html']));
}
// 保存CSS启用状态
update_option('nenghui_custom_css_enabled', isset($_POST['css_enabled']) ? '1' : '0');
// 保存HTML/JS启用状态
update_option('nenghui_custom_html_enabled', isset($_POST['html_enabled']) ? '1' : '0');
echo '<div class="notice notice-success is-dismissible"><p>设置已保存!</p></div>';
}
// 获取当前设置
$custom_css = get_option('nenghui_custom_css', '');
$custom_html = get_option('nenghui_custom_html', '');
$css_enabled = get_option('nenghui_custom_css_enabled', '1');
$html_enabled = get_option('nenghui_custom_html_enabled', '1');
?>
<div class="wrap">
<h1>自定义代码管理</h1>
<p>在这里可以添加自定义的CSS和JavaScript代码这些代码将在网站前端加载。</p>
<form method="post" action="">
<?php wp_nonce_field('nenghui_custom_code_action', 'nenghui_custom_code_nonce'); ?>
<div class="nenghui-custom-code-section">
<h2>自定义CSS</h2>
<p class="description">添加自定义CSS样式代码无需包含 &lt;style&gt; 标签。</p>
<label for="css_enabled">
<input type="checkbox" id="css_enabled" name="css_enabled" value="1" <?php checked($css_enabled, '1'); ?>>
启用自定义CSS
</label>
<div class="nenghui-code-editor">
<textarea
id="custom_css"
name="custom_css"
rows="15"
cols="100"
placeholder="/* 在这里输入您的CSS代码 */
.my-custom-class {
color: #333;
font-size: 16px;
}"
class="large-text code"
><?php echo esc_textarea($custom_css); ?></textarea>
</div>
</div>
<div class="nenghui-custom-code-section">
<h2>自定义HTML/JavaScript</h2>
<p class="description">添加自定义HTML和JavaScript代码支持完整的HTML标签。代码将在页面底部加载。</p>
<label for="html_enabled">
<input type="checkbox" id="html_enabled" name="html_enabled" value="1" <?php checked($html_enabled, '1'); ?>>
启用自定义HTML/JavaScript
</label>
<div class="nenghui-code-editor">
<textarea
id="custom_html"
name="custom_html"
rows="15"
cols="100"
placeholder="<!-- 在这里输入您的HTML和JavaScript代码 -->
<script>
jQuery(document).ready(function($) {
// 您的JavaScript代码
console.log('自定义HTML/JS已加载');
});
</script>
<!-- 您也可以添加HTML元素 -->
<div id='custom-element' style='display:none;'>
<p>这是自定义HTML内容</p>
</div>"
class="large-text code"
><?php echo esc_textarea($custom_html); ?></textarea>
</div>
</div>
<div class="nenghui-custom-code-tips">
<h3>💡 使用提示</h3>
<ul>
<li><strong>CSS代码</strong>直接输入CSS规则系统会自动包装在 &lt;style&gt; 标签中</li>
<li><strong>HTML/JavaScript代码</strong>支持完整的HTML标签包括script、div、span等</li>
<li><strong>jQuery支持</strong>主题已加载jQuery可以直接使用 $ 或 jQuery</li>
<li><strong>HTML元素</strong>可以添加自定义的HTML元素和内联样式</li>
<li><strong>代码安全:</strong>请确保代码来源可靠,避免添加恶意代码</li>
<li><strong>测试建议:</strong>添加代码后请在前端测试效果,确保没有错误</li>
</ul>
</div>
<?php submit_button('保存设置'); ?>
</form>
</div>
<style>
.nenghui-custom-code-section {
background: #fff;
border: 1px solid #ccd0d4;
border-radius: 4px;
padding: 20px;
margin: 20px 0;
}
.nenghui-custom-code-section h2 {
margin-top: 0;
color: #23282d;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
.nenghui-code-editor {
margin-top: 15px;
}
.nenghui-code-editor textarea {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 13px;
line-height: 1.4;
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
width: 100%;
box-sizing: border-box;
resize: vertical;
}
.nenghui-code-editor textarea:focus {
border-color: #007cba;
box-shadow: 0 0 0 1px #007cba;
outline: none;
}
.nenghui-custom-code-tips {
background: #f0f6fc;
border: 1px solid #c6e2ff;
border-radius: 4px;
padding: 20px;
margin: 20px 0;
}
.nenghui-custom-code-tips h3 {
margin-top: 0;
color: #0366d6;
}
.nenghui-custom-code-tips ul {
margin: 10px 0;
padding-left: 20px;
}
.nenghui-custom-code-tips li {
margin: 8px 0;
line-height: 1.5;
}
.nenghui-custom-code-section label {
display: inline-block;
margin-bottom: 10px;
font-weight: 600;
}
.nenghui-custom-code-section input[type="checkbox"] {
margin-right: 8px;
}
</style>
<?php
}
/**
* 在前端输出自定义CSS
*/
function nenghui_output_custom_css() {
$css_enabled = get_option('nenghui_custom_css_enabled', '1');
$custom_css = get_option('nenghui_custom_css', '');
if ($css_enabled === '1' && !empty($custom_css)) {
echo "\n<!-- 自定义CSS开始 -->\n";
echo '<style type="text/css" id="nenghui-custom-css">' . "\n";
echo wp_strip_all_tags($custom_css);
echo "\n</style>\n";
echo "<!-- 自定义CSS结束 -->\n";
}
}
add_action('wp_head', 'nenghui_output_custom_css', 999);
/**
* 在前端输出自定义HTML/JavaScript
*/
function nenghui_output_custom_html() {
$html_enabled = get_option('nenghui_custom_html_enabled', '1');
$custom_html = get_option('nenghui_custom_html', '');
if ($html_enabled === '1' && !empty($custom_html)) {
echo "\n<!-- 自定义HTML/JavaScript开始 -->\n";
echo '<div id="nenghui-custom-html-container">' . "\n";
// 检查用户权限,只有管理员或编辑者才能使用此功能
if (current_user_can('edit_theme_options')) {
// 对于有权限的用户直接输出HTML内容已在后台进行基本验证
echo wp_unslash($custom_html);
} else {
// 对于其他情况,进行严格的安全过滤
echo wp_kses($custom_html, array(
'script' => array(
'type' => array(),
'src' => array(),
'async' => array(),
'defer' => array()
),
'div' => array(
'id' => array(),
'class' => array(),
'style' => array()
),
'span' => array(
'id' => array(),
'class' => array(),
'style' => array()
),
'p' => array(
'id' => array(),
'class' => array(),
'style' => array()
),
'a' => array(
'href' => array(),
'target' => array(),
'id' => array(),
'class' => array(),
'style' => array()
),
'img' => array(
'src' => array(),
'alt' => array(),
'width' => array(),
'height' => array(),
'id' => array(),
'class' => array(),
'style' => array()
),
'h1' => array('id' => array(), 'class' => array(), 'style' => array()),
'h2' => array('id' => array(), 'class' => array(), 'style' => array()),
'h3' => array('id' => array(), 'class' => array(), 'style' => array()),
'h4' => array('id' => array(), 'class' => array(), 'style' => array()),
'h5' => array('id' => array(), 'class' => array(), 'style' => array()),
'h6' => array('id' => array(), 'class' => array(), 'style' => array()),
'ul' => array('id' => array(), 'class' => array(), 'style' => array()),
'ol' => array('id' => array(), 'class' => array(), 'style' => array()),
'li' => array('id' => array(), 'class' => array(), 'style' => array()),
'br' => array(),
'strong' => array('id' => array(), 'class' => array(), 'style' => array()),
'em' => array('id' => array(), 'class' => array(), 'style' => array()),
'b' => array('id' => array(), 'class' => array(), 'style' => array()),
'i' => array('id' => array(), 'class' => array(), 'style' => array())
));
}
echo "\n</div>\n";
echo "<!-- 自定义HTML/JavaScript结束 -->\n";
}
}
add_action('wp_footer', 'nenghui_output_custom_html', 999);
/**
* 为自定义代码管理页面添加帮助信息
*/
function nenghui_add_custom_code_help() {
$screen = get_current_screen();
if ($screen && $screen->id === 'appearance_page_nenghui-custom-code') {
$screen->add_help_tab(array(
'id' => 'nenghui-custom-code-help',
'title' => '使用帮助',
'content' => '<h3>自定义代码管理帮助</h3>' .
'<h4>CSS代码示例</h4>' .
'<pre>/* 修改标题颜色 */\n' .
'h1, h2, h3 {\n' .
' color: #333;\n' .
'}\n\n' .
'/* 自定义按钮样式 */\n' .
'.custom-button {\n' .
' background: #007cba;\n' .
' color: white;\n' .
' padding: 10px 20px;\n' .
' border-radius: 4px;\n' .
'}</pre>' .
'<h4>JavaScript代码示例</h4>' .
'<pre>// 页面加载完成后执行\n' .
'jQuery(document).ready(function($) {\n' .
' // 添加点击事件\n' .
' $(".custom-button").click(function() {\n' .
' alert("按钮被点击了!");\n' .
' });\n' .
'});\n\n' .
'// 原生JavaScript示例\n' .
'document.addEventListener("DOMContentLoaded", function() {\n' .
' console.log("页面加载完成");\n' .
'});</pre>' .
'<h4>注意事项:</h4>' .
'<ul>' .
'<li>CSS代码会在页面头部加载</li>' .
'<li>JavaScript代码会在页面底部加载</li>' .
'<li>可以随时启用或禁用代码而不删除内容</li>' .
'<li>建议在测试环境中先测试代码效果</li>' .
'</ul>'
));
$screen->set_help_sidebar(
'<p><strong>相关链接:</strong></p>' .
'<p><a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS" target="_blank">CSS文档</a></p>' .
'<p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript" target="_blank">JavaScript文档</a></p>' .
'<p><a href="https://jquery.com/" target="_blank">jQuery官网</a></p>'
);
}
}
add_action('current_screen', 'nenghui_add_custom_code_help');
/**
* Header/Footer代码管理页面
*/
function nenghui_header_footer_admin_page() {
// 处理表单提交
if (isset($_POST['submit']) && wp_verify_nonce($_POST['nenghui_header_footer_nonce'], 'nenghui_header_footer_action')) {
// 保存Header代码
if (isset($_POST['header_code'])) {
update_option('nenghui_header_code_content', wp_unslash($_POST['header_code']));
}
// 保存Footer代码
if (isset($_POST['footer_code'])) {
update_option('nenghui_footer_code_content', wp_unslash($_POST['footer_code']));
}
// 保存启用状态
update_option('nenghui_header_code_enabled', isset($_POST['header_enabled']) ? '1' : '0');
update_option('nenghui_footer_code_enabled', isset($_POST['footer_enabled']) ? '1' : '0');
echo '<div class="notice notice-success is-dismissible"><p>Header/Footer代码设置已保存</p></div>';
}
// 获取当前设置
$header_code = get_option('nenghui_header_code_content', '');
$footer_code = get_option('nenghui_footer_code_content', '');
$header_enabled = get_option('nenghui_header_code_enabled', '0');
$footer_enabled = get_option('nenghui_footer_code_enabled', '0');
?>
<div class="wrap">
<h1>Header/Footer自定义代码管理</h1>
<p>在这里可以管理网站头部和底部的自定义HTML代码如统计代码、验证代码、客服代码等。</p>
<form method="post" action="">
<?php wp_nonce_field('nenghui_header_footer_action', 'nenghui_header_footer_nonce'); ?>
<div class="nenghui-code-section">
<h2>🔝 Header自定义代码</h2>
<p class="description">这些代码将在网站头部(&lt;head&gt;标签内加载适合放置统计代码、验证代码、meta标签等。</p>
<label for="header_enabled">
<input type="checkbox" id="header_enabled" name="header_enabled" value="1" <?php checked($header_enabled, '1'); ?>>
启用Header自定义代码
</label>
<div class="nenghui-code-editor">
<textarea
id="header_code"
name="header_code"
rows="12"
cols="100"
placeholder="<!-- 示例Google Analytics代码 -->
<script async src=&quot;https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID&quot;></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
</script>"
class="large-text code"
><?php echo esc_textarea($header_code); ?></textarea>
</div>
</div>
<div class="nenghui-code-section">
<h2>🔻 Footer自定义代码</h2>
<p class="description">这些代码将在网站底部(&lt;/body&gt;标签前加载适合放置客服代码、统计代码、自定义JavaScript等。</p>
<label for="footer_enabled">
<input type="checkbox" id="footer_enabled" name="footer_enabled" value="1" <?php checked($footer_enabled, '1'); ?>>
启用Footer自定义代码
</label>
<div class="nenghui-code-editor">
<textarea
id="footer_code"
name="footer_code"
rows="12"
cols="100"
placeholder="<!-- 示例:客服代码 -->
<script>
(function() {
var script = document.createElement('script');
script.src = 'https://example.com/chat.js';
document.body.appendChild(script);
})();
</script>"
class="large-text code"
><?php echo esc_textarea($footer_code); ?></textarea>
</div>
</div>
<?php submit_button('保存Header/Footer代码设置'); ?>
</form>
</div>
<style>
.nenghui-code-section {
background: #fff;
border: 1px solid #ccd0d4;
border-radius: 6px;
padding: 25px;
margin: 25px 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.nenghui-code-section h2 {
margin-top: 0;
color: #23282d;
border-bottom: 2px solid #0073aa;
padding-bottom: 10px;
font-size: 18px;
}
.nenghui-code-section label {
display: inline-block;
margin-bottom: 15px;
font-weight: 600;
color: #23282d;
}
.nenghui-code-section input[type="checkbox"] {
margin-right: 8px;
transform: scale(1.1);
}
</style>
<?php
}
/**
* 在网站头部输出自定义Header代码
*/
function nenghui_output_header_code() {
$header_enabled = get_option('nenghui_header_code_enabled', '0');
$header_code = get_option('nenghui_header_code_content', '');
if ($header_enabled === '1' && !empty($header_code)) {
echo "\n<!-- Nenghui自定义Header代码开始 -->\n";
echo wp_unslash($header_code);
echo "\n<!-- Nenghui自定义Header代码结束 -->\n";
}
}
add_action('wp_head', 'nenghui_output_header_code', 998);
/**
* 在网站底部输出自定义Footer代码
*/
function nenghui_output_footer_code() {
$footer_enabled = get_option('nenghui_footer_code_enabled', '0');
$footer_code = get_option('nenghui_footer_code_content', '');
if ($footer_enabled && !empty($footer_code)) {
echo "\n<!-- Nenghui自定义Footer代码开始 -->\n";
echo wp_unslash($footer_code);
echo "\n<!-- Nenghui自定义Footer代码结束 -->\n";
}
}
add_action('wp_footer', 'nenghui_output_footer_code', 998);
?>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,321 @@
<?php
/**
* 错误处理和调试配置文件
* 专门用于诊断和修复 plugin.php 中的 foreach 错误
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 增强的错误处理函数
* 捕获和记录 foreach 相关的错误
*/
function nenghui_error_handler($errno, $errstr, $errfile, $errline) {
// 只处理 foreach 相关的错误
if (strpos($errstr, 'foreach') !== false || strpos($errstr, 'Invalid argument') !== false) {
$error_info = array(
'error_type' => $errno,
'error_message' => $errstr,
'error_file' => $errfile,
'error_line' => $errline,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'unknown'
);
// 记录错误日志
nenghui_log_foreach_error($error_info);
// 如果是调试模式,显示详细信息
if (WP_DEBUG && WP_DEBUG_DISPLAY) {
echo '<div style="background: #ffebee; border: 1px solid #f44336; padding: 10px; margin: 10px; border-radius: 4px;">';
echo '<strong>Foreach Error Detected:</strong><br>';
echo 'File: ' . esc_html($errfile) . '<br>';
echo 'Line: ' . esc_html($errline) . '<br>';
echo 'Message: ' . esc_html($errstr) . '<br>';
echo '</div>';
}
}
// 返回 false 让 PHP 继续处理错误
return false;
}
/**
* 记录 foreach 错误到日志文件
*/
function nenghui_log_foreach_error($error_info) {
$upload_dir = wp_upload_dir();
// 确保 $upload_dir 是数组且包含 basedir
if (!is_array($upload_dir) || !isset($upload_dir['basedir'])) {
return;
}
$log_file = $upload_dir['basedir'] . '/foreach_errors.log';
$log_entry = sprintf(
"[%s] FOREACH ERROR: %s in %s on line %d (URI: %s)\n",
$error_info['timestamp'],
$error_info['error_message'],
$error_info['error_file'],
$error_info['error_line'],
$error_info['request_uri']
);
// 确保日志文件安全
if (!file_exists($log_file)) {
file_put_contents($log_file, "# Foreach Errors Log\n");
chmod($log_file, 0600);
}
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}
/**
* 安全的 foreach 包装函数
* 确保传入的变量是可迭代的数组
*/
function nenghui_safe_foreach($array, $callback) {
if (!is_array($array) && !($array instanceof Traversable)) {
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'nenghui_safe_foreach: Invalid argument supplied, expected array or Traversable',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_safe_foreach'
));
return false;
}
if (is_callable($callback)) {
foreach ($array as $key => $value) {
call_user_func($callback, $value, $key);
}
return true;
}
return false;
}
/**
* 修复常见的 WordPress 全局变量问题
* 确保关键的全局变量是正确的数组格式
*/
function nenghui_fix_wp_globals() {
global $wp_filter, $wp_actions, $wp_current_filter, $wp_meta_boxes, $wp_settings_sections, $wp_settings_fields;
// 确保 $wp_filter 是数组
if (!is_array($wp_filter)) {
$wp_filter = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_filter global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
// 确保 $wp_actions 是数组
if (!is_array($wp_actions)) {
$wp_actions = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_actions global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
// 确保 $wp_current_filter 是数组
if (!is_array($wp_current_filter)) {
$wp_current_filter = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_current_filter global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
// 确保 $wp_meta_boxes 是数组
if (!is_array($wp_meta_boxes)) {
$wp_meta_boxes = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_meta_boxes global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
// 确保 $wp_settings_sections 是数组
if (!is_array($wp_settings_sections)) {
$wp_settings_sections = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_settings_sections global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
// 确保 $wp_settings_fields 是数组
if (!is_array($wp_settings_fields)) {
$wp_settings_fields = array();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => 'Fixed $wp_settings_fields global variable - was not array',
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_wp_globals'
));
}
}
/**
* 在插件加载前修复全局变量
*/
function nenghui_pre_plugin_fix() {
nenghui_fix_wp_globals();
}
/**
* 检查和修复主题选项中的数组
*/
function nenghui_fix_theme_options() {
// 检查常用的主题选项
$options_to_check = array(
'banner_images',
'futures_items',
'news_posts',
'menu_items',
'tab_items'
);
foreach ($options_to_check as $option) {
$value = get_theme_mod($option);
if ($value !== false && !is_array($value)) {
// 尝试将非数组值转换为数组
if (is_string($value) && !empty($value)) {
// 如果是 JSON 字符串,尝试解码
$decoded = json_decode($value, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
set_theme_mod($option, $decoded);
} else {
// 否则包装为数组
set_theme_mod($option, array($value));
}
} else {
// 设置为空数组
set_theme_mod($option, array());
}
}
}
}
/**
* 专门修复 plugin.php 第 1853 行的 foreach 错误
* 这个错误通常发生在钩子系统中的数组操作
*/
function nenghui_fix_plugin_foreach_error() {
global $wp_filter;
// 确保 $wp_filter 的每个钩子都是正确的数组结构
if (is_array($wp_filter)) {
foreach ($wp_filter as $hook_name => $hook_callbacks) {
if (!is_object($hook_callbacks) && !is_array($hook_callbacks)) {
// 如果钩子回调不是对象或数组,重置为空的 WP_Hook 对象
$wp_filter[$hook_name] = new WP_Hook();
nenghui_log_foreach_error(array(
'error_type' => E_WARNING,
'error_message' => "Fixed invalid hook callbacks for '$hook_name' - was " . gettype($hook_callbacks),
'error_file' => __FILE__,
'error_line' => __LINE__,
'timestamp' => date('Y-m-d H:i:s'),
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'unknown',
'user_agent' => 'nenghui_fix_plugin_foreach_error'
));
}
}
}
}
/**
* 在最早期修复全局变量
* 确保在任何插件或主题代码执行前修复问题
*/
function nenghui_early_fix() {
nenghui_fix_wp_globals();
nenghui_fix_plugin_foreach_error();
}
/**
* 立即修复全局变量 - 在文件加载时就执行
* 这确保在任何WordPress函数调用前就修复了全局变量
*/
function nenghui_immediate_fix() {
global $menu, $submenu, $wp_filter, $wp_actions, $wp_current_filter;
// 立即确保关键全局变量是数组
if (!is_array($menu)) {
$menu = array();
}
if (!is_array($submenu)) {
$submenu = array();
}
if (!is_array($wp_filter)) {
$wp_filter = array();
}
if (!is_array($wp_actions)) {
$wp_actions = array();
}
if (!is_array($wp_current_filter)) {
$wp_current_filter = array();
}
}
// 立即执行修复
nenghui_immediate_fix();
// 注册错误处理器(仅在调试模式下)
if (WP_DEBUG) {
set_error_handler('nenghui_error_handler', E_WARNING | E_NOTICE);
}
// 在最早期修复全局变量 - 在 muplugins_loaded 之前
add_action('muplugins_loaded', 'nenghui_early_fix', 1);
// 在插件加载前再次修复
add_action('plugins_loaded', 'nenghui_pre_plugin_fix', 1);
// 在主题设置后修复主题选项
add_action('after_setup_theme', 'nenghui_fix_theme_options', 1);
// 在管理页面初始化前修复
add_action('admin_init', 'nenghui_early_fix', 1);
// 在前端初始化前修复
add_action('init', 'nenghui_early_fix', 1);
// 在admin_menu动作前确保菜单变量正确
add_action('admin_menu', 'nenghui_immediate_fix', 1);
?>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save