jinchao a9a4b1832e 修复了编辑非数组变量时不能修改的错误;
修改了导入数据时变量类型不支持时的替换操作
2025-05-07 13:59:43 +08:00

461 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class VariableForm extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.mode = 'add';
this.interfaceData = null;
this.products = [];
this.ataChapters = [];
this.modelStructs = [];
}
connectedCallback() {
this.render();
this.addEventListeners();
}
// 接收父组件传递的选项数据
setOptions(products, atas) {
this.products = products;
this.ataChapters = atas;
this.updateProductOptions();
this.updateAtaOptions();
}
updateProductOptions() {
const select = this.shadowRoot.querySelector('#productName');
if (select) {
select.innerHTML = `
<option value="">请选择构型</option>
${this.products.map(product => `
<option value="${product}" ${this.interfaceData?.ProductName === product ? 'selected' : ''}>
${product}
</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(productName, ataName) {
try {
const response = await fetch(`/api/interface/struct/list?systemName=XNSim&productName=${productName}&ataName=${ataName}`);
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('加载模型结构体列表失败');
}
}
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;
if (data) {
// 保存原始数据
this.originalData = {
ProductName: data.ProductName,
ATAName: data.ATAName,
ModelStructName: data.ModelStructName,
InterfaceName: data.InterfaceName
};
// 如果是在编辑模式下,需要先加载模型结构体列表
this.loadModelStructs(data.ProductName, data.ATAName).then(() => {
this.render();
this.addEventListeners();
this.show();
});
} else {
this.render();
this.addEventListeners();
this.show();
}
}
show() {
const overlay = this.shadowRoot.querySelector('.form-overlay');
if (overlay) {
overlay.style.display = 'block';
}
}
hide() {
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 productSelect = this.shadowRoot.querySelector('#productName');
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章节的变化
productSelect.addEventListener('change', () => {
const productName = productSelect.value;
const ataName = ataSelect.value;
if (productName && ataName) {
this.loadModelStructs(productName, ataName);
}
});
ataSelect.addEventListener('change', () => {
const productName = productSelect.value;
const ataName = ataSelect.value;
if (productName && ataName) {
this.loadModelStructs(productName, ataName);
}
});
// 验证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();
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;
const data = {
SystemName: 'XNSim',
ProductName: formData.get('productName'),
ATAName: formData.get('ataName'),
ModelStructName: formData.get('modelStructName'),
InterfaceName: formData.get('interfaceName'),
InterfaceType: formData.get('interfaceType'),
InterfaceOption: 1,
InterfaceIsArray: isArray,
InterfaceArraySize_1: isArray && arraySize1 > 1 ? arraySize1 : 0,
InterfaceArraySize_2: isArray && arraySize1 > 1 ? arraySize2 : 0,
InterfaceNotes: formData.get('interfaceNotes')
};
// 如果是编辑模式,添加原始数据
if (this.mode === 'edit' && this.originalData) {
data.originalProductName = this.originalData.ProductName;
data.originalATAName = this.originalData.ATAName;
data.originalModelStructName = this.originalData.ModelStructName;
data.originalInterfaceName = this.originalData.InterfaceName;
}
// 验证必填字段
const requiredFields = [
'SystemName',
'ProductName',
'ATAName',
'ModelStructName',
'InterfaceName',
'InterfaceType'
];
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;
}
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 }
}));
this.hide();
});
cancelBtn.addEventListener('click', () => {
this.hide();
});
// 监听数组大小输入框的变化
isArrayCheckbox.addEventListener('change', () => {
arraySize1Input.disabled = !isArrayCheckbox.checked;
arraySize2Input.disabled = !isArrayCheckbox.checked;
if (!isArrayCheckbox.checked) {
arraySize1Input.value = '';
arraySize2Input.value = '';
}
});
}
render() {
const interfaceTypes = [
'char', 'octet', 'short', 'unsigned short',
'long', 'unsigned long', 'long long', 'unsigned long long',
'float', 'double', 'long double', 'boolean'
];
this.shadowRoot.innerHTML = `
<style>
.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;
}
.form-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 500px;
max-height: 90vh;
overflow-y: auto;
}
.form-title {
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;
}
select, input[type="text"], input[type="number"] {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 5px;
}
.checkbox-group input[type="checkbox"] {
width: auto;
}
.button-group {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}
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;
}
button:hover {
opacity: 0.9;
}
.array-size-group {
display: flex;
gap: 10px;
align-items: center;
}
.array-size-group input[type="number"] {
width: 100px;
}
</style>
<div class="form-overlay">
<div class="form-container">
<h2 class="form-title">${this.mode === 'add' ? '添加接口' : '编辑接口'}</h2>
<form>
<div class="form-group">
<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">
<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>
<div class="form-group">
<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>
<div class="form-group">
<label for="interfaceName">接口名称</label>
<input type="text" id="interfaceName" name="interfaceName" required
value="${this.interfaceData?.InterfaceName || ''}">
</div>
<div class="form-group">
<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>
<div class="form-group">
<div class="checkbox-group">
<input type="checkbox" id="interfaceIsArray" name="interfaceIsArray"
${this.interfaceData?.InterfaceIsArray === 1 ? 'checked' : ''}>
<label for="interfaceIsArray">是否为数组</label>
</div>
</div>
<div class="form-group">
<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>
<div class="form-group">
<label for="interfaceNotes">备注</label>
<input type="text" id="interfaceNotes" name="interfaceNotes"
value="${this.interfaceData?.InterfaceNotes || ''}">
</div>
<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);