接口配置已适配新数据库结构

This commit is contained in:
jinchao 2025-05-16 10:26:07 +08:00
parent 61cfdb94e9
commit b5d652a77e
7 changed files with 235 additions and 185 deletions

Binary file not shown.

View File

@ -11,15 +11,15 @@ class HeaderTools extends HTMLElement {
return this.shadowRoot.getElementById('planeSelect').value; return this.shadowRoot.getElementById('planeSelect').value;
} }
get selectedProduct() { get selectedConfiguration() {
return this.shadowRoot.getElementById('productSelect').value; return this.shadowRoot.getElementById('configurationSelect').value;
} }
// 保存选择到localStorage // 保存选择到localStorage
saveSelection() { saveSelection() {
const selection = { const selection = {
plane: this.selectedPlane, plane: this.selectedPlane,
product: this.selectedProduct configurationId: this.selectedConfiguration
}; };
localStorage.setItem('xnsim-selection', JSON.stringify(selection)); localStorage.setItem('xnsim-selection', JSON.stringify(selection));
} }
@ -30,16 +30,16 @@ class HeaderTools extends HTMLElement {
if (savedSelection) { if (savedSelection) {
const selection = JSON.parse(savedSelection); const selection = JSON.parse(savedSelection);
const planeSelect = this.shadowRoot.getElementById('planeSelect'); const planeSelect = this.shadowRoot.getElementById('planeSelect');
const productSelect = this.shadowRoot.getElementById('productSelect'); const configurationSelect = this.shadowRoot.getElementById('configurationSelect');
// 先加载机型列表 // 先加载机型列表
this.loadPlanes().then(() => { this.loadPlanes().then(() => {
if (selection.plane) { if (selection.plane) {
planeSelect.value = selection.plane; planeSelect.value = selection.plane;
// 加载该机型下的构型列表 // 加载该机型下的构型列表
this.loadProducts(selection.plane).then(() => { this.loadConfigurations(selection.plane).then(() => {
if (selection.product) { if (selection.configurationId) {
productSelect.value = selection.product; configurationSelect.value = selection.configurationId;
} }
}); });
} }
@ -88,7 +88,7 @@ class HeaderTools extends HTMLElement {
color: #666; color: #666;
} }
.plane-select, .product-select { .plane-select, .configuration-select {
min-width: 120px; min-width: 120px;
height: 32px; height: 32px;
padding: 0 8px; padding: 0 8px;
@ -130,7 +130,7 @@ class HeaderTools extends HTMLElement {
</div> </div>
<div class="select-container"> <div class="select-container">
<span class="select-label">构型</span> <span class="select-label">构型</span>
<select class="product-select" id="productSelect"> <select class="configuration-select" id="configurationSelect">
<option value="">选择构型</option> <option value="">选择构型</option>
</select> </select>
</div> </div>
@ -157,7 +157,7 @@ class HeaderTools extends HTMLElement {
// 加载机型列表 // 加载机型列表
this.loadPlanes(); this.loadPlanes();
// 加载构型列表 // 加载构型列表
this.loadProducts(); this.loadConfigurations();
// 恢复上次的选择 // 恢复上次的选择
this.restoreSelection(); this.restoreSelection();
@ -187,15 +187,19 @@ class HeaderTools extends HTMLElement {
detail: { plane: e.target.value } detail: { plane: e.target.value }
})); }));
// 当机型改变时,重新加载该机型下的构型列表 // 当机型改变时,重新加载该机型下的构型列表
this.loadProducts(e.target.value); this.loadConfigurations(e.target.value);
// 保存选择 // 保存选择
this.saveSelection(); this.saveSelection();
}); });
// 构型选择 // 构型选择
this.shadowRoot.getElementById('productSelect').addEventListener('change', (e) => { this.shadowRoot.getElementById('configurationSelect').addEventListener('change', (e) => {
this.dispatchEvent(new CustomEvent('product-change', { const selectedOption = e.target.options[e.target.selectedIndex];
detail: { product: e.target.value } this.dispatchEvent(new CustomEvent('configuration-change', {
detail: {
configurationId: e.target.value,
configurationName: selectedOption.textContent
}
})); }));
// 保存选择 // 保存选择
this.saveSelection(); this.saveSelection();
@ -225,23 +229,23 @@ class HeaderTools extends HTMLElement {
} }
} }
async loadProducts(planeName = '') { async loadConfigurations(planeName = '') {
try { try {
const url = planeName ? `/api/configurations?plane=${planeName}` : '/api/configurations'; const url = planeName ? `/api/configurations?plane=${planeName}` : '/api/configurations';
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {
throw new Error('获取构型列表失败'); throw new Error('获取构型列表失败');
} }
const products = await response.json(); const configurations = await response.json();
const select = this.shadowRoot.getElementById('productSelect'); const select = this.shadowRoot.getElementById('configurationSelect');
// 清空现有选项 // 清空现有选项
select.innerHTML = '<option value="">选择构型</option>'; select.innerHTML = '<option value="">选择构型</option>';
products.forEach(product => { configurations.forEach(config => {
const option = document.createElement('option'); const option = document.createElement('option');
option.value = product.ConfName; option.value = config.ConfID;
option.textContent = product.ConfName; option.textContent = config.ConfName;
select.appendChild(option); select.appendChild(option);
}); });
} catch (error) { } catch (error) {

View File

@ -8,7 +8,7 @@ class InterfaceConfig extends HTMLElement {
super(); super();
this.attachShadow({ mode: 'open' }); this.attachShadow({ mode: 'open' });
this.data = []; this.data = [];
this.products = []; // 存储构型列表 this.planes = []; // 存储构型列表
this.atas = []; // 存储ATA章节列表 this.atas = []; // 存储ATA章节列表
} }
@ -39,16 +39,25 @@ class InterfaceConfig extends HTMLElement {
} }
if (!confirm(`确定要删除选中的 ${selectedRows.length} 个接口吗?`)) { if (!confirm(`确定要删除选中的 ${selectedRows.length} 个接口吗?`)) {
return; return;
} }
try {
const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
throw new Error('请先选择构型');
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
throw new Error('请先选择构型');
}
try {
const deletePromises = selectedRows.map(row => { const deletePromises = selectedRows.map(row => {
const { SystemName, ProductName, ATAName, ModelStructName, InterfaceName } = row; const { InterfaceName } = row;
return fetch(`/api/interface/delete?systemName=${SystemName}&productName=${ProductName}&ataName=${ATAName}&modelStructName=${ModelStructName}&interfaceName=${InterfaceName}`, { return fetch(`/api/interface/delete?interfaceName=${InterfaceName}&confID=${selection.configurationId}`, {
method: 'DELETE' method: 'DELETE'
}); });
}); });
const results = await Promise.all(deletePromises); const results = await Promise.all(deletePromises);
const failed = results.some(result => !result.ok); const failed = results.some(result => !result.ok);
@ -61,30 +70,7 @@ class InterfaceConfig extends HTMLElement {
alert('删除成功'); alert('删除成功');
} catch (error) { } catch (error) {
console.error('删除接口时出错:', error); console.error('删除接口时出错:', error);
alert('删除接口失败'); alert(error.message || '删除接口失败');
}
});
// 下载模板事件
toolbar.addEventListener('download-template', async () => {
try {
const response = await fetch('/api/interface/template');
if (!response.ok) {
throw new Error('下载模板失败');
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '接口变量模板.xlsx';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (error) {
console.error('下载模板时出错:', error);
alert('下载模板失败');
} }
}); });
@ -123,14 +109,29 @@ class InterfaceConfig extends HTMLElement {
importDialog.addEventListener('confirm-import', async (e) => { importDialog.addEventListener('confirm-import', async (e) => {
const importData = e.detail; const importData = e.detail;
try { try {
console.log('准备导入的数据:', importData); const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
throw new Error('请先选择构型');
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
throw new Error('请先选择构型');
}
// 为每个导入项添加 confID
const importDataWithConfID = importData.map(item => ({
...item,
ConfID: selection.configurationId
}));
console.log('准备导入的数据:', importDataWithConfID);
const response = await fetch('/api/interface/import', { const response = await fetch('/api/interface/import', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(importData) body: JSON.stringify(importDataWithConfID)
}); });
if (!response.ok) { if (!response.ok) {
@ -147,7 +148,7 @@ class InterfaceConfig extends HTMLElement {
} }
} catch (error) { } catch (error) {
console.error('保存导入数据时出错:', error); console.error('保存导入数据时出错:', error);
alert('保存导入数据失败: ' + error.message); alert(error.message || '保存导入数据失败');
} }
}); });
@ -156,7 +157,7 @@ class InterfaceConfig extends HTMLElement {
const variableForm = this.shadowRoot.querySelector('variable-form'); const variableForm = this.shadowRoot.querySelector('variable-form');
if (variableForm) { if (variableForm) {
// 确保在设置编辑数据之前先设置选项 // 确保在设置编辑数据之前先设置选项
variableForm.setOptions(this.products, this.atas); variableForm.setOptions(this.planes, this.atas);
// 先显示表单,再设置模式和数据 // 先显示表单,再设置模式和数据
variableForm.show(); variableForm.show();
variableForm.setMode('edit', e.detail); variableForm.setMode('edit', e.detail);
@ -165,10 +166,19 @@ class InterfaceConfig extends HTMLElement {
// 表格删除按钮事件 // 表格删除按钮事件
dataTable.addEventListener('delete', async (e) => { dataTable.addEventListener('delete', async (e) => {
const { SystemName, ProductName, ATAName, ModelStructName, InterfaceName } = e.detail; const { InterfaceName } = e.detail;
try { try {
const response = await fetch(`/api/interface/delete?systemName=${SystemName}&productName=${ProductName}&ataName=${ATAName}&modelStructName=${ModelStructName}&interfaceName=${InterfaceName}`, { const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
throw new Error('请先选择构型');
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
throw new Error('请先选择构型');
}
const response = await fetch(`/api/interface/delete?interfaceName=${InterfaceName}&confID=${selection.configurationId}`, {
method: 'DELETE' method: 'DELETE'
}); });
@ -180,7 +190,7 @@ class InterfaceConfig extends HTMLElement {
alert('删除成功'); alert('删除成功');
} catch (error) { } catch (error) {
console.error('删除接口时出错:', error); console.error('删除接口时出错:', error);
alert('删除接口失败'); alert(error.message || '删除接口失败');
} }
}); });
@ -195,7 +205,7 @@ class InterfaceConfig extends HTMLElement {
const requestData = interfaceData.mode === 'edit' ? { const requestData = interfaceData.mode === 'edit' ? {
currentData: { currentData: {
SystemName: 'XNSim', SystemName: 'XNSim',
ProductName: interfaceData.ProductName, PlaneName: interfaceData.PlaneName,
ATAName: interfaceData.ATAName, ATAName: interfaceData.ATAName,
ModelStructName: interfaceData.ModelStructName, ModelStructName: interfaceData.ModelStructName,
InterfaceName: interfaceData.InterfaceName, InterfaceName: interfaceData.InterfaceName,
@ -204,18 +214,19 @@ class InterfaceConfig extends HTMLElement {
InterfaceIsArray: interfaceData.InterfaceIsArray, InterfaceIsArray: interfaceData.InterfaceIsArray,
InterfaceArraySize_1: interfaceData.InterfaceArraySize_1, InterfaceArraySize_1: interfaceData.InterfaceArraySize_1,
InterfaceArraySize_2: interfaceData.InterfaceArraySize_2, InterfaceArraySize_2: interfaceData.InterfaceArraySize_2,
InterfaceNotes: interfaceData.InterfaceNotes InterfaceNotes: interfaceData.InterfaceNotes,
ConfID: interfaceData.ConfID
}, },
originalData: { originalData: {
SystemName: 'XNSim', SystemName: 'XNSim',
ProductName: interfaceData.originalProductName || interfaceData.ProductName, PlaneName: interfaceData.originalPlaneName || interfaceData.PlaneName,
ATAName: interfaceData.originalATAName || interfaceData.ATAName, ATAName: interfaceData.originalATAName || interfaceData.ATAName,
ModelStructName: interfaceData.originalModelStructName || interfaceData.ModelStructName, ModelStructName: interfaceData.originalModelStructName || interfaceData.ModelStructName,
InterfaceName: interfaceData.originalInterfaceName || interfaceData.InterfaceName InterfaceName: interfaceData.originalInterfaceName || interfaceData.InterfaceName
} }
} : { } : {
SystemName: 'XNSim', SystemName: 'XNSim',
ProductName: interfaceData.ProductName, PlaneName: interfaceData.PlaneName,
ATAName: interfaceData.ATAName, ATAName: interfaceData.ATAName,
ModelStructName: interfaceData.ModelStructName, ModelStructName: interfaceData.ModelStructName,
InterfaceName: interfaceData.InterfaceName, InterfaceName: interfaceData.InterfaceName,
@ -224,7 +235,8 @@ class InterfaceConfig extends HTMLElement {
InterfaceIsArray: interfaceData.InterfaceIsArray, InterfaceIsArray: interfaceData.InterfaceIsArray,
InterfaceArraySize_1: interfaceData.InterfaceArraySize_1, InterfaceArraySize_1: interfaceData.InterfaceArraySize_1,
InterfaceArraySize_2: interfaceData.InterfaceArraySize_2, InterfaceArraySize_2: interfaceData.InterfaceArraySize_2,
InterfaceNotes: interfaceData.InterfaceNotes InterfaceNotes: interfaceData.InterfaceNotes,
ConfID: interfaceData.ConfID
}; };
const response = await fetch(url, { const response = await fetch(url, {
@ -288,14 +300,24 @@ class InterfaceConfig extends HTMLElement {
async loadData() { async loadData() {
try { try {
const response = await fetch('/api/interface/list'); // 从 localStorage 获取选择
const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
throw new Error('请先选择构型');
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
throw new Error('请先选择构型');
}
const response = await fetch(`/api/interface/list?systemName=XNSim&confID=${selection.configurationId}`);
if (!response.ok) { if (!response.ok) {
throw new Error('获取数据失败'); throw new Error('获取数据失败');
} }
this.data = await response.json(); this.data = await response.json();
// 从接口数据中提取构型和ATA章节列表 // 从接口数据中提取型和ATA章节列表
this.products = [...new Set(this.data.map(item => item.ProductName))]; this.planes = [...new Set(this.data.map(item => item.PlaneName))];
this.atas = [...new Set(this.data.map(item => item.ATAName))]; this.atas = [...new Set(this.data.map(item => item.ATAName))];
this.updateTable(); this.updateTable();
@ -304,16 +326,16 @@ class InterfaceConfig extends HTMLElement {
// 通知所有子组件数据已更新 // 通知所有子组件数据已更新
const importDialog = this.shadowRoot.querySelector('import-dialog'); const importDialog = this.shadowRoot.querySelector('import-dialog');
if (importDialog) { if (importDialog) {
importDialog.setOptions(this.products, this.atas); importDialog.setOptions(this.planes, this.atas);
} }
const variableForm = this.shadowRoot.querySelector('variable-form'); const variableForm = this.shadowRoot.querySelector('variable-form');
if (variableForm) { if (variableForm) {
variableForm.setOptions(this.products, this.atas); variableForm.setOptions(this.planes, this.atas);
} }
} catch (error) { } catch (error) {
console.error('加载数据时出错:', error); console.error('加载数据时出错:', error);
alert('加载数据失败'); alert(error.message || '加载数据失败');
} }
} }
@ -333,7 +355,7 @@ class InterfaceConfig extends HTMLElement {
// 更新下拉选项 // 更新下拉选项
toolbar.updateFilterOptions({ toolbar.updateFilterOptions({
products: this.products, planes: this.planes,
atas: this.atas, atas: this.atas,
structs structs
}); });

View File

@ -7,7 +7,7 @@ class InterfaceDataTable extends HTMLElement {
this.selectedRows = new Set(); this.selectedRows = new Set();
this.searchKeyword = ''; this.searchKeyword = '';
this.filters = { this.filters = {
productName: '', planeName: '',
ataName: '', ataName: '',
structName: '' structName: ''
}; };
@ -92,7 +92,7 @@ class InterfaceDataTable extends HTMLElement {
// 重置所有筛选条件 // 重置所有筛选条件
this.searchKeyword = ''; this.searchKeyword = '';
this.filters = { this.filters = {
productName: '', planeName: '',
ataName: '', ataName: '',
structName: '' structName: ''
}; };
@ -164,9 +164,9 @@ class InterfaceDataTable extends HTMLElement {
// 首先根据高级搜索条件过滤 // 首先根据高级搜索条件过滤
let filtered = [...this.data]; let filtered = [...this.data];
if (this.filters.productName) { if (this.filters.planeName) {
filtered = filtered.filter(item => filtered = filtered.filter(item =>
item.ProductName === this.filters.productName item.PlaneName === this.filters.planeName
); );
} }
if (this.filters.ataName) { if (this.filters.ataName) {
@ -209,8 +209,11 @@ class InterfaceDataTable extends HTMLElement {
this.selectedRows.clear(); this.selectedRows.clear();
// 设置新数据 // 设置新数据
this.data = data; this.data = data.map((item, index) => ({
this.filteredData = [...data]; ...item,
_displayIndex: index
}));
this.filteredData = [...this.data];
this.currentPage = 1; this.currentPage = 1;
this.render(); this.render();
} finally { } finally {
@ -238,11 +241,7 @@ class InterfaceDataTable extends HTMLElement {
getCurrentPageData() { getCurrentPageData() {
const start = (this.currentPage - 1) * this.pageSize; const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize; return this.filteredData.slice(start, start + this.pageSize);
return this.filteredData.slice(start, end).map((item, index) => ({
...item,
_displayIndex: start + index
}));
} }
setPage(page) { setPage(page) {
@ -323,7 +322,7 @@ class InterfaceDataTable extends HTMLElement {
text-align: center; text-align: center;
} }
.product-cell { .plane-cell {
width: 60px; width: 60px;
} }
@ -435,7 +434,7 @@ class InterfaceDataTable extends HTMLElement {
<th class="checkbox-cell"> <th class="checkbox-cell">
<input type="checkbox" id="selectAll"> <input type="checkbox" id="selectAll">
</th> </th>
<th class="product-cell"></th> <th class="plane-cell"></th>
<th class="ata-cell">ATA章节</th> <th class="ata-cell">ATA章节</th>
<th class="struct-cell">接口结构体名</th> <th class="struct-cell">接口结构体名</th>
<th class="interface-cell">接口名称</th> <th class="interface-cell">接口名称</th>
@ -451,16 +450,16 @@ class InterfaceDataTable extends HTMLElement {
<td class="checkbox-cell"> <td class="checkbox-cell">
<input type="checkbox" class="row-checkbox" data-index="${item._displayIndex}"> <input type="checkbox" class="row-checkbox" data-index="${item._displayIndex}">
</td> </td>
<td>${item.ProductName || ''}</td> <td>${item.PlaneName || ''}</td>
<td>${item.ATAName || ''}</td> <td>${item.ATAName || ''}</td>
<td>${item.ModelStructName || ''}</td> <td>${item.ModelStructName || ''}</td>
<td>${item.InterfaceName || ''}</td> <td>${item.InterfaceName || ''}</td>
<td>${item.InterfaceType || ''}</td> <td>${item.InterfaceType || ''}</td>
<td>${this.formatArraySize(item)}</td> <td>${this.formatArraySize(item)}</td>
<td>${item.InterfaceNotes || ''}</td> <td>${item.InterfaceNotes || ''}</td>
<td> <td class="action-cell">
<button type="button" class="action-btn edit-btn" data-index="${item._displayIndex}">编辑</button> <button class="action-btn edit-btn" data-index="${item._displayIndex}">编辑</button>
<button type="button" class="action-btn delete-btn" data-index="${item._displayIndex}">删除</button> <button class="action-btn delete-btn" data-index="${item._displayIndex}">删除</button>
</td> </td>
</tr> </tr>
`).join('')} `).join('')}
@ -471,19 +470,19 @@ class InterfaceDataTable extends HTMLElement {
<div class="loading-spinner"></div> <div class="loading-spinner"></div>
</div> </div>
` : ''} ` : ''}
</div> <div class="pagination">
<div class="pagination"> <button id="firstPage" ${this.currentPage === 1 ? 'disabled' : ''}>首页</button>
<button id="firstPage" ${this.currentPage === 1 ? 'disabled' : ''}></button> <button id="prevPage" ${this.currentPage === 1 ? 'disabled' : ''}>上一</button>
<button id="prevPage" ${this.currentPage === 1 ? 'disabled' : ''}>上一页</button> <span class="page-info"> ${this.currentPage} / ${this.getTotalPages()} </span>
<span class="page-info"> ${this.currentPage} / ${this.getTotalPages()} </span> <button id="nextPage" ${this.currentPage === this.getTotalPages() ? 'disabled' : ''}>下一页</button>
<button id="nextPage" ${this.currentPage === this.getTotalPages() ? 'disabled' : ''}>下一</button> <button id="lastPage" ${this.currentPage === this.getTotalPages() ? 'disabled' : ''}></button>
<button id="lastPage" ${this.currentPage === this.getTotalPages() ? 'disabled' : ''}>末页</button> <select class="page-size-select" id="pageSize">
<select class="page-size-select" id="pageSize"> <option value="10" ${this.pageSize === 10 ? 'selected' : ''}>10/</option>
<option value="10" ${this.pageSize === 10 ? 'selected' : ''}>10/</option> <option value="20" ${this.pageSize === 20 ? 'selected' : ''}>20/</option>
<option value="20" ${this.pageSize === 20 ? 'selected' : ''}>20/</option> <option value="50" ${this.pageSize === 50 ? 'selected' : ''}>50/</option>
<option value="50" ${this.pageSize === 50 ? 'selected' : ''}>50/</option> <option value="100" ${this.pageSize === 100 ? 'selected' : ''}>100/</option>
<option value="100" ${this.pageSize === 100 ? 'selected' : ''}>100/</option> </select>
</select> </div>
</div> </div>
`; `;
this.bindEventListeners(); this.bindEventListeners();
@ -607,7 +606,7 @@ class InterfaceDataTable extends HTMLElement {
const resetSearchHandler = async () => { const resetSearchHandler = async () => {
this.searchKeyword = ''; this.searchKeyword = '';
this.filters = { this.filters = {
productName: '', planeName: '',
ataName: '', ataName: '',
structName: '' structName: ''
}; };

View File

@ -3,7 +3,7 @@ class ImportDialog extends HTMLElement {
super(); super();
this.attachShadow({ mode: 'open' }); this.attachShadow({ mode: 'open' });
this.data = []; this.data = [];
this.products = []; this.planes = [];
this.atas = []; this.atas = [];
} }
@ -13,31 +13,22 @@ class ImportDialog extends HTMLElement {
} }
// 接收父组件传递的选项数据 // 接收父组件传递的选项数据
setOptions(products, atas) { setOptions(planes, atas) {
this.products = products; this.planes = planes;
this.atas = atas; this.atas = atas;
this.updateProductOptions();
this.updateAtaOptions(); this.updateAtaOptions();
} }
updateProductOptions() {
const select = this.shadowRoot.querySelector('#product-select');
select.innerHTML = `
<option value="">请选择构型</option>
${this.products.map(product => `
<option value="${product}">${product}</option>
`).join('')}
`;
}
updateAtaOptions() { updateAtaOptions() {
const select = this.shadowRoot.querySelector('#ata-select'); const select = this.shadowRoot.querySelector('#ata-select');
select.innerHTML = ` if (select) {
<option value="">请选择ATA章节</option> select.innerHTML = `
${this.atas.map(ata => ` <option value="">请选择ATA章节</option>
<option value="${ata}">${ata}</option> ${this.atas.map(ata => `
`).join('')} <option value="${ata}">${ata}</option>
`; `).join('')}
`;
}
} }
show(data) { show(data) {
@ -83,14 +74,21 @@ class ImportDialog extends HTMLElement {
}); });
confirmBtn.addEventListener('click', () => { confirmBtn.addEventListener('click', () => {
const productSelect = this.shadowRoot.querySelector('#product-select');
const ataSelect = this.shadowRoot.querySelector('#ata-select'); const ataSelect = this.shadowRoot.querySelector('#ata-select');
const modelInput = this.shadowRoot.querySelector('#model-input'); const modelInput = this.shadowRoot.querySelector('#model-input');
if (!productSelect.value) { // 从 localStorage 获取机型信息
alert('请选择构型'); const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
alert('请先选择机型');
return; return;
} }
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
alert('请先选择机型');
return;
}
if (!ataSelect.value) { if (!ataSelect.value) {
alert('请选择ATA章节'); alert('请选择ATA章节');
return; return;
@ -105,7 +103,7 @@ class ImportDialog extends HTMLElement {
// 处理数据,转换为数据库格式 // 处理数据,转换为数据库格式
const processedData = this.data.map(item => ({ const processedData = this.data.map(item => ({
SystemName: 'XNSim', // 系统名称固定为XNSim SystemName: 'XNSim', // 系统名称固定为XNSim
ProductName: productSelect.value, PlaneName: selection.plane,
ATAName: ataSelect.value, ATAName: ataSelect.value,
ModelStructName: `${modelName}_${item.structName}`, ModelStructName: `${modelName}_${item.structName}`,
InterfaceName: lowercaseCheckbox.checked ? item.name.toLowerCase() : item.name, InterfaceName: lowercaseCheckbox.checked ? item.name.toLowerCase() : item.name,
@ -114,7 +112,8 @@ class ImportDialog extends HTMLElement {
InterfaceIsArray: item.isArray ? 1 : 0, // 确保是数字类型 InterfaceIsArray: item.isArray ? 1 : 0, // 确保是数字类型
InterfaceArraySize_1: item.arraySize1 || 0, // 确保是数字类型 InterfaceArraySize_1: item.arraySize1 || 0, // 确保是数字类型
InterfaceArraySize_2: item.arraySize2 || 0, // 确保是数字类型 InterfaceArraySize_2: item.arraySize2 || 0, // 确保是数字类型
InterfaceNotes: item.description || '' // 确保不是null InterfaceNotes: item.description || '', // 确保不是null
ConfID: selection.configurationId
})); }));
// 验证数据 // 验证数据
@ -138,6 +137,11 @@ class ImportDialog extends HTMLElement {
} }
render() { render() {
// 从 localStorage 获取机型信息
const savedSelection = localStorage.getItem('xnsim-selection');
const selection = savedSelection ? JSON.parse(savedSelection) : null;
const planeName = selection?.plane || '';
this.shadowRoot.innerHTML = ` this.shadowRoot.innerHTML = `
<style> <style>
:host { :host {
@ -263,19 +267,24 @@ class ImportDialog extends HTMLElement {
background-color: #f44336; background-color: #f44336;
color: white; color: white;
} }
.plane-info {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
font-size: 14px;
}
</style> </style>
<div class="dialog"> <div class="dialog">
<div class="header"> <div class="header">
<div class="title">导入数据预览</div> <div class="title">导入数据预览</div>
<button class="close-btn">&times;</button> <button class="close-btn">&times;</button>
</div> </div>
<div class="plane-info">
当前机型${planeName}
</div>
<div class="options"> <div class="options">
<div class="option-group">
<label for="product-select">构型</label>
<select id="product-select">
<option value="">请选择构型</option>
</select>
</div>
<div class="option-group"> <div class="option-group">
<label for="ata-select">ATA章节</label> <label for="ata-select">ATA章节</label>
<select id="ata-select"> <select id="ata-select">

View File

@ -11,7 +11,7 @@ class InterfaceToolbar extends HTMLElement {
2. IDL文件格式规范 2. IDL文件格式规范
module XNSim { module XNSim {
// 型名称 // 型名称
module C909 { module C909 {
// ATA章节名称 // ATA章节名称
module ATAxx { module ATAxx {
@ -68,7 +68,6 @@ class InterfaceToolbar extends HTMLElement {
const resetBtn = this.shadowRoot.querySelector('.reset-btn'); const resetBtn = this.shadowRoot.querySelector('.reset-btn');
const advancedSearchBtn = this.shadowRoot.querySelector('.advanced-search-btn'); const advancedSearchBtn = this.shadowRoot.querySelector('.advanced-search-btn');
const advancedSearchPanel = this.shadowRoot.querySelector('.advanced-search-panel'); const advancedSearchPanel = this.shadowRoot.querySelector('.advanced-search-panel');
const productSelect = this.shadowRoot.querySelector('#filterProduct');
const ataSelect = this.shadowRoot.querySelector('#filterAta'); const ataSelect = this.shadowRoot.querySelector('#filterAta');
const structSelect = this.shadowRoot.querySelector('#filterStruct'); const structSelect = this.shadowRoot.querySelector('#filterStruct');
const importModal = this.shadowRoot.querySelector('#importModal'); const importModal = this.shadowRoot.querySelector('#importModal');
@ -142,7 +141,6 @@ class InterfaceToolbar extends HTMLElement {
// 重置搜索框 // 重置搜索框
searchInput.value = ''; searchInput.value = '';
// 重置高级搜索下拉框 // 重置高级搜索下拉框
productSelect.value = '';
ataSelect.value = ''; ataSelect.value = '';
structSelect.value = ''; structSelect.value = '';
// 触发重置事件 // 触发重置事件
@ -156,11 +154,10 @@ class InterfaceToolbar extends HTMLElement {
}); });
// 监听高级搜索的筛选条件变化 // 监听高级搜索的筛选条件变化
[productSelect, ataSelect, structSelect].forEach(select => { [ataSelect, structSelect].forEach(select => {
select.addEventListener('change', () => { select.addEventListener('change', () => {
this.dispatchEvent(new CustomEvent('advanced-search', { this.dispatchEvent(new CustomEvent('advanced-search', {
detail: { detail: {
productName: productSelect.value,
ataName: ataSelect.value, ataName: ataSelect.value,
structName: structSelect.value structName: structSelect.value
} }
@ -430,9 +427,6 @@ class InterfaceToolbar extends HTMLElement {
</div> </div>
</div> </div>
<div class="advanced-search-panel"> <div class="advanced-search-panel">
<select id="filterProduct">
<option value="">选择构型</option>
</select>
<select id="filterAta"> <select id="filterAta">
<option value="">选择ATA章节</option> <option value="">选择ATA章节</option>
</select> </select>
@ -480,14 +474,9 @@ class InterfaceToolbar extends HTMLElement {
} }
updateFilterOptions(options) { updateFilterOptions(options) {
const productSelect = this.shadowRoot.querySelector('#filterProduct');
const ataSelect = this.shadowRoot.querySelector('#filterAta'); const ataSelect = this.shadowRoot.querySelector('#filterAta');
const structSelect = this.shadowRoot.querySelector('#filterStruct'); const structSelect = this.shadowRoot.querySelector('#filterStruct');
// 更新构型选项
productSelect.innerHTML = '<option value="">选择构型</option>' +
options.products.map(product => `<option value="${product}">${product}</option>`).join('');
// 更新ATA章节选项 // 更新ATA章节选项
ataSelect.innerHTML = '<option value="">选择ATA章节</option>' + ataSelect.innerHTML = '<option value="">选择ATA章节</option>' +
options.atas.map(ata => `<option value="${ata}">${ata}</option>`).join(''); options.atas.map(ata => `<option value="${ata}">${ata}</option>`).join('');

View File

@ -4,7 +4,7 @@ class VariableForm extends HTMLElement {
this.attachShadow({ mode: 'open' }); this.attachShadow({ mode: 'open' });
this.mode = 'add'; this.mode = 'add';
this.interfaceData = null; this.interfaceData = null;
this.products = []; this.planes = [];
this.ataChapters = []; this.ataChapters = [];
this.modelStructs = []; this.modelStructs = [];
} }
@ -15,21 +15,21 @@ class VariableForm extends HTMLElement {
} }
// 接收父组件传递的选项数据 // 接收父组件传递的选项数据
setOptions(products, atas) { setOptions(planes, atas) {
this.products = products; this.planes = planes;
this.ataChapters = atas; this.ataChapters = atas;
this.updateProductOptions(); this.updatePlaneOptions();
this.updateAtaOptions(); this.updateAtaOptions();
} }
updateProductOptions() { updatePlaneOptions() {
const select = this.shadowRoot.querySelector('#productName'); const select = this.shadowRoot.querySelector('#planeName');
if (select) { if (select) {
select.innerHTML = ` select.innerHTML = `
<option value="">请选择</option> <option value="">请选择</option>
${this.products.map(product => ` ${this.planes.map(plane => `
<option value="${product}" ${this.interfaceData?.ProductName === product ? 'selected' : ''}> <option value="${plane}" ${this.interfaceData?.PlaneName === plane ? 'selected' : ''}>
${product} ${plane}
</option> </option>
`).join('')} `).join('')}
`; `;
@ -50,9 +50,18 @@ class VariableForm extends HTMLElement {
} }
} }
async loadModelStructs(productName, ataName) { async loadModelStructs(planeName, ataName) {
try { try {
const response = await fetch(`/api/interface/struct/list?systemName=XNSim&productName=${productName}&ataName=${ataName}`); const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
throw new Error('请先选择构型');
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
throw new Error('请先选择构型');
}
const response = await fetch(`/api/interface/struct/list?systemName=XNSim&planeName=${planeName}&ataName=${ataName}&confID=${selection.configurationId}`);
if (!response.ok) { if (!response.ok) {
throw new Error('获取模型结构体列表失败'); throw new Error('获取模型结构体列表失败');
} }
@ -61,7 +70,7 @@ class VariableForm extends HTMLElement {
this.updateModelStructSelect(); this.updateModelStructSelect();
} catch (error) { } catch (error) {
console.error('加载模型结构体列表失败:', error); console.error('加载模型结构体列表失败:', error);
alert('加载模型结构体列表失败'); alert(error.message || '加载模型结构体列表失败');
} }
} }
@ -85,13 +94,13 @@ class VariableForm extends HTMLElement {
if (data) { if (data) {
// 保存原始数据 // 保存原始数据
this.originalData = { this.originalData = {
ProductName: data.ProductName, PlaneName: data.PlaneName,
ATAName: data.ATAName, ATAName: data.ATAName,
ModelStructName: data.ModelStructName, ModelStructName: data.ModelStructName,
InterfaceName: data.InterfaceName InterfaceName: data.InterfaceName
}; };
// 如果是在编辑模式下,需要先加载模型结构体列表 // 如果是在编辑模式下,需要先加载模型结构体列表
this.loadModelStructs(data.ProductName, data.ATAName).then(() => { this.loadModelStructs(data.PlaneName, data.ATAName).then(() => {
this.render(); this.render();
this.addEventListeners(); this.addEventListeners();
this.show(); this.show();
@ -120,7 +129,7 @@ class VariableForm extends HTMLElement {
addEventListeners() { addEventListeners() {
const form = this.shadowRoot.querySelector('form'); const form = this.shadowRoot.querySelector('form');
const cancelBtn = this.shadowRoot.querySelector('.cancel-btn'); const cancelBtn = this.shadowRoot.querySelector('.cancel-btn');
const productSelect = this.shadowRoot.querySelector('#productName'); const planeSelect = this.shadowRoot.querySelector('#planeName');
const ataSelect = this.shadowRoot.querySelector('#ataName'); const ataSelect = this.shadowRoot.querySelector('#ataName');
const interfaceNameInput = this.shadowRoot.querySelector('#interfaceName'); const interfaceNameInput = this.shadowRoot.querySelector('#interfaceName');
const isArrayCheckbox = this.shadowRoot.querySelector('#interfaceIsArray'); const isArrayCheckbox = this.shadowRoot.querySelector('#interfaceIsArray');
@ -128,19 +137,19 @@ class VariableForm extends HTMLElement {
const arraySize2Input = this.shadowRoot.querySelector('#interfaceArraySize_2'); const arraySize2Input = this.shadowRoot.querySelector('#interfaceArraySize_2');
// 监听构型和ATA章节的变化 // 监听构型和ATA章节的变化
productSelect.addEventListener('change', () => { planeSelect.addEventListener('change', () => {
const productName = productSelect.value; const planeName = planeSelect.value;
const ataName = ataSelect.value; const ataName = ataSelect.value;
if (productName && ataName) { if (planeName && ataName) {
this.loadModelStructs(productName, ataName); this.loadModelStructs(planeName, ataName);
} }
}); });
ataSelect.addEventListener('change', () => { ataSelect.addEventListener('change', () => {
const productName = productSelect.value; const planeName = planeSelect.value;
const ataName = ataSelect.value; const ataName = ataSelect.value;
if (productName && ataName) { if (planeName && ataName) {
this.loadModelStructs(productName, ataName); this.loadModelStructs(planeName, ataName);
} }
}); });
@ -185,7 +194,7 @@ class VariableForm extends HTMLElement {
const data = { const data = {
SystemName: 'XNSim', SystemName: 'XNSim',
ProductName: formData.get('productName'), PlaneName: formData.get('planeName'),
ATAName: formData.get('ataName'), ATAName: formData.get('ataName'),
ModelStructName: formData.get('modelStructName'), ModelStructName: formData.get('modelStructName'),
InterfaceName: formData.get('interfaceName'), InterfaceName: formData.get('interfaceName'),
@ -197,9 +206,22 @@ class VariableForm extends HTMLElement {
InterfaceNotes: formData.get('interfaceNotes') InterfaceNotes: formData.get('interfaceNotes')
}; };
// 从 localStorage 获取 ConfID
const savedSelection = localStorage.getItem('xnsim-selection');
if (!savedSelection) {
alert('请先选择机型');
return;
}
const selection = JSON.parse(savedSelection);
if (!selection.configurationId) {
alert('请先选择机型');
return;
}
data.ConfID = selection.configurationId;
// 如果是编辑模式,添加原始数据 // 如果是编辑模式,添加原始数据
if (this.mode === 'edit' && this.originalData) { if (this.mode === 'edit' && this.originalData) {
data.originalProductName = this.originalData.ProductName; data.originalPlaneName = this.originalData.PlaneName;
data.originalATAName = this.originalData.ATAName; data.originalATAName = this.originalData.ATAName;
data.originalModelStructName = this.originalData.ModelStructName; data.originalModelStructName = this.originalData.ModelStructName;
data.originalInterfaceName = this.originalData.InterfaceName; data.originalInterfaceName = this.originalData.InterfaceName;
@ -208,11 +230,12 @@ class VariableForm extends HTMLElement {
// 验证必填字段 // 验证必填字段
const requiredFields = [ const requiredFields = [
'SystemName', 'SystemName',
'ProductName', 'PlaneName',
'ATAName', 'ATAName',
'ModelStructName', 'ModelStructName',
'InterfaceName', 'InterfaceName',
'InterfaceType' 'InterfaceType',
'ConfID'
]; ];
const missingFields = requiredFields.filter(field => !data[field]); const missingFields = requiredFields.filter(field => !data[field]);
@ -261,6 +284,11 @@ class VariableForm extends HTMLElement {
'float', 'double', 'long double', 'boolean' 'float', 'double', 'long double', 'boolean'
]; ];
// 从 localStorage 获取机型信息
const savedSelection = localStorage.getItem('xnsim-selection');
const selection = savedSelection ? JSON.parse(savedSelection) : null;
const planeName = selection?.plane || '';
this.shadowRoot.innerHTML = ` this.shadowRoot.innerHTML = `
<style> <style>
.form-overlay { .form-overlay {
@ -359,23 +387,22 @@ class VariableForm extends HTMLElement {
.array-size-group input[type="number"] { .array-size-group input[type="number"] {
width: 100px; width: 100px;
} }
.plane-info {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
}
</style> </style>
<div class="form-overlay"> <div class="form-overlay">
<div class="form-container"> <div class="form-container">
<h2 class="form-title">${this.mode === 'add' ? '添加接口' : '编辑接口'}</h2> <h2 class="form-title">${this.mode === 'add' ? '添加接口' : '编辑接口'}</h2>
<div class="plane-info">
当前机型${planeName}
</div>
<form> <form>
<div class="form-group"> <input type="hidden" id="planeName" name="planeName" value="${planeName}">
<label for="productName">构型</label>
<select id="productName" name="productName" required>
<option value="">请选择构型</option>
${this.products.map(product => `
<option value="${product}" ${this.interfaceData?.ProductName === product ? 'selected' : ''}>
${product}
</option>
`).join('')}
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="ataName">ATA章节</label> <label for="ataName">ATA章节</label>
<select id="ataName" name="ataName" required> <select id="ataName" name="ataName" required>