You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

925 lines
27 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* 案例展示板块模板
* 支持选项卡、分页和响应式卡片布局
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 获取短代码参数
global $cases_shortcode_atts;
$atts = $cases_shortcode_atts;
// 设置默认值
$block_id = !empty($atts['id']) ? $atts['id'] : 'nenghui-cases';
$block_class = !empty($atts['class']) ? $atts['class'] : '';
$title = !empty($atts['title']) ? $atts['title'] : 'Cases';
$posts_per_page = !empty($atts['posts_per_page']) ? intval($atts['posts_per_page']) : 6;
$columns = !empty($atts['columns']) ? intval($atts['columns']) : 3;
$show_pagination = !empty($atts['show_pagination']) ? $atts['show_pagination'] === 'true' : true;
$show_tabs = !empty($atts['show_tabs']) ? $atts['show_tabs'] === 'true' : true;
$default_category = !empty($atts['default_category']) ? $atts['default_category'] : 'power-station';
$show_animation = !empty($atts['show_animation']) ? $atts['show_animation'] === 'true' : true;
// 获取案例分类
$categories = get_terms(array(
'taxonomy' => 'case_category',
'hide_empty' => false,
'orderby' => 'term_order',
'order' => 'ASC'
));
// 如果没有分类,创建默认分类
if (empty($categories) || is_wp_error($categories)) {
$categories = array(
(object) array(
'term_id' => 1,
'name' => 'Power Station',
'slug' => 'power-station',
'description' => '电站项目案例'
),
(object) array(
'term_id' => 2,
'name' => 'PV Project',
'slug' => 'pv-project',
'description' => '光伏项目案例'
),
(object) array(
'term_id' => 3,
'name' => 'Agricultural Solar',
'slug' => 'agricultural-solar',
'description' => '农业太阳能项目案例'
)
);
}
// 获取当前页码
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
// 生成唯一ID
$unique_id = $block_id . '-' . uniqid();
// 获取背景设置
$background_type = get_theme_mod('cases_background_type', 'color');
$background_color = get_theme_mod('cases_background_color', '#f8f9fa');
$background_image = get_theme_mod('cases_background_image', '');
$background_video = get_theme_mod('cases_background_video', '');
$background_position = get_theme_mod('cases_background_position', 'center center');
$background_size = get_theme_mod('cases_background_size', 'cover');
$background_repeat = get_theme_mod('cases_background_repeat', 'no-repeat');
$background_overlay = get_theme_mod('cases_background_overlay', true);
$background_overlay_color = get_theme_mod('cases_background_overlay_color', '#000000');
$background_overlay_opacity = get_theme_mod('cases_background_overlay_opacity', '0.4');
$section_title = get_theme_mod('cases_section_title', 'Cases');
// 如果title参数为空使用自定义器中的标题
if (empty($title)) {
$title = $section_title;
}
?>
<section id="<?php echo esc_attr($block_id); ?>" class="cases-section nenghui-cases-section <?php echo esc_attr($block_class); ?> position-relative">
<?php if ($background_type === 'video' && !empty($background_video)): ?>
<video class="cases-background-video" autoplay muted loop playsinline>
<source src="<?php echo esc_url($background_video); ?>" type="video/mp4">
<?php if (!empty($background_image)): ?>
<img src="<?php echo esc_url($background_image); ?>" alt="Background" class="cases-video-fallback">
<?php endif; ?>
</video>
<?php endif; ?>
<?php if ($background_overlay && ($background_type === 'image' || $background_type === 'video')): ?>
<div class="cases-background-overlay"></div>
<?php endif; ?>
<div class="container position-relative">
<?php if (!empty($title)): ?>
<div class="section-header text-center mb-5">
<h2 class="section-title <?php echo $show_animation ? 'animate-on-scroll' : ''; ?>" data-animation="fadeInUp">
<?php echo esc_html($title); ?>
</h2>
</div>
<?php endif; ?>
<?php if ($show_tabs && !empty($categories)): ?>
<!-- 案例分类选项卡 -->
<div class="cases-tabs-wrapper <?php echo $show_animation ? 'animate-on-scroll' : ''; ?>" data-animation="fadeInUp" data-delay="200">
<ul class="cases-tabs" role="tablist">
<?php foreach ($categories as $index => $category): ?>
<li class="tab-item" role="presentation">
<button class="tab-link <?php echo ($index === 0 || $category->slug === $default_category) ? 'active' : ''; ?>"
id="tab-<?php echo esc_attr($category->slug); ?>"
data-category="<?php echo esc_attr($category->slug); ?>"
type="button"
role="tab"
aria-controls="content-<?php echo esc_attr($category->slug); ?>"
aria-selected="<?php echo ($index === 0 || $category->slug === $default_category) ? 'true' : 'false'; ?>">
<?php echo esc_html($category->name); ?>
</button>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<!-- 案例内容区域 -->
<div class="cases-content-wrapper">
<?php if ($show_tabs && !empty($categories)): ?>
<div class="tab-content" id="<?php echo esc_attr($unique_id); ?>-tabContent">
<?php foreach ($categories as $index => $category): ?>
<div class="tab-panel <?php echo ($index === 0 || $category->slug === $default_category) ? 'active' : ''; ?>"
id="content-<?php echo esc_attr($category->slug); ?>"
role="tabpanel"
aria-labelledby="tab-<?php echo esc_attr($category->slug); ?>">
<div class="cases-grid-container" data-category="<?php echo esc_attr($category->slug); ?>">
<!-- 案例网格将通过AJAX加载 -->
<div class="cases-loading">
<div class="loading-spinner" role="status">
<span class="loading-text">Loading...</span>
</div>
</div>
</div>
<?php if ($show_pagination): ?>
<div class="cases-pagination-wrapper" data-category="<?php echo esc_attr($category->slug); ?>">
<!-- 分页将通过AJAX加载 -->
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<!-- 不显示选项卡时,显示所有案例 -->
<div class="cases-grid-container" data-category="all">
<div class="cases-loading">
<div class="loading-spinner" role="status">
<span class="loading-text">Loading...</span>
</div>
</div>
</div>
<?php if ($show_pagination): ?>
<div class="cases-pagination-wrapper" data-category="all">
<!-- 分页将通过AJAX加载 -->
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
</section>
<!-- 案例展示样式 -->
<style>
.nenghui-cases-section {
width: 100%;
padding: 80px 0;
<?php if ($background_type === 'color'): ?>
background-color: <?php echo esc_attr($background_color); ?>;
<?php elseif ($background_type === 'image' && !empty($background_image)): ?>
background-image: url('<?php echo esc_url($background_image); ?>');
background-position: <?php echo esc_attr($background_position); ?>;
background-size: <?php echo esc_attr($background_size); ?>;
background-repeat: <?php echo esc_attr($background_repeat); ?>;
background-attachment: fixed;
<?php else: ?>
background-color: <?php echo esc_attr($background_color); ?>;
<?php endif; ?>
}
.cases-background-video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -2;
}
.cases-video-fallback {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -1;
display: none;
}
.cases-background-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: <?php echo esc_attr($background_overlay_color); ?>;
opacity: <?php echo esc_attr($background_overlay_opacity); ?>;
z-index: -1;
}
/* 响应式设计 */
@media (max-width: 768px) {
.cases-section {
<?php if ($background_type === 'image' && !empty($background_image)): ?>
background-attachment: scroll;
<?php endif; ?>
}
.cases-background-video {
object-fit: cover;
object-position: center;
}
}
/* 减少动画模式支持 */
@media (prefers-reduced-motion: reduce) {
.cases-background-video {
animation: none;
}
}
.nenghui-cases-section .container {
width: 80%;
max-width: none;
margin: 0 auto;
padding: 0 20px;
}
.nenghui-cases-section .section-title {
font-size: 2.5rem;
text-align: center;
font-weight: 700;
color: #2c3e50;
margin-bottom: 3rem;
position: relative;
}
.nenghui-cases-section .section-title::after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 3px;
background: linear-gradient(135deg, #2cb5a9, #00699f);
border-radius: 2px;
}
/* 选项卡样式 */
.cases-tabs {
display: flex;
justify-content: center;
align-items: center;
list-style: none;
margin: 0 0 2rem 0;
padding: 0;
padding-bottom: 25px;
border-bottom: 2px solid #e9ecef;
}
.cases-tabs .tab-item {
margin: 0 8px;
}
.cases-tabs .tab-link {
background: transparent;
border: 2px solid transparent;
color: #6c757d;
font-weight: 600;
padding: 12px 24px;
border-radius: 25px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
cursor: pointer;
font-size: 1rem;
text-decoration: none;
display: inline-block;
}
.cases-tabs .tab-link:hover {
border-color: #2cb5a9;
color: #2cb5a9;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(44, 181, 169, 0.2);
transition: all 0.3s ease;
}
.cases-tabs .tab-link.active {
background: linear-gradient(135deg, #2cb5a9, #00699f);
border-color: #2cb5a9;
color: #fff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(44, 181, 169, 0.3);
}
.cases-tabs .tab-link::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.cases-tabs .tab-link:hover::before {
left: 100%;
transition: all 0.3s ease;
}
/* 选项卡内容面板 */
.tab-content {
position: relative;
}
.tab-panel {
display: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.tab-panel.active {
display: block;
opacity: 1;
}
/* 加载动画样式 */
.cases-loading {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 3rem 0;
}
.loading-spinner {
display: inline-block;
width: 40px;
height: 40px;
border: 3px solid #f3f3f3;
border-top: 3px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-text {
display: none;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 案例网格样式 */
.cases-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 30px;
margin-bottom: 2rem;
}
.case-card {
background: white;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
transition: all 0.3s ease;
position: relative;
height: 100%;
display: flex;
flex-direction: column;
}
.case-card:hover {
transform: translateY(-10px);
box-shadow: 0 15px 40px rgba(0,0,0,0.15);
transition: all 0.3s ease;
}
.case-card-image {
position: relative;
overflow: hidden;
height: 250px;
}
.case-card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.case-card:hover .case-card-image img {
transform: scale(1.1);
transition: all 0.3s ease;
}
.case-card-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, rgba(46,182,170,0.5), rgba(0,105,160,0.5));
opacity: 0;
transition: opacity 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.case-card-overlay>a{
color: #fff!important;
}
.case-card:hover .case-card-overlay {
opacity: 1;
}
.case-card-content {
padding: 25px;
flex-grow: 1;
display: flex;
flex-direction: column;
}
.case-card-title {
font-size: 1.25rem;
font-weight: 700;
color: #2c3e50;
margin-bottom: 15px;
line-height: 1.4;
}
.case-card-description {
color: #6c757d;
line-height: 1.6;
margin-bottom: 20px;
flex-grow: 1;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.case-card-footer {
margin-top: auto;
}
.case-read-more {
display: inline-flex;
align-items: center;
color: #007bff;
text-decoration: none;
font-weight: 600;
transition: all 0.3s ease;
position: relative;
}
.case-read-more:hover {
color: #0056b3;
transform: translateX(5px);
}
.case-read-more::after {
content: '→';
margin-left: 8px;
transition: transform 0.3s ease;
}
.case-read-more:hover::after {
transform: translateX(5px);
}
/* 分页样式 */
.cases-pagination-wrapper {
margin-top: 2rem;
}
.cases-pagination {
display: flex;
justify-content: center;
align-items: center;
margin-top: 3rem;
}
.cases-pagination .page-numbers {
display: inline-flex;
align-items: center;
justify-content: center;
width: 45px;
height: 45px;
margin: 0 5px;
background: white;
border: 2px solid #e9ecef;
color: #6c757d;
text-decoration: none;
border-radius: 50%;
font-weight: 600;
transition: all 0.3s ease;
}
.cases-pagination .page-numbers:hover,
.cases-pagination .page-numbers.current {
background: #007bff;
border-color: #007bff;
color: white;
transform: scale(1.1);
}
.cases-pagination .page-numbers.dots {
border: none;
background: transparent;
cursor: default;
}
.cases-pagination .page-numbers.dots:hover {
transform: none;
background: transparent;
color: #6c757d;
}
/* 加载动画 */
.cases-loading {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.cases-grid {
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 25px;
}
}
@media (max-width: 768px) {
.nenghui-cases-section {
padding: 60px 0;
}
.nenghui-cases-section .section-title {
font-size: 2rem;
}
.cases-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.cases-tabs {
flex-wrap: wrap;
justify-content: center;
}
.cases-tabs .tab-item {
margin: 4px;
}
.cases-tabs .tab-link {
padding: 10px 16px;
font-size: 0.9rem;
}
.case-card-content {
padding: 20px;
}
}
@media (max-width: 576px) {
.cases-tabs {
flex-wrap: wrap;
padding: 0 1rem;
}
.cases-tabs .tab-item {
margin: 4px 2px;
}
.cases-tabs .tab-link {
padding: 8px 12px;
font-size: 0.85rem;
}
.case-card-image {
height: 200px;
}
.cases-loading {
min-height: 200px;
padding: 2rem 0;
}
}
/* 动画效果 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.animate-on-scroll {
opacity: 0;
animation: fadeInUp 0.6s ease forwards;
}
.animate-on-scroll[data-delay="200"] {
animation-delay: 0.2s;
}
.animate-on-scroll[data-delay="400"] {
animation-delay: 0.4s;
}
.case-card {
animation: fadeIn 0.6s ease forwards;
}
</style>
<!-- 案例展示JavaScript -->
<script>
// 等待 jQuery 加载完成
if (typeof jQuery !== 'undefined') {
jQuery(document).ready(function($) {
var casesData = {
postsPerPage: <?php echo $posts_per_page; ?>,
columns: <?php echo $columns; ?>,
showPagination: <?php echo $show_pagination ? 'true' : 'false'; ?>,
showTabs: <?php echo $show_tabs ? 'true' : 'false'; ?>,
defaultCategory: '<?php echo esc_js($default_category); ?>',
uniqueId: '<?php echo esc_js($unique_id); ?>',
nonce: '<?php echo wp_create_nonce('load_cases_nonce'); ?>'
};
// 初始化案例展示
initCasesDisplay();
function initCasesDisplay() {
// 如果显示选项卡,加载默认分类的案例
if (casesData.showTabs) {
var defaultTab = $('.cases-tabs .tab-link.active');
var defaultCategory = defaultTab.data('category');
loadCases(defaultCategory, 1);
// 绑定选项卡切换事件
$('.cases-tabs .tab-link').on('click', function() {
// 移除所有活动状态
$('.cases-tabs .tab-link').removeClass('active');
$('.tab-panel').removeClass('active');
// 添加当前活动状态
$(this).addClass('active');
var category = $(this).data('category');
$('#content-' + category).addClass('active');
// 加载案例数据
loadCases(category, 1);
});
} else {
// 不显示选项卡时,加载所有案例
loadCases('all', 1);
}
}
function loadCases(category, page) {
var container = $('.cases-grid-container[data-category="' + category + '"]');
var paginationContainer = $('.cases-pagination-wrapper[data-category="' + category + '"]');
// 显示加载动画
container.html('<div class="cases-loading"><div class="loading-spinner" role="status"><span class="loading-text">Loading...</span></div></div>');
// AJAX请求加载案例
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'load_cases',
nonce: casesData.nonce,
category: category,
page: page,
posts_per_page: casesData.postsPerPage,
columns: casesData.columns,
show_pagination: casesData.showPagination
},
success: function(response) {
if (response.success) {
// 更新案例网格
container.html(response.data.html);
// 更新分页
if (casesData.showPagination && response.data.pagination) {
paginationContainer.html(response.data.pagination);
// 绑定分页点击事件
paginationContainer.find('.page-numbers').on('click', function(e) {
e.preventDefault();
var pageNum = $(this).text();
if ($(this).hasClass('next')) {
pageNum = parseInt($('.page-numbers.current').text()) + 1;
} else if ($(this).hasClass('prev')) {
pageNum = parseInt($('.page-numbers.current').text()) - 1;
}
if (!isNaN(pageNum)) {
loadCases(category, pageNum);
}
});
} else {
paginationContainer.empty();
}
// 触发动画
setTimeout(function() {
container.find('.case-card').each(function(index) {
$(this).css('animation-delay', (index * 100) + 'ms');
});
}, 100);
} else {
container.html('<div class="cases-loading"><p style="color: #6c757d; text-align: center;">暂无案例数据</p></div>');
paginationContainer.empty();
}
},
error: function() {
container.html('<div class="cases-loading"><p style="color: #dc3545; text-align: center;">加载失败,请稍后重试</p></div>');
paginationContainer.empty();
}
});
}
});
// 处理背景视频事件
function initCasesVideoEvents() {
const videos = document.querySelectorAll('.cases-background-video');
videos.forEach(video => {
const fallbackImg = video.querySelector('.cases-video-fallback');
// 视频加载错误时显示备用图片
video.addEventListener('error', function() {
if (fallbackImg) {
fallbackImg.style.display = 'block';
video.style.display = 'none';
}
});
// 视频加载成功时隐藏备用图片
video.addEventListener('loadeddata', function() {
if (fallbackImg) {
fallbackImg.style.display = 'none';
}
});
// 确保视频循环播放
video.addEventListener('ended', function() {
video.currentTime = 0;
video.play();
});
});
}
// 初始化视频事件
initCasesVideoEvents();
} else {
// 如果 jQuery 未加载,等待加载
document.addEventListener('DOMContentLoaded', function() {
var checkJQuery = setInterval(function() {
if (typeof jQuery !== 'undefined') {
clearInterval(checkJQuery);
jQuery(document).ready(function($) {
// 重复上面的初始化代码
initCasesDisplayFallback($);
});
}
}, 100);
});
}
function initCasesDisplayFallback($) {
var casesData = {
postsPerPage: <?php echo $posts_per_page; ?>,
columns: <?php echo $columns; ?>,
showPagination: <?php echo $show_pagination ? 'true' : 'false'; ?>,
showTabs: <?php echo $show_tabs ? 'true' : 'false'; ?>,
defaultCategory: '<?php echo esc_js($default_category); ?>',
uniqueId: '<?php echo esc_js($unique_id); ?>'
};
// 初始化案例展示
initCasesDisplay();
function initCasesDisplay() {
// 如果显示选项卡,加载默认分类的案例
if (casesData.showTabs) {
var defaultTab = $('.cases-tabs .tab-link.active');
var defaultCategory = defaultTab.data('category');
loadCases(defaultCategory, 1);
// 绑定选项卡切换事件
$('.cases-tabs .tab-link').on('click', function() {
// 移除所有活动状态
$('.cases-tabs .tab-link').removeClass('active');
$('.tab-panel').removeClass('active');
// 添加当前活动状态
$(this).addClass('active');
var category = $(this).data('category');
$('#content-' + category).addClass('active');
// 加载案例数据
loadCases(category, 1);
});
} else {
// 不显示选项卡时,加载所有案例
loadCases('all', 1);
}
}
function loadCases(category, page) {
var container = $('.cases-grid-container[data-category="' + category + '"]');
var paginationContainer = $('.cases-pagination-wrapper[data-category="' + category + '"]');
// 显示加载动画
container.html('<div class="cases-loading"><div class="loading-spinner" role="status"><span class="loading-text">Loading...</span></div></div>');
// AJAX请求加载案例
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'load_cases',
category: category,
page: page,
posts_per_page: casesData.postsPerPage,
columns: casesData.columns,
show_pagination: casesData.showPagination
},
success: function(response) {
if (response.success) {
// 更新案例网格
container.html(response.data.html);
// 更新分页
if (casesData.showPagination && response.data.pagination) {
paginationContainer.html(response.data.pagination);
// 绑定分页点击事件
paginationContainer.find('.page-numbers').on('click', function(e) {
e.preventDefault();
var pageNum = $(this).text();
if ($(this).hasClass('next')) {
pageNum = parseInt($('.page-numbers.current').text()) + 1;
} else if ($(this).hasClass('prev')) {
pageNum = parseInt($('.page-numbers.current').text()) - 1;
}
if (!isNaN(pageNum)) {
loadCases(category, pageNum);
}
});
} else {
paginationContainer.empty();
}
// 触发动画
setTimeout(function() {
container.find('.case-card').each(function(index) {
$(this).css('animation-delay', (index * 100) + 'ms');
});
}, 100);
} else {
container.html('<div class="cases-loading"><p style="color: #6c757d; text-align: center;">暂无案例数据</p></div>');
paginationContainer.empty();
}
},
error: function() {
container.html('<div class="cases-loading"><p style="color: #dc3545; text-align: center;">加载失败,请稍后重试</p></div>');
paginationContainer.empty();
}
});
}
}
</script>