2025-04-30 13:47:35 +08:00
|
|
|
|
class HeaderTools extends HTMLElement {
|
|
|
|
|
constructor() {
|
|
|
|
|
super();
|
|
|
|
|
this.attachShadow({ mode: 'open' });
|
|
|
|
|
this.render();
|
|
|
|
|
this.addEventListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加getter方法
|
2025-05-16 09:21:11 +08:00
|
|
|
|
get selectedPlane() {
|
|
|
|
|
return this.shadowRoot.getElementById('planeSelect').value;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 10:26:07 +08:00
|
|
|
|
get selectedConfiguration() {
|
|
|
|
|
return this.shadowRoot.getElementById('configurationSelect').value;
|
2025-04-30 13:47:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 11:02:12 +08:00
|
|
|
|
get selectedDomain() {
|
|
|
|
|
const select = this.shadowRoot.getElementById('configurationSelect');
|
|
|
|
|
const selectedOption = select.options[select.selectedIndex];
|
|
|
|
|
return selectedOption ? selectedOption.dataset.domainId : '';
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 保存选择到localStorage
|
|
|
|
|
saveSelection() {
|
|
|
|
|
const selection = {
|
|
|
|
|
plane: this.selectedPlane,
|
2025-06-06 11:02:12 +08:00
|
|
|
|
configurationId: this.selectedConfiguration,
|
|
|
|
|
domainId: this.selectedDomain
|
2025-05-16 09:21:11 +08:00
|
|
|
|
};
|
|
|
|
|
localStorage.setItem('xnsim-selection', JSON.stringify(selection));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从localStorage恢复选择
|
|
|
|
|
restoreSelection() {
|
|
|
|
|
const savedSelection = localStorage.getItem('xnsim-selection');
|
|
|
|
|
if (savedSelection) {
|
|
|
|
|
const selection = JSON.parse(savedSelection);
|
|
|
|
|
const planeSelect = this.shadowRoot.getElementById('planeSelect');
|
2025-05-16 10:26:07 +08:00
|
|
|
|
const configurationSelect = this.shadowRoot.getElementById('configurationSelect');
|
2025-05-16 09:21:11 +08:00
|
|
|
|
|
|
|
|
|
// 先加载机型列表
|
|
|
|
|
this.loadPlanes().then(() => {
|
|
|
|
|
if (selection.plane) {
|
|
|
|
|
planeSelect.value = selection.plane;
|
|
|
|
|
// 加载该机型下的构型列表
|
2025-05-16 10:26:07 +08:00
|
|
|
|
this.loadConfigurations(selection.plane).then(() => {
|
|
|
|
|
if (selection.configurationId) {
|
|
|
|
|
configurationSelect.value = selection.configurationId;
|
2025-06-06 11:02:12 +08:00
|
|
|
|
// 触发change事件以确保domainId被更新
|
|
|
|
|
configurationSelect.dispatchEvent(new Event('change'));
|
2025-05-16 09:21:11 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-30 13:47:35 +08:00
|
|
|
|
render() {
|
|
|
|
|
this.shadowRoot.innerHTML = `
|
|
|
|
|
<style>
|
|
|
|
|
:host {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tool-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
width: 32px;
|
|
|
|
|
height: 32px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tool-item:hover {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tool-item img {
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 09:21:11 +08:00
|
|
|
|
.select-container {
|
2025-04-30 13:47:35 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 09:21:11 +08:00
|
|
|
|
.select-label {
|
2025-04-30 13:47:35 +08:00
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 10:26:07 +08:00
|
|
|
|
.plane-select, .configuration-select {
|
2025-04-30 13:47:35 +08:00
|
|
|
|
min-width: 120px;
|
|
|
|
|
height: 32px;
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
background-color: white;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.search-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
height: 32px;
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
background-color: white;
|
|
|
|
|
padding: 0 8px;
|
2025-05-16 09:21:11 +08:00
|
|
|
|
margin-left: 50px;
|
2025-04-30 13:47:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.search-box input {
|
|
|
|
|
border: none;
|
|
|
|
|
outline: none;
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
width: 120px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.search-box img {
|
|
|
|
|
width: 16px;
|
|
|
|
|
height: 16px;
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
2025-05-16 09:21:11 +08:00
|
|
|
|
<div class="select-container">
|
|
|
|
|
<span class="select-label">机型:</span>
|
|
|
|
|
<select class="plane-select" id="planeSelect">
|
|
|
|
|
<option value="">选择机型</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="select-container">
|
|
|
|
|
<span class="select-label">构型:</span>
|
2025-05-16 10:26:07 +08:00
|
|
|
|
<select class="configuration-select" id="configurationSelect">
|
2025-04-30 13:47:35 +08:00
|
|
|
|
<option value="">选择构型</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="search-box">
|
|
|
|
|
<input type="text" placeholder="搜索...">
|
|
|
|
|
<img src="assets/icons/png/search_b.png" alt="搜索">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tool-item" id="fontSizeBtn" title="调整字体大小">
|
|
|
|
|
<img src="assets/icons/png/font_b.png" alt="字体">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tool-item" id="themeBtn" title="调整主题">
|
|
|
|
|
<img src="assets/icons/png/palette_b.png" alt="主题">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tool-item" id="notificationBtn" title="通知">
|
|
|
|
|
<img src="assets/icons/png/bell_b.png" alt="通知">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tool-item" id="onlineUsersBtn" title="在线用户">
|
|
|
|
|
<img src="assets/icons/png/users_b.png" alt="在线用户">
|
|
|
|
|
</div>
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addEventListeners() {
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 加载机型列表
|
|
|
|
|
this.loadPlanes();
|
2025-04-30 13:47:35 +08:00
|
|
|
|
// 加载构型列表
|
2025-05-16 10:26:07 +08:00
|
|
|
|
this.loadConfigurations();
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 恢复上次的选择
|
|
|
|
|
this.restoreSelection();
|
2025-04-30 13:47:35 +08:00
|
|
|
|
|
|
|
|
|
// 字体大小调整
|
|
|
|
|
this.shadowRoot.getElementById('fontSizeBtn').addEventListener('click', () => {
|
|
|
|
|
this.dispatchEvent(new CustomEvent('font-size-click'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 主题调整
|
|
|
|
|
this.shadowRoot.getElementById('themeBtn').addEventListener('click', () => {
|
|
|
|
|
this.dispatchEvent(new CustomEvent('theme-click'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 通知
|
|
|
|
|
this.shadowRoot.getElementById('notificationBtn').addEventListener('click', () => {
|
|
|
|
|
this.dispatchEvent(new CustomEvent('notification-click'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 在线用户
|
|
|
|
|
this.shadowRoot.getElementById('onlineUsersBtn').addEventListener('click', () => {
|
|
|
|
|
this.dispatchEvent(new CustomEvent('online-users-click'));
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 机型选择
|
|
|
|
|
this.shadowRoot.getElementById('planeSelect').addEventListener('change', (e) => {
|
|
|
|
|
// 当机型改变时,重新加载该机型下的构型列表
|
2025-05-16 10:26:07 +08:00
|
|
|
|
this.loadConfigurations(e.target.value);
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 保存选择
|
|
|
|
|
this.saveSelection();
|
|
|
|
|
});
|
|
|
|
|
|
2025-04-30 13:47:35 +08:00
|
|
|
|
// 构型选择
|
2025-05-16 10:26:07 +08:00
|
|
|
|
this.shadowRoot.getElementById('configurationSelect').addEventListener('change', (e) => {
|
2025-05-16 09:21:11 +08:00
|
|
|
|
// 保存选择
|
|
|
|
|
this.saveSelection();
|
2025-04-30 13:47:35 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 09:21:11 +08:00
|
|
|
|
async loadPlanes() {
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch('/api/planes');
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error('获取机型列表失败');
|
|
|
|
|
}
|
|
|
|
|
const planes = await response.json();
|
|
|
|
|
const select = this.shadowRoot.getElementById('planeSelect');
|
|
|
|
|
|
|
|
|
|
// 清空现有选项
|
|
|
|
|
select.innerHTML = '<option value="">选择机型</option>';
|
|
|
|
|
|
|
|
|
|
planes.forEach(plane => {
|
|
|
|
|
const option = document.createElement('option');
|
|
|
|
|
option.value = plane.PlaneName;
|
|
|
|
|
option.textContent = plane.PlaneName;
|
|
|
|
|
select.appendChild(option);
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('加载机型列表失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-16 10:26:07 +08:00
|
|
|
|
async loadConfigurations(planeName = '') {
|
2025-04-30 13:47:35 +08:00
|
|
|
|
try {
|
2025-05-16 09:21:11 +08:00
|
|
|
|
const url = planeName ? `/api/configurations?plane=${planeName}` : '/api/configurations';
|
|
|
|
|
const response = await fetch(url);
|
2025-04-30 13:47:35 +08:00
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error('获取构型列表失败');
|
|
|
|
|
}
|
2025-05-16 10:26:07 +08:00
|
|
|
|
const configurations = await response.json();
|
|
|
|
|
const select = this.shadowRoot.getElementById('configurationSelect');
|
2025-04-30 13:47:35 +08:00
|
|
|
|
|
|
|
|
|
// 清空现有选项
|
|
|
|
|
select.innerHTML = '<option value="">选择构型</option>';
|
|
|
|
|
|
2025-05-16 10:26:07 +08:00
|
|
|
|
configurations.forEach(config => {
|
2025-04-30 13:47:35 +08:00
|
|
|
|
const option = document.createElement('option');
|
2025-05-16 10:26:07 +08:00
|
|
|
|
option.value = config.ConfID;
|
|
|
|
|
option.textContent = config.ConfName;
|
2025-06-06 11:02:12 +08:00
|
|
|
|
// 将DomainID存储在option的data属性中
|
|
|
|
|
option.dataset.domainId = config.DomainID;
|
2025-04-30 13:47:35 +08:00
|
|
|
|
select.appendChild(option);
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('加载构型列表失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
customElements.define('header-tools', HeaderTools);
|