class UpdateHistory extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.versions = []; this.accessLevel = 0; this.currentPage = 1; this.pageSize = 10; this.totalPages = 1; } connectedCallback() { this.render(); this.loadData(); this.checkUserAccess(); } // 检查用户权限 async checkUserAccess() { try { const response = await fetch('/api/check-auth', { credentials: 'include' }); const result = await response.json(); if (result.success) { this.accessLevel = result.user.access_level || 0; } else { this.accessLevel = 0; } this.updateAddButton(); } catch (error) { console.error('获取用户权限失败:', error); this.accessLevel = 0; this.updateAddButton(); } } // 更新添加按钮显示状态 updateAddButton() { const addButton = this.shadowRoot.querySelector('#addVersionBtn'); if (addButton) { addButton.style.display = this.accessLevel >= 2 ? 'flex' : 'none'; } } async loadData() { try { const response = await fetch('/api/versions'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // 按版本号降序排序,然后按日期降序 this.versions = data.sort((a, b) => { // 使用版本号比较函数 const versionCompare = this.compareVersions(b.verNum, a.verNum); if (versionCompare !== 0) { return versionCompare; } const dateA = new Date(a.date + ' ' + a.time); const dateB = new Date(b.date + ' ' + b.time); return dateB - dateA; }); this.renderVersions(); } catch (error) { console.error('加载版本信息失败:', error); this.showError(); } } // 比较版本号 compareVersions(versionA, versionB) { const partsA = versionA.split('.').map(Number); const partsB = versionB.split('.').map(Number); for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) { const partA = partsA[i] || 0; const partB = partsB[i] || 0; if (partA > partB) return 1; if (partA < partB) return -1; } return 0; } renderVersions() { const contentContainer = this.shadowRoot.querySelector('#content'); if (this.versions.length === 0) { contentContainer.innerHTML = '
暂无更新记录
'; return; } this.totalPages = Math.ceil(this.versions.length / this.pageSize); const startIndex = (this.currentPage - 1) * this.pageSize; const endIndex = Math.min(startIndex + this.pageSize, this.versions.length); const currentPageVersions = this.versions.slice(startIndex, endIndex); let html = `
${currentPageVersions.map(version => `
V${this.formatVersionNumber(version)} ${this.getStageLabel(version.stage)} ${version.title} ${version.date} ${version.time} 作者: ${version.author || '未知用户'}
${version.note ? ` ` : ''}
${version.note ? `
${version.note}
` : ''}
`).join('')}
`; contentContainer.innerHTML = html; // 添加展开/收起事件 this.addExpandListeners(); // 更新添加按钮显示状态 this.updateAddButton(); // 添加分页按钮事件监听 this.addPaginationListeners(); } addExpandListeners() { const expandButtons = this.shadowRoot.querySelectorAll('.expand-btn'); expandButtons.forEach((button, index) => { // 移除旧事件(如果有) button.removeEventListener('click', this.onButtonClick); // 添加新事件 button.addEventListener('click', (e) => { const versionItem = button.closest('.version-item'); const description = versionItem.querySelector('.version-description'); // 切换显示/隐藏状态 description.classList.toggle('show'); // 更新按钮状态 button.classList.toggle('expanded'); // 更新按钮文本和图标 const img = button.querySelector('img'); if (description.classList.contains('show')) { button.setAttribute('aria-label', '收起详情'); img.alt = '收起'; } else { button.setAttribute('aria-label', '展开详情'); img.alt = '展开'; } }); }); } showError() { const contentContainer = this.shadowRoot.querySelector('#content'); contentContainer.innerHTML = '
加载失败,请稍后重试
'; } render() { this.shadowRoot.innerHTML = `

更新记录

加载中...
`; // 添加事件监听器 this.addModalEventListeners(); } // 添加模态框事件监听器 addModalEventListeners() { const addButton = this.shadowRoot.getElementById('addVersionBtn'); const closeButton = this.shadowRoot.getElementById('closeModalBtn'); const cancelButton = this.shadowRoot.getElementById('cancelBtn'); const modal = this.shadowRoot.getElementById('versionModal'); const form = this.shadowRoot.getElementById('versionForm'); // 点击添加按钮显示模态框 if (addButton) { addButton.addEventListener('click', () => { this.prepareModalData(); modal.classList.add('active'); }); } // 关闭模态框 if (closeButton) { closeButton.addEventListener('click', () => { modal.classList.remove('active'); }); } // 取消按钮 if (cancelButton) { cancelButton.addEventListener('click', () => { modal.classList.remove('active'); }); } // 表单提交 if (form) { form.addEventListener('submit', (e) => { e.preventDefault(); this.submitVersion(); }); } } // 格式化版本号显示 formatVersionNumber(version) { // 将日期转换为六位数字格式 (YYYY-MM-DD -> YYMMDD) const dateParts = version.date.split('-'); const shortDate = dateParts[0].slice(-2) + dateParts[1] + dateParts[2]; // 组合版本号、日期和阶段 return `${version.verNum}.${shortDate}_${version.stage || 'alpha'}`; } // 准备模态框数据 prepareModalData() { // 获取表单元素 const verNumInput = this.shadowRoot.getElementById('verNum'); const dateInput = this.shadowRoot.getElementById('date'); const timeInput = this.shadowRoot.getElementById('time'); // 设置当前日期和时间 const now = new Date(); const formattedDate = now.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\//g, '-'); const formattedTime = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); dateInput.value = formattedDate; timeInput.value = formattedTime; // 计算新版本号 if (this.versions && this.versions.length > 0) { const latestVersion = this.versions[0]; const currentVersionParts = latestVersion.verNum.split('.'); // 增加最后一位 let newVersion; if (currentVersionParts.length >= 3) { currentVersionParts[2] = (parseInt(currentVersionParts[2]) + 1).toString(); newVersion = currentVersionParts.join('.'); } else { // 如果版本号格式不是 x.y.z,则简单地加0.0.1 const versionNum = parseFloat(latestVersion.verNum); newVersion = (versionNum + 0.001).toFixed(3); } verNumInput.value = newVersion; } else { // 如果没有现有版本,使用默认的1.0.0 verNumInput.value = '1.0.0'; } } // 获取版本阶段显示标签 getStageLabel(stage) { const stageLabels = { 'alpha': '开发版', 'beta': '测试版', 'rc': '候选版', 'stable': '正式版' }; return stageLabels[stage] || '开发版'; } // 提交版本信息 async submitVersion() { const modal = this.shadowRoot.getElementById('versionModal'); const verNum = this.shadowRoot.getElementById('verNum').value; const date = this.shadowRoot.getElementById('date').value; const time = this.shadowRoot.getElementById('time').value; const title = this.shadowRoot.getElementById('title').value; const note = this.shadowRoot.getElementById('note').value; const stage = this.shadowRoot.getElementById('stage').value; // 获取当前登录用户名 let author = '未知用户'; try { const response = await fetch('/api/check-auth', { credentials: 'include' }); const result = await response.json(); if (result.success) { author = result.user.username || '未知用户'; } } catch (error) { console.error('获取用户信息失败:', error); } try { const response = await fetch('/api/versions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ verNum, date, time, title, note, author, stage }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // 重新加载版本数据 this.loadData(); // 关闭模态框 modal.classList.remove('active'); // 清空表单 this.shadowRoot.getElementById('title').value = ''; this.shadowRoot.getElementById('note').value = ''; // 显示成功消息 alert('更新记录提交成功!'); } catch (error) { console.error('提交更新记录失败:', error); alert('提交失败,请重试!'); } } // 添加分页按钮事件监听 addPaginationListeners() { const prevButton = this.shadowRoot.getElementById('prevPage'); const nextButton = this.shadowRoot.getElementById('nextPage'); if (prevButton) { prevButton.addEventListener('click', () => { if (this.currentPage > 1) { this.currentPage--; this.renderVersions(); } }); } if (nextButton) { nextButton.addEventListener('click', () => { if (this.currentPage < this.totalPages) { this.currentPage++; this.renderVersions(); } }); } } } customElements.define('update-history', UpdateHistory);