Comience su viaje transfronterizo
Póngase en contacto con nosotros

Servicio de atención al cliente

Atención al cliente

Tablones de anuncios personalizados de WordPress, puede personalizar varios tablones de anuncios para que roten automáticamente y establecer un temporizador de cuenta atrás, que luego se puede añadir en la navegación del menú backend.
add_action('init', function() {
register_post_type('announcement_bar', [
'labels' => [
'name' => '公告栏',
'add_new_item' => '添加新公告',
'edit_item' => '编辑公告',
],
'public' => false,
'show_ui' => true,
'menu_icon' => 'dashicons-megaphone',
'supports' => ['title', 'page-attributes'],
]);
});
add_action('add_meta_boxes', function() {
add_meta_box('announcement_fields', '公告设置', function($post) {
$meta = get_post_meta($post->ID);
$val = function($key, $default = '') use ($meta) {
return isset($meta[$key][0]) ? esc_attr($meta[$key][0]) : $default;
};
?>
<p><label>链接地址:<input type="url" name="link" value="<?php echo $val('link'); ?>" style="width:100%"></label></p>
<p><label><input type="checkbox" name="enable_timer" value="1" <?php checked($val('enable_timer'), '1'); ?>> 启用倒计时</label></p>
<p><label>倒计时目标时间:<input type="datetime-local" name="timer_end" value="<?php echo $val('timer_end'); ?>"></label></p>
<?php
}, 'announcement_bar');
});
add_action('save_post', function($post_id) {
if (get_post_type($post_id) !== 'announcement_bar') return;
foreach (['link', 'timer_end'] as $field) {
if (isset($_POST[$field])) update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
update_post_meta($post_id, 'enable_timer', isset($_POST['enable_timer']) ? '1' : '0');
});
add_action('admin_menu', function() {
add_submenu_page(
'edit.php?post_type=announcement_bar',
'公告栏全局设置',
'公告栏设置',
'manage_options',
'announcement_bar_options',
function() {
if ($_POST && current_user_can('manage_options')) {
update_option('announcement_bar_enabled', isset($_POST['enabled']) ? 1 : 0);
update_option('announcement_bar_autoplay', isset($_POST['autoplay']) ? 1 : 0);
update_option('announcement_bar_interval', intval($_POST['interval']));
update_option('announcement_bar_bg', sanitize_hex_color($_POST['bg']));
update_option('announcement_bar_text', sanitize_hex_color($_POST['text']));
update_option('announcement_bar_timerbg', sanitize_hex_color($_POST['timerbg']));
update_option('announcement_bar_timertext', sanitize_hex_color($_POST['timertext']));
echo '<div class="updated"><p>设置已保存!</p></div>';
}
$bg = esc_attr(get_option('announcement_bar_bg', '#222222'));
$text = esc_attr(get_option('announcement_bar_text', '#ffffff'));
$timerbg = esc_attr(get_option('announcement_bar_timerbg', '#ff4444'));
$timertext = esc_attr(get_option('announcement_bar_timertext', '#ffffff'));
?>
<div class="wrap">
<h2>公告栏全局设置</h2>
<form method="post">
<table class="form-table">
<tr>
<th><label>启用公告栏</label></th>
<td><input type="checkbox" name="enabled" value="1" <?php checked(get_option('announcement_bar_enabled'), 1); ?>></td>
</tr>
<tr>
<th><label>启用轮播(所有设备)</label></th>
<td><input type="checkbox" name="autoplay" value="1" <?php checked(get_option('announcement_bar_autoplay'), 1); ?>></td>
</tr>
<tr>
<th><label>轮播间隔(毫秒)</label></th>
<td><input type="number" name="interval" value="<?php echo esc_attr(get_option('announcement_bar_interval', 5000)); ?>" min="1000" step="500"></td>
</tr>
<tr>
<th><label>背景颜色</label></th>
<td>
<input type="color" id="bg_color_picker" value="<?php echo $bg; ?>">
<input type="text" name="bg" id="bg_color_text" value="<?php echo $bg; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>字体颜色</label></th>
<td>
<input type="color" id="text_color_picker" value="<?php echo $text; ?>">
<input type="text" name="text" id="text_color_text" value="<?php echo $text; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>倒计时背景颜色</label></th>
<td>
<input type="color" id="timerbg_color_picker" value="<?php echo $timerbg; ?>">
<input type="text" name="timerbg" id="timerbg_color_text" value="<?php echo $timerbg; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>倒计时字体颜色</label></th>
<td>
<input type="color" id="timertext_color_picker" value="<?php echo $timertext; ?>">
<input type="text" name="timertext" id="timertext_color_text" value="<?php echo $timertext; ?>" style="width:100px;">
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded',function(){
var bgPicker=document.getElementById('bg_color_picker');
var bgText=document.getElementById('bg_color_text');
var textPicker=document.getElementById('text_color_picker');
var textText=document.getElementById('text_color_text');
var timerbgPicker=document.getElementById('timerbg_color_picker');
var timerbgText=document.getElementById('timerbg_color_text');
var timertextPicker=document.getElementById('timertext_color_picker');
var timertextText=document.getElementById('timertext_color_text');
if(bgPicker&&bgText){
bgPicker.addEventListener('input',function(){bgText.value=bgPicker.value;});
bgText.addEventListener('input',function(){bgPicker.value=bgText.value;});
}
if(textPicker&&textText){
textPicker.addEventListener('input',function(){textText.value=textPicker.value;});
textText.addEventListener('input',function(){textPicker.value=textText.value;});
}
if(timerbgPicker&&timerbgText){
timerbgPicker.addEventListener('input',function(){timerbgText.value=timerbgPicker.value;});
timerbgText.addEventListener('input',function(){timerbgPicker.value=timerbgText.value;});
}
if(timertextPicker&&timertextText){
timertextPicker.addEventListener('input',function(){timertextText.value=timertextPicker.value;});
timertextText.addEventListener('input',function(){timertextPicker.value=timertextText.value;});
}
});
</script>
<?php
}
);
});
add_action('wp_body_open', function() {
if (!get_option('announcement_bar_enabled')) return;
$bg_color = get_option('announcement_bar_bg', '#222222');
$text_color = get_option('announcement_bar_text', '#ffffff');
$timerbg = get_option('announcement_bar_timerbg', '#ff4444');
$timertext = get_option('announcement_bar_timertext', '#ffffff');
$autoplay = get_option('announcement_bar_autoplay') ? 'true' : '0';
$interval = intval(get_option('announcement_bar_interval', 5000));
$posts = get_posts([
'post_type' => 'announcement_bar',
'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
'numberposts' => -1
]);
if (!$posts) return;
echo '<div class="announcement-bar-swiper"><div class="swiper-wrapper">';
foreach ($posts as $post) {
$link = get_post_meta($post->ID, 'link', true);
$text = esc_html($post->post_title);
$enable_timer = get_post_meta($post->ID, 'enable_timer', true);
$timer_end = get_post_meta($post->ID, 'timer_end', true);
echo '<div class="swiper-slide bar-has-timer" style="color:'.$text_color.';background:'.$bg_color.';font-weight:bold;">';
echo '<div class="bar-center-wrap">';
echo '<span class="bar-main">'.($link ? '<a href="'.esc_url($link).'">'.$text.'</a>' : $text).'</span>';
if ($enable_timer && $timer_end) {
echo '<span class="bar-countdown" data-end="'.esc_attr($timer_end).'" data-bg="'.esc_attr($timerbg).'" data-txt="'.esc_attr($timertext).'"></span>';
}
echo '</div>';
echo '</div>';
}
echo '</div></div>';
});
add_action('wp_footer', function() {
$interval = intval(get_option('announcement_bar_interval', 5000));
$autoplay = get_option('announcement_bar_autoplay') ? 'true' : '0';
?>
<style>
.announcement-bar-swiper {
font-size: 14px; position: relative; overflow: hidden; z-index: 9999;
width: 100vw; max-width: 100vw;
}
.announcement-bar-swiper .swiper-wrapper { display: flex;}
.announcement-bar-swiper .swiper-slide {
display: flex; justify-content: center; align-items: center;
padding: 10px 20px; font-weight: bold; color: inherit;
white-space: normal; word-break: break-all;
font-size: 14px; box-sizing: border-box;
width: 100vw !important; max-width: 100vw; min-width: 100vw;
}
.announcement-bar-swiper .bar-center-wrap {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
}
.announcement-bar-swiper .bar-main { display: inline-block; }
.announcement-bar-swiper .swiper-slide * { color: inherit !important; font-size: inherit !important;}
.announcement-bar-swiper a { color: inherit !important; text-decoration: none;}
.announcement-bar-swiper .bar-countdown {
display: inline-flex;
align-items: center;
gap: 6px;
margin-left: 0;
line-height: 1;
}
.announcement-bar-swiper .bar-countdown .time-num {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 32px;
padding: 2px 8px;
border-radius: 0; /* 去掉圆角 */
font-family: monospace;
font-weight: bold;
font-size: inherit;
}
.announcement-bar-swiper .bar-countdown .time-label {
margin: 0 2px;
font-family: inherit;
background: none !important;
padding: 0;
min-width: unset;
border-radius: 0;
}
@media (max-width: 767.98px) {
.announcement-bar-swiper { padding-left:0; padding-right:0;}
.announcement-bar-swiper .swiper-wrapper {
display: flex !important;
flex-direction: row !important;
width: 100vw;
}
.announcement-bar-swiper .swiper-slide {
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 0 !important;
box-sizing: border-box;
padding-left: 20px !important;
padding-right: 20px !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 !important;
}
.announcement-bar-swiper .bar-center-wrap {
width: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.announcement-bar-swiper .bar-main {
width:100%;
justify-content:center;
text-align: center;
padding-bottom: 0;
}
.announcement-bar-swiper .bar-countdown {
width: 100%;
margin: 0;
justify-content: center;
margin-bottom: 0;
}
}
@media (min-width: 768px) {
.announcement-bar-swiper .swiper-wrapper { display: flex;}
.announcement-bar-swiper .swiper-slide {flex-direction: row !important;}
.announcement-bar-swiper .bar-countdown {margin-left:10px;margin-top:0;}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var autoplay = <?php echo $autoplay; ?>;
var interval = <?php echo $interval; ?>;
if (typeof Swiper !== 'undefined') {
new Swiper('.announcement-bar-swiper', {
loop: false,
autoplay: autoplay ? { delay: interval } : false,
slidesPerView: 1,
centeredSlides: false,
spaceBetween: 0,
});
}
document.querySelectorAll('.bar-countdown').forEach(function(el){
const end = new Date(el.dataset.end).getTime();
const bg = el.dataset.bg || '#ff4444';
const txt = el.dataset.txt || '#fff';
function render(left){
const d = Math.floor(left / (1000*60*60*24));
const h = Math.floor((left / (1000*60*60)) % 24);
const m = Math.floor((left / (1000*60)) % 60);
const s = Math.floor((left / 1000) % 60);
el.innerHTML =
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(d).padStart(2,'0')+'</span>' +
'<span class="time-label">D</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(h).padStart(2,'0')+'</span>' +
'<span class="time-label">:</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(m).padStart(2,'0')+'</span>' +
'<span class="time-label">:</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(s).padStart(2,'0')+'</span>';
}
function update(){
const now = new Date().getTime();
const left = Math.max(0, end - now);
render(left);
}
update();
setInterval(update, 1000);
});
});
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
<?php
});