488 lines
19 KiB
JavaScript
Raw Normal View History

class VariableForm extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.mode = 'add';
this.interfaceData = null;
this.planes = [];
2025-05-07 13:46:48 +08:00
this.ataChapters = [];
this.modelStructs = [];
}
connectedCallback() {
this.render();
this.addEventListeners();
}
2025-05-07 13:46:48 +08:00
// 接收父组件传递的选项数据
setOptions(planes, atas) {
this.planes = planes;
2025-05-07 13:46:48 +08:00
this.ataChapters = atas;
this.updatePlaneOptions();
2025-05-07 13:46:48 +08:00
this.updateAtaOptions();
}
updatePlaneOptions() {
const select = this.shadowRoot.querySelector('#planeName');
2025-05-07 13:46:48 +08:00
if (select) {
select.innerHTML = `
<option value="">请选择机型</option>
${this.planes.map(plane => `
<option value="${plane}" ${this.interfaceData?.PlaneName === plane ? 'selected' : ''}>
${plane}
2025-05-07 13:46:48 +08:00
</option>
`).join('')}
`;
}
}
updateAtaOptions() {
const select = this.shadowRoot.querySelector('#ataName');
if (select) {
select.innerHTML = `
<option value="">请选择ATA章节</option>
${this.ataChapters.map(chapter => `
<option value="${chapter}" ${this.interfaceData?.ATAName === chapter ? 'selected' : ''}>
${chapter}
</option>
`).join('')}
`;
}
}
async loadModelStructs(planeName, ataName) {
2025-05-07 13:46:48 +08:00
try {
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}`);
2025-05-07 13:46:48 +08:00
if (!response.ok) {
throw new Error('获取模型结构体列表失败');
}
const data = await response.json();
this.modelStructs = data.map(item => item.ModelStructName);
this.updateModelStructSelect();
} catch (error) {
console.error('加载模型结构体列表失败:', error);
alert(error.message || '加载模型结构体列表失败');
2025-05-07 13:46:48 +08:00
}
}
updateModelStructSelect() {
const select = this.shadowRoot.querySelector('#modelStructName');
if (select) {
select.innerHTML = `
<option value="">请选择模型结构体</option>
${this.modelStructs.map(struct => `
<option value="${struct}" ${this.interfaceData?.ModelStructName === struct ? 'selected' : ''}>
${struct}
</option>
`).join('')}
`;
}
}
setMode(mode, data = null) {
this.mode = mode;
this.interfaceData = data;
2025-05-07 13:46:48 +08:00
if (data) {
// 保存原始数据
this.originalData = {
PlaneName: data.PlaneName,
2025-05-07 13:46:48 +08:00
ATAName: data.ATAName,
ModelStructName: data.ModelStructName,
InterfaceName: data.InterfaceName
};
// 如果是在编辑模式下,需要先加载模型结构体列表
this.loadModelStructs(data.PlaneName, data.ATAName).then(() => {
2025-05-07 13:46:48 +08:00
this.render();
this.addEventListeners();
this.show();
});
} else {
this.render();
this.addEventListeners();
this.show();
}
}
show() {
2025-05-07 13:46:48 +08:00
const overlay = this.shadowRoot.querySelector('.form-overlay');
if (overlay) {
overlay.style.display = 'block';
}
}
hide() {
2025-05-07 13:46:48 +08:00
const overlay = this.shadowRoot.querySelector('.form-overlay');
if (overlay) {
overlay.style.display = 'none';
}
}
addEventListeners() {
const form = this.shadowRoot.querySelector('form');
const cancelBtn = this.shadowRoot.querySelector('.cancel-btn');
const planeSelect = this.shadowRoot.querySelector('#planeName');
2025-05-07 13:46:48 +08:00
const ataSelect = this.shadowRoot.querySelector('#ataName');
const interfaceNameInput = this.shadowRoot.querySelector('#interfaceName');
const isArrayCheckbox = this.shadowRoot.querySelector('#interfaceIsArray');
const arraySize1Input = this.shadowRoot.querySelector('#interfaceArraySize_1');
const arraySize2Input = this.shadowRoot.querySelector('#interfaceArraySize_2');
// 监听构型和ATA章节的变化
planeSelect.addEventListener('change', () => {
const planeName = planeSelect.value;
2025-05-07 13:46:48 +08:00
const ataName = ataSelect.value;
if (planeName && ataName) {
this.loadModelStructs(planeName, ataName);
2025-05-07 13:46:48 +08:00
}
});
ataSelect.addEventListener('change', () => {
const planeName = planeSelect.value;
2025-05-07 13:46:48 +08:00
const ataName = ataSelect.value;
if (planeName && ataName) {
this.loadModelStructs(planeName, ataName);
2025-05-07 13:46:48 +08:00
}
});
// 验证C++命名规范
interfaceNameInput.addEventListener('input', (e) => {
const value = e.target.value;
// C++命名规范:以字母或下划线开头,只能包含字母、数字和下划线
const isValid = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value);
if (!isValid) {
e.target.setCustomValidity('接口名称必须以字母或下划线开头,只能包含字母、数字和下划线');
} else {
e.target.setCustomValidity('');
}
});
// 验证数组大小
arraySize1Input.addEventListener('input', (e) => {
const value = parseInt(e.target.value);
if (value <= 1) {
e.target.setCustomValidity('第一维大小必须大于1');
} else {
e.target.setCustomValidity('');
}
});
arraySize2Input.addEventListener('input', (e) => {
const value = e.target.value;
if (value && parseInt(value) <= 1 && parseInt(value) !== 0) {
e.target.setCustomValidity('第二维大小必须大于1');
} else {
e.target.setCustomValidity('');
}
});
form.addEventListener('submit', (e) => {
e.preventDefault();
2025-05-07 13:46:48 +08:00
const formData = new FormData(form);
const isArray = formData.get('interfaceIsArray') ? 1 : 0;
const arraySize1 = parseInt(formData.get('interfaceArraySize_1')) || 0;
const arraySize2 = parseInt(formData.get('interfaceArraySize_2')) || 0;
2025-05-07 13:46:48 +08:00
const data = {
SystemName: 'XNSim',
PlaneName: formData.get('planeName'),
ATAName: formData.get('ataName'),
ModelStructName: formData.get('modelStructName'),
InterfaceName: formData.get('interfaceName'),
InterfaceType: formData.get('interfaceType'),
2025-05-07 13:46:48 +08:00
InterfaceOption: 1,
InterfaceIsArray: isArray,
InterfaceArraySize_1: isArray && arraySize1 > 1 ? arraySize1 : 0,
InterfaceArraySize_2: isArray && arraySize1 > 1 ? arraySize2 : 0,
2025-05-07 13:46:48 +08:00
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;
2025-05-07 13:46:48 +08:00
// 如果是编辑模式,添加原始数据
if (this.mode === 'edit' && this.originalData) {
data.originalPlaneName = this.originalData.PlaneName;
2025-05-07 13:46:48 +08:00
data.originalATAName = this.originalData.ATAName;
data.originalModelStructName = this.originalData.ModelStructName;
data.originalInterfaceName = this.originalData.InterfaceName;
}
// 验证必填字段
const requiredFields = [
'SystemName',
'PlaneName',
2025-05-07 13:46:48 +08:00
'ATAName',
'ModelStructName',
'InterfaceName',
'InterfaceType',
'ConfID'
2025-05-07 13:46:48 +08:00
];
const missingFields = requiredFields.filter(field => !data[field]);
if (missingFields.length > 0) {
alert(`请填写以下必填字段:${missingFields.join(', ')}`);
return;
}
// 如果是数组类型,验证数组大小
if (data.InterfaceIsArray === 1) {
if (!data.InterfaceArraySize_1 || data.InterfaceArraySize_1 <= 1) {
alert('第一维大小必须大于1');
return;
}
2025-05-07 13:46:48 +08:00
if (data.InterfaceArraySize_2 && data.InterfaceArraySize_2 <= 1 && data.InterfaceArraySize_2 !== 0) {
alert('第二维大小必须大于1或等于0');
return;
}
}
this.dispatchEvent(new CustomEvent('save-success', {
detail: { ...data, mode: this.mode }
}));
2025-05-07 13:46:48 +08:00
this.hide();
});
2025-05-07 13:46:48 +08:00
cancelBtn.addEventListener('click', () => {
this.hide();
});
2025-05-07 13:46:48 +08:00
// 监听数组大小输入框的变化
isArrayCheckbox.addEventListener('change', () => {
arraySize1Input.disabled = !isArrayCheckbox.checked;
arraySize2Input.disabled = !isArrayCheckbox.checked;
if (!isArrayCheckbox.checked) {
arraySize1Input.value = '';
arraySize2Input.value = '';
}
});
}
render() {
2025-05-07 13:46:48 +08:00
const interfaceTypes = [
'char', 'octet', 'short', 'unsigned short',
'long', 'unsigned long', 'long long', 'unsigned long long',
'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 = `
<style>
2025-05-07 13:46:48 +08:00
.form-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
2025-05-07 13:46:48 +08:00
.form-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 8px;
2025-05-07 13:46:48 +08:00
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 500px;
max-height: 90vh;
overflow-y: auto;
}
.form-title {
2025-05-07 13:46:48 +08:00
margin: 0 0 20px 0;
font-size: 18px;
font-weight: bold;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
2025-05-07 13:46:48 +08:00
select, input[type="text"], input[type="number"] {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
2025-05-07 13:46:48 +08:00
.checkbox-group {
display: flex;
align-items: center;
gap: 5px;
}
2025-05-07 13:46:48 +08:00
.checkbox-group input[type="checkbox"] {
width: auto;
}
.button-group {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}
2025-05-07 13:46:48 +08:00
button {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.save-btn {
background-color: #4CAF50;
color: white;
}
.cancel-btn {
background-color: #f44336;
color: white;
}
2025-05-07 13:46:48 +08:00
button:hover {
opacity: 0.9;
}
.array-size-group {
display: flex;
gap: 10px;
align-items: center;
}
.array-size-group input[type="number"] {
width: 100px;
}
.plane-info {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
}
</style>
2025-05-07 13:46:48 +08:00
<div class="form-overlay">
<div class="form-container">
<h2 class="form-title">${this.mode === 'add' ? '添加接口' : '编辑接口'}</h2>
<div class="plane-info">
当前机型${planeName}
</div>
<form>
<input type="hidden" id="planeName" name="planeName" value="${planeName}">
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label for="ataName">ATA章节</label>
<select id="ataName" name="ataName" required>
<option value="">请选择ATA章节</option>
${this.ataChapters.map(chapter => `
<option value="${chapter}" ${this.interfaceData?.ATAName === chapter ? 'selected' : ''}>
${chapter}
</option>
`).join('')}
</select>
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label for="modelStructName">接口结构体名</label>
<select id="modelStructName" name="modelStructName" required>
<option value="">请选择接口结构体</option>
${this.modelStructs.map(struct => `
<option value="${struct}" ${this.interfaceData?.ModelStructName === struct ? 'selected' : ''}>
${struct}
</option>
`).join('')}
</select>
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label for="interfaceName">接口名称</label>
<input type="text" id="interfaceName" name="interfaceName" required
value="${this.interfaceData?.InterfaceName || ''}">
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label for="interfaceType">数据类型</label>
<select id="interfaceType" name="interfaceType" required>
<option value="">请选择数据类型</option>
${interfaceTypes.map(type => `
<option value="${type}" ${this.interfaceData?.InterfaceType === type ? 'selected' : ''}>
${type}
</option>
`).join('')}
</select>
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<div class="checkbox-group">
<input type="checkbox" id="interfaceIsArray" name="interfaceIsArray"
${this.interfaceData?.InterfaceIsArray === 1 ? 'checked' : ''}>
<label for="interfaceIsArray">是否为数组</label>
</div>
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label>数组大小</label>
<div class="array-size-group">
<input type="number" id="interfaceArraySize_1" name="interfaceArraySize_1"
value="${this.interfaceData?.InterfaceArraySize_1 || ''}"
${this.interfaceData?.InterfaceIsArray !== 1 ? 'disabled' : ''}
placeholder="第一维">
<span>×</span>
<input type="number" id="interfaceArraySize_2" name="interfaceArraySize_2"
value="${this.interfaceData?.InterfaceArraySize_2 || ''}"
${this.interfaceData?.InterfaceIsArray !== 1 ? 'disabled' : ''}
placeholder="第二维">
</div>
</div>
2025-05-07 13:46:48 +08:00
<div class="form-group">
2025-05-07 13:46:48 +08:00
<label for="interfaceNotes">备注</label>
<input type="text" id="interfaceNotes" name="interfaceNotes"
value="${this.interfaceData?.InterfaceNotes || ''}">
</div>
2025-05-07 13:46:48 +08:00
<div class="button-group">
<button type="button" class="cancel-btn">取消</button>
<button type="submit" class="save-btn">保存</button>
</div>
</form>
</div>
</div>
`;
}
}
customElements.define('variable-form', VariableForm);