// 统一的组件加载函数 - 同时处理导航栏和页脚
async function loadComponents(isLanguageChange = false) {
// 移除防止重复执行的机制,允许重复执行以确保最新数据被加载
try {
// 1. 检查页面中是否已存在header元素(导航栏)
let existingHeader = document.querySelector('header#navbar');
// 2. 如果不存在header元素,则动态加载navbar.html
if (!existingHeader) {
try {
const navbarResponse = await fetch('/components/navbar.html');
if (navbarResponse.ok) {
const navbarHTML = await navbarResponse.text();
// 将navbar HTML插入到body开头
document.body.insertAdjacentHTML('afterbegin', navbarHTML);
console.log('导航栏HTML已成功加载');
} else {
console.error('加载导航栏HTML失败,状态码:', navbarResponse.status);
}
} catch (error) {
console.error('加载导航栏HTML时发生错误:', error);
}
}
// 3. 检查页面中是否已存在footer元素
let existingFooter = document.querySelector('footer');
// 4. 如果不存在footer元素,则动态加载footer.html
if (!existingFooter) {
try {
const footerResponse = await fetch('/components/footer.html');
if (footerResponse.ok) {
const footerHTML = await footerResponse.text();
// 将footer HTML插入到body末尾
document.body.insertAdjacentHTML('beforeend', footerHTML);
// 给页脚添加初始隐藏类
const footerElement = document.querySelector('footer');
if (footerElement) {
footerElement.classList.add('content-hidden');
}
console.log('页脚HTML已成功加载');
} else {
console.error('加载页脚HTML失败,状态码:', footerResponse.status);
}
} catch (error) {
console.error('加载页脚HTML时发生错误:', error);
}
}
// 3. 从服务器获取最新的配置数据
let homePageData = {};
// 当语言切换时,尝试从localStorage获取数据,如果没有则从服务器获取
if (!isLanguageChange) {
try {
// 获取当前语言,确保传递正确的语言参数
const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh';
console.log('当前语言:', currentLang);
// 添加缓存控制头,确保每次都从服务器获取最新的数据
const response = await fetch(`/api/config?lang=${currentLang}`, {
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
});
console.log('服务器响应状态:', response.status);
if (response.ok) {
const data = await response.json();
console.log('服务器返回数据:', data);
if (data.success && data.config) {
homePageData = data.config;
// 将服务器数据保存到localStorage,以便下次使用
localStorage.setItem('homePageData', JSON.stringify(homePageData));
// 保存当前语言到localStorage,以便下次检查
localStorage.setItem('homePageDataLang', currentLang);
console.log('从服务器更新了homePageData:', homePageData);
}
}
} catch (error) {
console.error('从服务器获取页脚数据失败,使用localStorage备用数据:', error);
// 如果从服务器获取数据失败,使用localStorage数据
homePageData = JSON.parse(localStorage.getItem('homePageData') || '{}');
// 检查localStorage中的数据语言是否与当前语言一致
const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh';
const cachedLang = localStorage.getItem('homePageDataLang');
if (cachedLang && cachedLang !== currentLang) {
console.log('localStorage中的数据语言与当前语言不一致,尝试从服务器获取');
// 尝试从服务器获取当前语言的数据
try {
const response = await fetch(`/api/config?lang=${currentLang}`, {
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
});
if (response.ok) {
const data = await response.json();
if (data.success && data.config) {
homePageData = data.config;
localStorage.setItem('homePageData', JSON.stringify(homePageData));
localStorage.setItem('homePageDataLang', currentLang);
}
}
} catch (innerError) {
console.error('再次尝试获取数据失败:', innerError);
// 如果再次失败,使用空对象
homePageData = {};
}
}
console.log('使用localStorage中的homePageData:', homePageData);
}
} else {
console.log('语言切换,从localStorage获取数据');
// 从localStorage获取数据
homePageData = JSON.parse(localStorage.getItem('homePageData') || '{}');
// 检查localStorage中的数据语言是否与当前语言一致
const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh';
const cachedLang = localStorage.getItem('homePageDataLang');
if (cachedLang && cachedLang !== currentLang) {
console.log('localStorage中的数据语言与当前语言不一致,尝试从服务器获取');
// 尝试从服务器获取当前语言的数据
try {
const response = await fetch(`/api/config?lang=${currentLang}`, {
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
});
if (response.ok) {
const data = await response.json();
if (data.success && data.config) {
homePageData = data.config;
localStorage.setItem('homePageData', JSON.stringify(homePageData));
localStorage.setItem('homePageDataLang', currentLang);
}
}
} catch (error) {
console.error('获取当前语言数据失败:', error);
// 如果失败,使用空对象
homePageData = {};
}
}
console.log('语言切换后使用的homePageData:', homePageData);
}
// 确保footer数据存在
const footerData = homePageData.footer || {};
// 第一格:品牌信息
const logoImage = document.getElementById('logo-image');
const logoText = document.getElementById('logo-text');
const footerLogoImage = document.getElementById('footer-logo-image');
const footerLogoText = document.getElementById('footer-logo-text');
const footerDesc = document.querySelector('[data-lang-key="footer_desc"]');
// 获取siteSettings中的LOGO设置,优先级最高
const siteSettings = JSON.parse(localStorage.getItem('siteSettings') || '{}');
// 更新品牌LOGO(导航栏和页脚)
const logoSrc = siteSettings.logo || homePageData.logo || (footerData.column1 && footerData.column1.logo);
if (logoSrc) {
// 更新导航栏LOGO
if (logoImage) {
logoImage.src = logoSrc;
logoImage.style.display = 'block';
logoText.style.display = 'none';
}
// 更新页脚LOGO
if (footerLogoImage) {
footerLogoImage.src = logoSrc;
footerLogoImage.style.display = 'block';
footerLogoText.style.display = 'none';
}
} else {
// 否则显示文字LOGO
if (logoImage) {
logoImage.src = '';
logoImage.style.display = 'none';
logoText.style.display = 'block';
}
if (footerLogoImage) {
footerLogoImage.src = '';
footerLogoImage.style.display = 'none';
footerLogoText.style.display = 'block';
}
// 更新文字LOGO内容
const logoTextContent = siteSettings.logoText || homePageData.logoText || (footerData.column1 && footerData.column1.logoText) || '无穷智能自动售货机';
// 检查是否包含高亮部分
if (logoText && logoTextContent.includes('智能自动售货机')) {
logoText.innerHTML = logoTextContent.replace('智能自动售货机', '智能自动售货机');
} else if (logoText) {
logoText.textContent = logoTextContent;
}
if (footerLogoText && logoTextContent.includes('智能自动售货机')) {
footerLogoText.innerHTML = logoTextContent.replace('智能自动售货机', '智能自动售货机');
} else if (footerLogoText) {
footerLogoText.textContent = logoTextContent;
}
}
// 更新页脚第一格描述信息
if (footerDesc) {
// 优先使用footerData.column1.desc
if (footerData.column1 && footerData.column1.desc) {
footerDesc.textContent = footerData.column1.desc;
}
// 其次使用footerData.desc
else if (footerData.desc) {
footerDesc.textContent = footerData.desc;
}
// 保留data-lang-key属性,让语言管理器处理翻译
}
// 调试信息
console.log('Footer data loaded:', {
footerData: footerData,
column1Desc: footerData.column1 ? footerData.column1.desc : 'N/A',
footerDesc: footerData.desc,
footerDescElement: footerDesc
});
// 第二格:快速链接
const quickLinksTitle = document.querySelector('footer [data-lang-key="quick_links"]');
const quickLinksItems = document.querySelectorAll('footer [data-lang-key^="nav_"]');
if (footerData.column2) {
if (footerData.column2.title && quickLinksTitle) {
quickLinksTitle.textContent = footerData.column2.title;
}
if (footerData.column2.links && quickLinksItems) {
// 更新快速链接项
footerData.column2.links.forEach((link, index) => {
if (quickLinksItems[index]) {
quickLinksItems[index].textContent = link.text;
quickLinksItems[index].href = link.url || '#';
}
});
}
}
// 第三格:联系信息
const contactInfoTitle = document.querySelector('footer [data-lang-key="contact_info"]');
const contactAddress = document.querySelector('footer [data-lang-key="contact_address"]');
const contactPhone = document.querySelector('footer [data-lang-key="contact_phone"]');
const contactEmail = document.querySelector('footer [data-lang-key="contact_email"]');
const qrCodeText = document.querySelector('footer .text-neutral-400.text-sm');
// 给二维码文本添加data-lang-key属性
if (qrCodeText && !qrCodeText.hasAttribute('data-lang-key')) {
qrCodeText.setAttribute('data-lang-key', 'contact_qrcode_text');
}
const qrCodeElement = document.querySelector('footer .bg-white.p-4.rounded-md.mb-3 .w-32.h-32');
if (footerData.column3) {
if (footerData.column3.title && contactInfoTitle) {
contactInfoTitle.textContent = footerData.column3.title;
}
if (footerData.column3.address && contactAddress) {
contactAddress.textContent = footerData.column3.address;
}
if (footerData.column3.phone && contactPhone) {
contactPhone.textContent = footerData.column3.phone;
}
if (footerData.column3.email && contactEmail) {
contactEmail.textContent = footerData.column3.email;
}
if (footerData.column3.qrCodeText && qrCodeText) {
qrCodeText.textContent = footerData.column3.qrCodeText;
}
// 更新二维码图片
if (footerData.column3.qrCode && qrCodeElement) {
// 清空容器,移除所有旧内容
qrCodeElement.innerHTML = '';
// 创建新的二维码图片
const qrImg = document.createElement('img');
qrImg.src = footerData.column3.qrCode;
qrImg.alt = '二维码';
qrImg.className = 'w-full h-full object-contain';
qrCodeElement.appendChild(qrImg);
}
}
// 更新版权信息
const copyrightText = document.querySelector('[data-lang-key="copyright"] p');
if (copyrightText) {
if (footerData.copyright) {
copyrightText.innerHTML = footerData.copyright;
} else if (homePageData.footer && homePageData.footer.copyright) {
copyrightText.innerHTML = homePageData.footer.copyright;
}
}
// 更新备案号信息 - 简化版
const beianInfo = document.getElementById('beian-info');
if (beianInfo) {
// 只在有新数据时更新备案号,否则保持默认值
const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh';
fetch(`/api/config?lang=${currentLang}`, {
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
})
.then(response => response.json())
.then(data => {
if (data.success && data.config && data.config.beian) {
// 只有当服务器返回了beian数据时才更新
beianInfo.innerHTML = data.config.beian;
}
// 确保元素可见
beianInfo.style.display = 'block';
beianInfo.style.visibility = 'visible';
beianInfo.style.opacity = '1';
})
.catch(error => {
console.error('更新备案号失败:', error);
// 出错时保持默认值不变
});
}
// 更新官方商城链接
const mallLinks = document.querySelectorAll('[data-lang-key="official_mall"]');
// 使用配置的链接,如果没有则使用默认值
// 检查officialMallUrl是否在images对象中(旧格式)或根对象中(新格式)
const mallUrl = homePageData.officialMallUrl || (homePageData.images && homePageData.images.officialMallUrl ? homePageData.images.officialMallUrl.url : '#');
// 更新所有官方商城链接
mallLinks.forEach(link => {
link.href = mallUrl;
});
// 初始化移动端菜单
window.initMobileMenu = function() {
// 确保元素存在
if (!document.getElementById('mobile-menu-btn') || !document.getElementById('mobile-menu')) {
console.error('移动端菜单元素未找到');
return;
}
// 为移动端菜单按钮添加点击事件(直接绑定,不替换元素)
// 移除旧的事件监听器,避免重复绑定
document.getElementById('mobile-menu-btn').onclick = function() {
const mobileMenu = document.getElementById('mobile-menu');
if (mobileMenu.classList.contains('hidden')) {
mobileMenu.classList.remove('hidden');
mobileMenu.style.opacity = '1';
mobileMenu.style.transform = 'translateY(0)';
} else {
// 直接隐藏菜单,不使用外部函数
mobileMenu.style.opacity = '0';
mobileMenu.style.transform = 'translateY(-10px)';
setTimeout(() => {
mobileMenu.classList.add('hidden');
}, 300);
}
};
// 为移动端菜单链接添加点击事件,点击后隐藏菜单
const mobileMenuLinks = document.querySelectorAll('#mobile-menu a');
mobileMenuLinks.forEach(link => {
// 保存原始的onclick事件处理函数
const originalOnClick = link.onclick || function() {};
// 使用addEventListener添加事件监听,而不是直接覆盖onclick
link.onclick = function(event) {
// 执行原始的点击事件处理函数
originalOnClick.call(this, event);
// 隐藏菜单
const mobileMenu = document.getElementById('mobile-menu');
if (!mobileMenu.classList.contains('hidden')) {
mobileMenu.style.opacity = '0';
mobileMenu.style.transform = 'translateY(-10px)';
setTimeout(() => {
mobileMenu.classList.add('hidden');
}, 300);
}
};
});
// 初始化移动端产品中心下拉菜单
const mobileProductsBtn = document.getElementById('mobile-products-btn');
const mobileProductsDropdown = document.getElementById('mobile-products-dropdown');
const mobileProductsArrow = document.querySelector('#mobile-products-btn i');
if (mobileProductsBtn && mobileProductsDropdown) {
// 设置初始样式
mobileProductsDropdown.style.opacity = '0';
mobileProductsDropdown.style.transform = 'translateY(-10px)';
mobileProductsDropdown.style.transition = 'opacity 300ms ease, transform 300ms ease';
// 直接绑定onclick事件,会自动覆盖旧事件
mobileProductsBtn.onclick = function(event) {
event.stopPropagation();
if (mobileProductsDropdown.classList.contains('hidden')) {
// 显示下拉菜单
mobileProductsDropdown.classList.remove('hidden');
// 延迟设置样式以触发过渡效果
setTimeout(() => {
mobileProductsDropdown.style.opacity = '1';
mobileProductsDropdown.style.transform = 'translateY(0)';
}, 10);
} else {
// 隐藏下拉菜单
mobileProductsDropdown.style.opacity = '0';
mobileProductsDropdown.style.transform = 'translateY(-10px)';
// 延迟添加hidden类以完成过渡效果
setTimeout(() => {
mobileProductsDropdown.classList.add('hidden');
}, 300);
}
if (mobileProductsArrow) {
mobileProductsArrow.classList.toggle('rotate-180');
}
};
}
// 为产品下拉菜单链接添加点击事件
const mobileProductsLinks = document.querySelectorAll('#mobile-products-dropdown a');
mobileProductsLinks.forEach(link => {
// 直接绑定onclick事件,会自动覆盖旧事件
link.onclick = function() {
const mobileMenu = document.getElementById('mobile-menu');
if (!mobileMenu.classList.contains('hidden')) {
mobileMenu.style.opacity = '0';
mobileMenu.style.transform = 'translateY(-10px)';
setTimeout(() => {
mobileMenu.classList.add('hidden');
}, 300);
}
};
});
}
// 调用语言管理器的reinit方法,更新语言切换按钮和页面翻译
if (window.languageManager) {
window.languageManager.reinit();
}
// 显示页脚
const footerElement = document.querySelector('footer');
if (footerElement) {
footerElement.classList.remove('content-hidden');
footerElement.classList.add('content-visible');
}
// 初始化移动端菜单
window.initMobileMenu();
} catch (error) {
console.error('加载页脚数据失败:', error);
}
}
// 添加向后兼容的别名,确保现有代码仍能正常工作
window.loadFooterData = loadComponents;
// 移除自动执行机制,由各个页面的初始化函数手动调用,确保执行顺序可控
// if (typeof window !== 'undefined') {
// window.addEventListener('DOMContentLoaded', loadComponents);
// }