// Live Float Button and Modal JavaScript
let currentLiveStream = null; // 当前直播源数据
$(document).ready(function() {
initLiveFloat();
});
let liveStatsInterval = null;
let randomMessageInterval = null;
let floatViewersInterval = null;
let danmakuInterval = null;
function initLiveFloat() {
// 先加载直播源数据
loadLiveStreamData();
bindLiveFloatEvents();
// 监听语言切换
$(document).on('languageChanged', function() {
if ($('#liveModal').hasClass('active')) {
loadChatMessages();
loadLiveProducts();
}
});
}
// 加载直播源数据
function loadLiveStreamData() {
LiveStreamAPI.getActiveLiveStreams()
.then(data => {
if (data && data.length > 0) {
// 获取第一个有stream_url的直播源
currentLiveStream = data.find(stream => stream.stream_url);
if (currentLiveStream) {
// 有直播源,显示浮窗并更新数据
updateFloatButton(currentLiveStream);
$('#liveFloatBtn').show();
// 启动悬浮窗观看人数动态更新
updateFloatViewers();
floatViewersInterval = setInterval(updateFloatViewers, 3000);
} else {
// 没有可用的直播源,显示未开播
showOfflineFloat();
}
} else {
// 没有直播源数据,显示未开播
showOfflineFloat();
}
})
.catch(error => {
console.error('加载直播源失败:', error);
// 加载失败,隐藏浮窗
$('#liveFloatBtn').hide();
});
}
// 更新浮窗按钮数据
function updateFloatButton(stream) {
// 更新标题
$('.live-float-title').text(stream.title);
// 更新平台名称
$('.live-float-name').text(stream.platform + '官方直播');
// 如果有封面图,更新封面
if (stream.cover_image) {
const $video = $('.live-float-video');
$video.replaceWith(`
`);
}
}
// 显示未开播状态
function showOfflineFloat() {
$('#liveFloatBtn').show().addClass('offline');
// 移除LIVE徽章
$('.live-float-badge-top').html(`
未开播
`);
// 更新标题
$('.live-float-title').text('暂未开播');
$('.live-float-name').text('敬请期待');
$('.live-float-desc').text('主播休息中...');
// 清除定时器
if (floatViewersInterval) {
clearInterval(floatViewersInterval);
floatViewersInterval = null;
}
}
// 绑定事件
function bindLiveFloatEvents() {
// 点击悬浮按钮打开直播
$('#liveFloatBtn').on('click', function() {
if (currentLiveStream && currentLiveStream.stream_url) {
// 有直播源,打开直播弹窗
openLiveModal();
} else {
// 未开播,显示提示
if (typeof Toast !== 'undefined') {
Toast.show('直播暂未开始,敬请期待', 'info');
} else {
alert('直播暂未开始,敬请期待');
}
}
});
// 点击关闭按钮
$('#liveModalClose').on('click', function() {
closeLiveModal();
});
// 点击模态框背景关闭
$('#liveModal').on('click', function(e) {
if (e.target.id === 'liveModal') {
closeLiveModal();
}
});
// Tab切换
$('.tab-btn').on('click', function() {
const tabName = $(this).data('tab');
switchTab(tabName);
});
// 点赞按钮
$('#likeBtn').on('click', function() {
handleLike();
});
// 发送消息
$('#sendMessageBtn').on('click', function() {
sendMessage();
});
$('#chatInput').on('keypress', function(e) {
if (e.which === 13) {
sendMessage();
}
});
// 产品点击
$(document).on('click', '.live-product-item', function() {
const productId = $(this).data('product-id');
// 关闭直播窗口并跳转到商品详情
closeLiveModal();
setTimeout(() => {
window.location.href = `product-detail.html?id=${productId}`;
}, 300);
});
$(document).on('click', '.live-product-btn', function(e) {
e.stopPropagation();
const productId = $(this).closest('.live-product-item').data('product-id');
addProductToCart(productId);
});
}
// 打开直播模态框
function openLiveModal() {
if (!currentLiveStream || !currentLiveStream.stream_url) {
if (typeof Toast !== 'undefined') {
Toast.show('直播暂未开始,敬请期待', 'info');
} else {
alert('直播暂未开始,敬请期待');
}
return;
}
$('#liveModal').addClass('active');
$('body').css('overflow', 'hidden');
// 更新主播信息
$('#liveHostName').text(currentLiveStream.title);
$('#liveViewerCount').text(formatViewCount(currentLiveStream.view_count || 1234));
// 显示并绑定跳转按钮
const $gotoBtn = $('#gotoPlatformBtnTop');
$('#platformNameTop').text(currentLiveStream.platform);
$gotoBtn.show().off('click').on('click', function() {
window.open(currentLiveStream.stream_url, '_blank');
});
// 更新视频源
const videoContainer = $('.live-video-container');
videoContainer.html(`
${currentLiveStream.title}
${formatViewCount(currentLiveStream.view_count || 1234)} 人在线
`);
// 绑定点赞按钮
$('#likeBtn').on('click', function() {
handleLike();
});
// 增加观看次数
LiveStreamAPI.incrementViewCount(currentLiveStream.id)
.then(() => {
console.log('观看次数已增加');
})
.catch(error => {
console.error('增加观看次数失败:', error);
});
// 加载内容
loadChatMessages();
loadLiveProducts();
// 开始定时更新
randomMessageInterval = setInterval(addRandomMessage, 10000);
danmakuInterval = setInterval(addRandomDanmaku, 3000);
}
// 格式化观看人数
function formatViewCount(count) {
if (!count || count === 0) return '0';
if (count < 1000) return count.toString();
if (count < 10000) return (count / 1000).toFixed(1) + 'K';
return (count / 10000).toFixed(1) + 'W';
}
// 关闭直播模态框
function closeLiveModal() {
$('#liveModal').removeClass('active');
$('body').css('overflow', '');
// 恢复原始视频容器结构(移除controls属性)
const videoContainer = $('.live-video-container');
videoContainer.html(`
🔴 直播中
`);
// 清除定时器
if (liveStatsInterval) {
clearInterval(liveStatsInterval);
liveStatsInterval = null;
}
if (randomMessageInterval) {
clearInterval(randomMessageInterval);
randomMessageInterval = null;
}
if (danmakuInterval) {
clearInterval(danmakuInterval);
danmakuInterval = null;
}
// 清除弹幕
$('#danmakuContainer').empty();
}
// Tab切换
function switchTab(tabName) {
$('.tab-btn').removeClass('active');
$(`.tab-btn[data-tab="${tabName}"]`).addClass('active');
$('.tab-content').removeClass('active');
$(`#${tabName}Tab`).addClass('active');
}
// 加载聊天消息
function loadChatMessages() {
const lang = i18n.currentLang;
const messages = [
{
type: 'system',
text: lang === 'zh-CN' ? '欢迎来到直播间!' :
lang === 'en-US' ? 'Welcome to the live stream!' :
'ライブ配信へようこそ!',
time: '10:00'
},
{
username: lang === 'zh-CN' ? '小明' : lang === 'en-US' ? 'Mike' : 'タロウ',
text: lang === 'zh-CN' ? '这款拼图看起来很不错!' :
lang === 'en-US' ? 'This puzzle looks great!' :
'このパズルは素晴らしいですね!',
time: '10:05'
},
{
username: lang === 'zh-CN' ? '小红' : lang === 'en-US' ? 'Lucy' : 'ハナコ',
text: lang === 'zh-CN' ? '适合多大年龄的孩子?' :
lang === 'en-US' ? 'What age is it suitable for?' :
'何歳の子供に適していますか?',
time: '10:06'
},
{
username: lang === 'zh-CN' ? '主播' : lang === 'en-US' ? 'Host' : 'ホスト',
text: lang === 'zh-CN' ? '这款拼图适合3-6岁的孩子,可以培养动手能力和空间想象力!' :
lang === 'en-US' ? 'This puzzle is suitable for children aged 3-6 and helps develop hands-on skills and spatial imagination!' :
'このパズルは3〜6歳の子供に適しており、実践的なスキルと空間想像力を養うのに役立ちます!',
time: '10:07'
},
{
username: lang === 'zh-CN' ? '李华' : lang === 'en-US' ? 'David' : 'ダビデ',
text: lang === 'zh-CN' ? '价格很优惠,已经下单了!' :
lang === 'en-US' ? 'Great price, just ordered!' :
'価格もお得で、注文しました!',
time: '10:08'
},
{
username: lang === 'zh-CN' ? '王芳' : lang === 'en-US' ? 'Sarah' : 'サラ',
text: lang === 'zh-CN' ? '材质安全吗?' :
lang === 'en-US' ? 'Is the material safe?' :
'素材は安全ですか?',
time: '10:09'
},
{
username: lang === 'zh-CN' ? '主播' : lang === 'en-US' ? 'Host' : 'ホスト',
text: lang === 'zh-CN' ? '所有产品都通过了安全认证,使用环保材料,家长可以放心!' :
lang === 'en-US' ? 'All products are safety certified and made from eco-friendly materials. Parents can rest assured!' :
'すべての製品は安全認証を受けており、環境に優しい素材を使用しています。親御さんも安心です!',
time: '10:10'
}
];
let chatHtml = '';
messages.forEach(msg => {
if (msg.type === 'system') {
chatHtml += `
`;
} else {
chatHtml += `
`;
}
});
$('#chatMessages').html(chatHtml);
scrollChatToBottom();
}
// 加载直播商品
function loadLiveProducts() {
const lang = i18n.currentLang;
const products = [
{
id: 1,
name: '200片拼图 - 海洋世界',
name_en: '200 Piece Puzzle - Ocean World',
name_ja: '200ピースパズル - 海の世界',
price: 19.99,
originalPrice: 29.99,
image: 'https://picsum.photos/200/200?random=live1'
},
{
id: 2,
name: '艺术绘画套装',
name_en: 'Art Painting Set',
name_ja: 'アート絵画セット',
price: 24.99,
originalPrice: 34.99,
image: 'https://picsum.photos/200/200?random=live2'
},
{
id: 3,
name: '木质积木 - 100块',
name_en: 'Wooden Blocks - 100 Pieces',
name_ja: '木製ブロック - 100ピース',
price: 29.99,
originalPrice: 39.99,
image: 'https://picsum.photos/200/200?random=live3'
},
{
id: 4,
name: '磁力片建构玩具',
name_en: 'Magnetic Building Tiles',
name_ja: 'マグネットタイル',
price: 34.99,
originalPrice: 49.99,
image: 'https://picsum.photos/200/200?random=live4'
},
{
id: 5,
name: '儿童桌游套装',
name_en: 'Kids Board Game Set',
name_ja: '子供用ボードゲームセット',
price: 27.99,
originalPrice: 37.99,
image: 'https://picsum.photos/200/200?random=live5'
},
{
id: 6,
name: '手工贴纸书',
name_en: 'Sticker Activity Book',
name_ja: 'ステッカーブック',
price: 12.99,
originalPrice: 18.99,
image: 'https://picsum.photos/200/200?random=live6'
}
];
let productsHtml = '';
products.forEach(product => {
const productName = lang === 'zh-CN' ? product.name :
lang === 'en-US' ? product.name_en :
product.name_ja;
const btnText = i18n.t('add_to_cart');
productsHtml += `
${productName}
$${product.price.toFixed(2)}
$${product.originalPrice.toFixed(2)}
`;
});
$('#liveProducts').html(productsHtml);
}
// 更新直播统计
function updateLiveStats() {
const currentViewers = parseInt($('#viewerCount').text().replace(/,/g, ''));
const currentLikes = parseInt($('#likeCount').text().replace(/,/g, ''));
const currentMessages = parseInt($('#messageCount').text().replace(/,/g, ''));
// 随机增加数值
const newViewers = currentViewers + Math.floor(Math.random() * 20) - 5;
const newLikes = currentLikes + Math.floor(Math.random() * 15);
const newMessages = currentMessages + Math.floor(Math.random() * 5);
$('#viewerCount').text(Math.max(1000, newViewers).toLocaleString());
$('#likeCount').text(Math.max(500, newLikes).toLocaleString());
$('#messageCount').text(Math.max(50, newMessages).toLocaleString());
}
// 发送消息
function sendMessage() {
const message = $('#chatInput').val().trim();
if (!message) {
return;
}
const lang = i18n.currentLang;
const username = lang === 'zh-CN' ? '我' : lang === 'en-US' ? 'Me' : '私';
const currentTime = new Date();
const timeString = `${currentTime.getHours()}:${currentTime.getMinutes().toString().padStart(2, '0')}`;
// 添加到聊天记录
const messageHtml = `
`;
$('#chatMessages').append(messageHtml);
// 如果开启了弹幕,也显示在弹幕区
if ($('#danmakuToggle').is(':checked')) {
createDanmaku(message);
}
$('#chatInput').val('');
scrollChatToBottom();
// 更新消息计数
const currentCount = parseInt($('#messageCount').text().replace(/,/g, ''));
$('#messageCount').text((currentCount + 1).toLocaleString());
}
// 添加随机消息
function addRandomMessage() {
const lang = i18n.currentLang;
const usernames = lang === 'zh-CN' ? ['张三', '李四', '王五', '赵六'] :
lang === 'en-US' ? ['John', 'Jane', 'Bob', 'Alice'] :
['太郎', '花子', '次郎', '美咲'];
const messages = lang === 'zh-CN' ?
['这个产品真不错!', '价格很实惠', '已经下单了', '质量怎么样?', '有优惠码吗?', '主播讲得很详细', '这个颜色好看'] :
lang === 'en-US' ?
['This product is great!', 'Great price', 'Just ordered', 'How\'s the quality?', 'Any discount codes?', 'Very informative', 'Love this color'] :
['この製品は素晴らしいです!', '価格もお得', '注文しました', '品質はどうですか?', '割引コードはありますか?', 'とても詳しい', 'この色いいね'];
const randomUsername = usernames[Math.floor(Math.random() * usernames.length)];
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
const currentTime = new Date();
const timeString = `${currentTime.getHours()}:${currentTime.getMinutes().toString().padStart(2, '0')}`;
const messageHtml = `
`;
$('#chatMessages').append(messageHtml);
scrollChatToBottom();
// 更新消息计数
const currentCount = parseInt($('#messageCount').text().replace(/,/g, ''));
$('#messageCount').text((currentCount + 1).toLocaleString());
}
// 滚动聊天到底部
function scrollChatToBottom() {
const chatMessages = document.getElementById('chatMessages');
if (chatMessages) {
chatMessages.scrollTop = chatMessages.scrollHeight;
}
}
// 更新悬浮窗观看人数
function updateFloatViewers() {
const lang = i18n.currentLang;
const viewers = ['1.8W', '1.9W', '2.0W', '2.1W', '1.7W'];
const randomViewers = viewers[Math.floor(Math.random() * viewers.length)];
const viewersText = lang === 'zh-CN' ? `${randomViewers}观看` :
lang === 'en-US' ? `${randomViewers} watching` :
`${randomViewers}視聴中`;
$('#floatViewers').text(viewersText);
}
// 处理点赞
function handleLike() {
const $likeBtn = $('#likeBtn');
$likeBtn.addClass('liked');
// 更新点赞数
const currentLikes = parseInt($('#likeCount').text().replace(/,/g, ''));
$('#likeCount').text((currentLikes + 1).toLocaleString());
// 移除动画类
setTimeout(() => {
$likeBtn.removeClass('liked');
}, 500);
// 生成点赞动画
createLikeAnimation();
}
// 创建点赞动画
function createLikeAnimation() {
const $container = $('.live-video-container');
const colors = ['#ff6b6b', '#ff8787', '#ffa5a5', '#ff5252', '#ee5a6f'];
for (let i = 0; i < 3; i++) {
setTimeout(() => {
const $heart = $('❤️
');
$heart.css({
position: 'absolute',
bottom: '20%',
right: Math.random() * 30 + 5 + '%',
fontSize: Math.random() * 15 + 25 + 'px',
color: colors[Math.floor(Math.random() * colors.length)],
animation: 'likeFloat 2.5s ease-out forwards',
zIndex: 100,
pointerEvents: 'none'
});
$container.append($heart);
setTimeout(() => {
$heart.remove();
}, 2500);
}, i * 200);
}
}
// 添加随机弹幕
function addRandomDanmaku() {
const lang = i18n.currentLang;
const messages = lang === 'zh-CN' ?
['这个好看!', '已经下单了', '主播讲得很好', '价格优惠', '喜欢这款', '质量怎么样?', '太棒了!', '有优惠吗?'] :
lang === 'en-US' ?
['Love this!', 'Just ordered', 'Great demo', 'Good price', 'Like this one', 'How\'s the quality?', 'Amazing!', 'Any discounts?'] :
['これいい!', '注文しました', '素晴らしい', '価格が良い', '好きです', '品質は?', '最高!', '割引は?'];
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
createDanmaku(randomMessage);
}
// 创建弹幕
function createDanmaku(text) {
const $container = $('#danmakuContainer');
const containerWidth = $container.width();
const containerHeight = $container.height();
if (!containerWidth || !containerHeight) return;
const $danmaku = $('');
$danmaku.text(text);
// 随机高度位置
const top = Math.random() * (containerHeight - 50);
const duration = 6 + Math.random() * 2; // 6-8秒,更快
$danmaku.css({
top: top + 'px',
left: containerWidth + 'px',
animationDuration: duration + 's'
});
$container.append($danmaku);
// 弹幕结束后移除
setTimeout(() => {
$danmaku.remove();
}, duration * 1000);
}
// 添加商品到购物车
function addProductToCart(productId) {
const lang = i18n.currentLang;
// 获取产品信息
const products = [
{
id: 1,
name: '200片拼图 - 海洋世界',
name_en: '200 Piece Puzzle - Ocean World',
name_ja: '200ピースパズル - 海の世界',
price: 19.99,
image: 'https://picsum.photos/200/200?random=live1'
},
{
id: 2,
name: '艺术绘画套装',
name_en: 'Art Painting Set',
name_ja: 'アート絵画セット',
price: 24.99,
image: 'https://picsum.photos/200/200?random=live2'
},
{
id: 3,
name: '木质积木 - 100块',
name_en: 'Wooden Blocks - 100 Pieces',
name_ja: '木製ブロック - 100ピース',
price: 29.99,
image: 'https://picsum.photos/200/200?random=live3'
},
{
id: 4,
name: '磁力片建构玩具',
name_en: 'Magnetic Building Tiles',
name_ja: 'マグネットタイル',
price: 34.99,
image: 'https://picsum.photos/200/200?random=live4'
},
{
id: 5,
name: '儿童桌游套装',
name_en: 'Kids Board Game Set',
name_ja: '子供用ボードゲームセット',
price: 27.99,
image: 'https://picsum.photos/200/200?random=live5'
},
{
id: 6,
name: '手工贴纸书',
name_en: 'Sticker Activity Book',
name_ja: 'ステッカーブック',
price: 12.99,
image: 'https://picsum.photos/200/200?random=live6'
}
];
const product = products.find(p => p.id === productId);
if (product) {
cart.addToCart(product);
const message = i18n.t('product_added_to_cart') ||
(lang === 'zh-CN' ? '商品已添加到购物车' :
lang === 'en-US' ? 'Product added to cart' :
'商品がカートに追加されました');
alert(message);
}
}