2025-04-28 12:25:20 +08:00
|
|
|
|
class OverviewPage extends HTMLElement {
|
|
|
|
|
constructor() {
|
|
|
|
|
super();
|
|
|
|
|
this.attachShadow({ mode: 'open' });
|
|
|
|
|
this.versions = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connectedCallback() {
|
|
|
|
|
this.loadVersions().then(() => {
|
|
|
|
|
this.render();
|
|
|
|
|
this.startClock();
|
|
|
|
|
this.setupEventListeners();
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('加载版本信息失败:', error);
|
|
|
|
|
this.render();
|
|
|
|
|
this.startClock();
|
|
|
|
|
this.setupEventListeners();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
disconnectedCallback() {
|
|
|
|
|
if (this.clockInterval) {
|
|
|
|
|
clearInterval(this.clockInterval);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async loadVersions() {
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch('/api/versions');
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
this.versions = await response.json();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('加载版本信息失败:', error);
|
|
|
|
|
this.versions = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatVersionRecord(version) {
|
|
|
|
|
const date = version.date;
|
|
|
|
|
const time = version.time;
|
|
|
|
|
const verNum = version.verNum;
|
|
|
|
|
const title = version.title;
|
|
|
|
|
|
|
|
|
|
return `【${date} ${time}】v${verNum} ${title}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startClock() {
|
|
|
|
|
const updateClock = () => {
|
|
|
|
|
const dateElement = this.shadowRoot.querySelector('.current-time .date');
|
|
|
|
|
const timeElement = this.shadowRoot.querySelector('.current-time .time');
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
|
|
|
|
dateElement.textContent = now.toLocaleString('zh-CN', {
|
|
|
|
|
year: 'numeric',
|
|
|
|
|
month: '2-digit',
|
|
|
|
|
day: '2-digit'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
timeElement.textContent = now.toLocaleString('zh-CN', {
|
|
|
|
|
hour: '2-digit',
|
|
|
|
|
minute: '2-digit',
|
|
|
|
|
second: '2-digit',
|
|
|
|
|
hour12: false
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
updateClock();
|
|
|
|
|
this.clockInterval = setInterval(updateClock, 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setupEventListeners() {
|
|
|
|
|
const detailsLink = this.shadowRoot.querySelector('.details-link');
|
|
|
|
|
if (detailsLink) {
|
|
|
|
|
detailsLink.addEventListener('click', (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
// 获取子工具栏
|
|
|
|
|
const subToolbar = document.querySelector('sub-toolbar');
|
|
|
|
|
if (subToolbar) {
|
|
|
|
|
// 触发与更新记录按钮相同的事件
|
|
|
|
|
const event = new CustomEvent('sub-item-selected', {
|
|
|
|
|
detail: {
|
|
|
|
|
parent: 'home',
|
|
|
|
|
text: '更新记录',
|
|
|
|
|
icon: 'clock'
|
|
|
|
|
},
|
|
|
|
|
bubbles: true,
|
|
|
|
|
composed: true
|
|
|
|
|
});
|
|
|
|
|
subToolbar.dispatchEvent(event);
|
|
|
|
|
|
|
|
|
|
// 激活更新记录按钮
|
|
|
|
|
const updateRecordButton = subToolbar.shadowRoot.querySelector('.sub-item[data-icon="clock"]');
|
|
|
|
|
if (updateRecordButton) {
|
|
|
|
|
// 移除其他按钮的激活状态
|
|
|
|
|
const siblings = updateRecordButton.parentElement.querySelectorAll('.sub-item');
|
|
|
|
|
siblings.forEach(si => si.classList.remove('active'));
|
|
|
|
|
// 激活更新记录按钮
|
|
|
|
|
updateRecordButton.classList.add('active');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-05-08 09:25:40 +08:00
|
|
|
|
|
|
|
|
|
// 添加Q&A和帮助链接的事件监听
|
|
|
|
|
const qaLink = this.shadowRoot.querySelector('#qa-link');
|
|
|
|
|
const helpLink = this.shadowRoot.querySelector('#help-link');
|
|
|
|
|
|
|
|
|
|
if (qaLink) {
|
|
|
|
|
qaLink.addEventListener('click', (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
// 获取子工具栏
|
|
|
|
|
const subToolbar = document.querySelector('sub-toolbar');
|
|
|
|
|
if (subToolbar) {
|
|
|
|
|
// 触发与常见问题按钮相同的事件
|
|
|
|
|
const event = new CustomEvent('sub-item-selected', {
|
|
|
|
|
detail: {
|
|
|
|
|
parent: 'home',
|
|
|
|
|
text: 'Q&A',
|
|
|
|
|
icon: 'question'
|
|
|
|
|
},
|
|
|
|
|
bubbles: true,
|
|
|
|
|
composed: true
|
|
|
|
|
});
|
|
|
|
|
subToolbar.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (helpLink) {
|
|
|
|
|
helpLink.addEventListener('click', (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
// 获取子工具栏
|
|
|
|
|
const subToolbar = document.querySelector('sub-toolbar');
|
|
|
|
|
if (subToolbar) {
|
|
|
|
|
// 触发与帮助文档按钮相同的事件
|
|
|
|
|
const event = new CustomEvent('sub-item-selected', {
|
|
|
|
|
detail: {
|
|
|
|
|
parent: 'home',
|
|
|
|
|
text: '帮助',
|
|
|
|
|
icon: 'help'
|
|
|
|
|
},
|
|
|
|
|
bubbles: true,
|
|
|
|
|
composed: true
|
|
|
|
|
});
|
|
|
|
|
subToolbar.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
// 添加加载状态的样式
|
|
|
|
|
const style = `
|
|
|
|
|
.update-list {
|
|
|
|
|
min-height: 100px;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.update-list.loading::after {
|
|
|
|
|
content: '加载中...';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
left: 50%;
|
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
|
|
color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.update-list.error::after {
|
|
|
|
|
content: '加载失败';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
left: 50%;
|
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
|
|
color: #ff4444;
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
this.shadowRoot.innerHTML = `
|
|
|
|
|
<style>
|
|
|
|
|
${style}
|
|
|
|
|
:host {
|
|
|
|
|
display: block;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.overview-container {
|
|
|
|
|
max-width: 1200px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(12, 1fr);
|
|
|
|
|
gap: 20px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.welcome-card {
|
|
|
|
|
grid-column: span 8;
|
|
|
|
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 30px;
|
|
|
|
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.welcome-card h1 {
|
|
|
|
|
font-size: 32px;
|
|
|
|
|
margin: 0 0 10px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.welcome-card p {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
opacity: 0.9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.current-time {
|
|
|
|
|
grid-column: span 4;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.current-time h2 {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin: 0 0 15px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.current-time .value {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
color: #3498db;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.current-time .date{
|
|
|
|
|
display: block;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
color: #764ba2;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.current-time .time {
|
|
|
|
|
display: block;
|
|
|
|
|
font-size: 40px;
|
|
|
|
|
color: #667eea;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-info {
|
|
|
|
|
grid-column: span 4;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.about-section {
|
|
|
|
|
grid-column: span 4;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
2025-05-08 09:25:40 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.about-section .section-title {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.about-section p {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.about-section .version-list {
|
|
|
|
|
margin-bottom: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-links {
|
|
|
|
|
margin-top: auto;
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
padding-top: 20px;
|
|
|
|
|
border-top: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link {
|
|
|
|
|
position: relative;
|
|
|
|
|
color: #667eea;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
padding: 4px 2px;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link:hover {
|
|
|
|
|
color: #764ba2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link::before {
|
|
|
|
|
content: '';
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 16px;
|
|
|
|
|
height: 16px;
|
|
|
|
|
background-size: 16px;
|
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
background-position: center;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
/* 将黑色图标转换为蓝色 (#667eea) */
|
|
|
|
|
filter: brightness(0) saturate(100%) invert(53%) sepia(95%) saturate(1731%) hue-rotate(213deg) brightness(99%) contrast(94%) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#qa-link::before {
|
|
|
|
|
background-image: url('assets/icons/png/question_b.png');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#help-link::before {
|
|
|
|
|
background-image: url('assets/icons/png/help_b.png');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link:hover::before {
|
|
|
|
|
/* 将黑色图标转换为紫色 (#764ba2) */
|
|
|
|
|
filter: brightness(0) saturate(100%) invert(36%) sepia(24%) saturate(1674%) hue-rotate(233deg) brightness(94%) contrast(92%) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 1px;
|
|
|
|
|
background: currentColor;
|
|
|
|
|
transform: scaleX(0);
|
|
|
|
|
transform-origin: right;
|
|
|
|
|
transition: transform 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link:hover::after {
|
|
|
|
|
transform: scaleX(1);
|
|
|
|
|
transform-origin: left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link::before {
|
|
|
|
|
content: '';
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 18px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
background-size: 18px;
|
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
background-position: center;
|
|
|
|
|
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.1));
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.help-link:hover::before {
|
|
|
|
|
transform: scale(1.1);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-widget {
|
|
|
|
|
grid-column: span 4;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.updates-log {
|
|
|
|
|
grid-column: span 12;
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin: 0 0 15px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list, .update-list {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li, .update-list li {
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li:last-child, .update-list li:last-child {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar .month {
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(7, 1fr);
|
|
|
|
|
gap: 5px;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-header {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(7, 1fr);
|
|
|
|
|
gap: 5px;
|
|
|
|
|
margin-bottom: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-header span {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #666;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-day {
|
|
|
|
|
padding: 5px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-day.today {
|
|
|
|
|
background-color: #667eea;
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.calendar-day.other-month {
|
|
|
|
|
color: #ccc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li {
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li .label {
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
min-width: 80px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li .value {
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
text-align: right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-list li:last-child {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-note {
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.version-loading {
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #666;
|
|
|
|
|
padding: 20px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.details-link {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 20px;
|
|
|
|
|
right: 20px;
|
|
|
|
|
color: #667eea;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
transition: color 0.3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.details-link:hover {
|
|
|
|
|
color: #764ba2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.details-link::after {
|
|
|
|
|
content: '›';
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
margin-top: -2px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<div class="overview-container">
|
|
|
|
|
<div class="welcome-card">
|
|
|
|
|
<h1>欢迎使用 XNSim</h1>
|
|
|
|
|
<p>XNSim 是一个功能强大的仿真系统,为您提供专业的飞行模拟仿真分析工具和直观的操作界面。</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="current-time">
|
|
|
|
|
<h2>当前时间</h2>
|
|
|
|
|
<div class="value">
|
|
|
|
|
<span class="date"></span>
|
|
|
|
|
<span class="time"></span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="version-info">
|
|
|
|
|
<h2 class="section-title">版本信息</h2>
|
|
|
|
|
${this.versions.length > 0 ? `
|
|
|
|
|
<ul class="version-list">
|
|
|
|
|
<li>
|
|
|
|
|
<span class="label">当前版本</span>
|
|
|
|
|
<span class="value">v${this.versions[0].verNum}</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<span class="label">发布日期</span>
|
|
|
|
|
<span class="value">${this.versions[0].date}</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<span class="label">发布时间</span>
|
|
|
|
|
<span class="value">${this.versions[0].time}</span>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
` : `
|
|
|
|
|
<div class="version-loading">版本信息加载中...</div>
|
|
|
|
|
`}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="about-section">
|
|
|
|
|
<h2 class="section-title">关于系统</h2>
|
|
|
|
|
<p>XNSim 是新一代飞行模拟数据包仿真分析平台,致力于提供高效、准确的飞行模拟仿真解决方案。</p>
|
|
|
|
|
<ul class="version-list">
|
|
|
|
|
<li>开发团队:XNSim Team</li>
|
|
|
|
|
<li>技术支持:无</li>
|
|
|
|
|
<li>官方网站:无</li>
|
|
|
|
|
</ul>
|
2025-05-08 09:25:40 +08:00
|
|
|
|
<div class="help-links">
|
2025-05-29 09:26:44 +08:00
|
|
|
|
<a href="#" class="help-link" id="qa-link">Q&A</a>
|
|
|
|
|
<a href="#" class="help-link" id="help-link">帮助</a>
|
2025-05-08 09:25:40 +08:00
|
|
|
|
</div>
|
2025-04-28 12:25:20 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="calendar-widget">
|
|
|
|
|
<h2 class="section-title">日历</h2>
|
|
|
|
|
<div class="calendar">
|
|
|
|
|
<div class="month"></div>
|
|
|
|
|
<div class="calendar-header">
|
|
|
|
|
<span>日</span>
|
|
|
|
|
<span>一</span>
|
|
|
|
|
<span>二</span>
|
|
|
|
|
<span>三</span>
|
|
|
|
|
<span>四</span>
|
|
|
|
|
<span>五</span>
|
|
|
|
|
<span>六</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="calendar-grid"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="updates-log">
|
|
|
|
|
<h2 class="section-title">更新记录</h2>
|
|
|
|
|
<a href="#" class="details-link">详细信息</a>
|
|
|
|
|
<ul class="update-list ${this.versions.length === 0 ? 'error' : ''}">
|
|
|
|
|
${this.versions.slice(0, 3).map(version => `
|
|
|
|
|
<li>${this.formatVersionRecord(version)}</li>
|
|
|
|
|
`).join('')}
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// 初始化日历显示
|
|
|
|
|
const now = new Date();
|
|
|
|
|
const calendarElement = this.shadowRoot.querySelector('.calendar');
|
|
|
|
|
calendarElement.querySelector('.month').textContent = now.toLocaleString('zh-CN', { month: 'long' });
|
|
|
|
|
calendarElement.querySelector('.calendar-grid').innerHTML = this.generateCalendarGrid(now);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
generateCalendarGrid(date) {
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
const month = date.getMonth();
|
|
|
|
|
const today = new Date();
|
|
|
|
|
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
|
|
|
const firstDay = new Date(year, month, 1).getDay();
|
|
|
|
|
const lastDayPrevMonth = new Date(year, month, 0).getDate();
|
|
|
|
|
let gridHtml = '';
|
|
|
|
|
|
|
|
|
|
// 上个月的日期
|
|
|
|
|
for (let i = firstDay - 1; i >= 0; i--) {
|
|
|
|
|
gridHtml += `<div class="calendar-day other-month">${lastDayPrevMonth - i}</div>`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当月的日期
|
|
|
|
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
|
|
|
const isToday = day === today.getDate() &&
|
|
|
|
|
month === today.getMonth() &&
|
|
|
|
|
year === today.getFullYear();
|
|
|
|
|
gridHtml += `<div class="calendar-day${isToday ? ' today' : ''}">${day}</div>`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下个月的日期
|
|
|
|
|
const remainingDays = 42 - (firstDay + daysInMonth); // 保持6行格式
|
|
|
|
|
for (let day = 1; day <= remainingDays; day++) {
|
|
|
|
|
gridHtml += `<div class="calendar-day other-month">${day}</div>`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return gridHtml;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
customElements.define('overview-page', OverviewPage);
|