V0.32.1.250620_alpha:模型开发新增数据包模型上传功能
This commit is contained in:
parent
fa8f4f0234
commit
129e1459ca
0
Release/Configuration/C909_V1/Packages/ATA04_WeightBalance_2.0.14.6H_20241106/std_04_dll.h
Executable file → Normal file
0
Release/Configuration/C909_V1/Packages/ATA04_WeightBalance_2.0.14.6H_20241106/std_04_dll.h
Executable file → Normal file
Binary file not shown.
@ -11,7 +11,7 @@ std::string GenIDL::idlFilePath = "";
|
|||||||
|
|
||||||
bool GenIDL::createConfigDirectory(const std::string &configName)
|
bool GenIDL::createConfigDirectory(const std::string &configName)
|
||||||
{
|
{
|
||||||
std::string dirPath = GetXNCoreEnv() + "/IDL/" + configName;
|
std::string dirPath = GetXNCoreEnv() + "/Configuration/" + configName + "/IDL";
|
||||||
try {
|
try {
|
||||||
fs::create_directories(dirPath);
|
fs::create_directories(dirPath);
|
||||||
GenIDL::idlFilePath = dirPath + "/" + configName + ".idl";
|
GenIDL::idlFilePath = dirPath + "/" + configName + ".idl";
|
||||||
|
@ -21,11 +21,18 @@ class HeaderTools extends HTMLElement {
|
|||||||
return selectedOption ? selectedOption.dataset.domainId : '';
|
return selectedOption ? selectedOption.dataset.domainId : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get selectedConfigurationName() {
|
||||||
|
const select = this.shadowRoot.getElementById('configurationSelect');
|
||||||
|
const selectedOption = select.options[select.selectedIndex];
|
||||||
|
return selectedOption ? selectedOption.textContent : '';
|
||||||
|
}
|
||||||
|
|
||||||
// 保存选择到localStorage
|
// 保存选择到localStorage
|
||||||
saveSelection() {
|
saveSelection() {
|
||||||
const selection = {
|
const selection = {
|
||||||
plane: this.selectedPlane,
|
plane: this.selectedPlane,
|
||||||
configurationId: this.selectedConfiguration,
|
configurationId: this.selectedConfiguration,
|
||||||
|
configurationName: this.selectedConfigurationName,
|
||||||
domainId: this.selectedDomain
|
domainId: this.selectedDomain
|
||||||
};
|
};
|
||||||
localStorage.setItem('xnsim-selection', JSON.stringify(selection));
|
localStorage.setItem('xnsim-selection', JSON.stringify(selection));
|
||||||
|
@ -782,10 +782,12 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ text: '生成代码', color: '#805ad5', action: () => alert('生成代码功能即将上线') },
|
{
|
||||||
{ text: '编辑代码', color: '#d69e2e', action: () => alert('编辑代码功能即将上线') },
|
text: '数据包模型上传',
|
||||||
{ text: '模型编译', color: '#dd6b20', action: () => alert('模型编译功能即将上线') },
|
color: '#dd6b20',
|
||||||
{ text: '模型提交', color: '#e53e3e', action: () => alert('模型提交功能即将上线') }
|
action: () => this.uploadDataPackage()
|
||||||
|
},
|
||||||
|
{ text: '自动封装', color: '#e53e3e', action: () => alert('自动封装功能即将上线') }
|
||||||
];
|
];
|
||||||
|
|
||||||
buttonConfigs.forEach(config => {
|
buttonConfigs.forEach(config => {
|
||||||
@ -878,17 +880,17 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
// 添加左列输入框
|
// 添加左列输入框
|
||||||
const leftAdvancedColumn = document.createElement('div');
|
const leftAdvancedColumn = document.createElement('div');
|
||||||
leftAdvancedColumn.innerHTML = `
|
leftAdvancedColumn.innerHTML = `
|
||||||
<div class="form-group">
|
|
||||||
<label for="codePath">代码路径 (CodePath)</label>
|
|
||||||
<input type="text" id="codePath" name="CodePath" value="${this.currentVersion.CodePath || ''}" title="模型代码文件的路径">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="dataPackagePath">数据包路径 (DataPackagePath)</label>
|
<label for="dataPackagePath">数据包路径 (DataPackagePath)</label>
|
||||||
<input type="text" id="dataPackagePath" name="DataPackagePath" value="${this.currentVersion.DataPackagePath || ''}" title="数据包文件的路径">
|
<input type="text" id="dataPackagePath" name="DataPackagePath" value="${this.currentVersion.DataPackagePath || ''}" title="数据包文件的路径">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="dataPackageHeaderPath">数据包头文件路径 (DataPackageHeaderPath)</label>
|
<label for="dataPackageName">数据包名称 (DataPackageName)</label>
|
||||||
<input type="text" id="dataPackageHeaderPath" name="DataPackageHeaderPath" value="${this.currentVersion.DataPackageHeaderPath || ''}" title="数据包头文件的路径">
|
<input type="text" id="dataPackageName" name="DataPackageName" value="${this.currentVersion.DataPackageName || ''}" title="数据包的名称">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="dataPackageHeaderName">数据包头文件名称 (DataPackageHeaderName)</label>
|
||||||
|
<input type="text" id="dataPackageHeaderName" name="DataPackageHeaderName" value="${this.currentVersion.DataPackageHeaderName || ''}" title="数据包头文件的名称">
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -952,6 +954,39 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
cmdListSection.className = 'form-section cmd-list';
|
cmdListSection.className = 'form-section cmd-list';
|
||||||
cmdListSection.style.cssText = 'border-top: 1px solid #e2e8f0; padding-top: 20px; margin-top: 20px;';
|
cmdListSection.style.cssText = 'border-top: 1px solid #e2e8f0; padding-top: 20px; margin-top: 20px;';
|
||||||
|
|
||||||
|
// 添加结构体参数部分
|
||||||
|
const structSection = document.createElement('div');
|
||||||
|
structSection.className = 'form-section struct-params';
|
||||||
|
structSection.style.cssText = 'border-top: 1px solid #e2e8f0; padding-top: 20px; margin-top: 20px;';
|
||||||
|
|
||||||
|
// 创建结构体参数标题
|
||||||
|
const structHeader = document.createElement('div');
|
||||||
|
structHeader.style.cssText = 'margin-bottom: 15px;';
|
||||||
|
structHeader.innerHTML = '<label style="font-weight: 500; color: #333;">结构体参数</label>';
|
||||||
|
|
||||||
|
// 创建结构体参数网格布局
|
||||||
|
const structGrid = document.createElement('div');
|
||||||
|
structGrid.style.cssText = 'display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;';
|
||||||
|
|
||||||
|
// 添加三个结构体输入框
|
||||||
|
structGrid.innerHTML = `
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="inputStruct">输入结构体 (InputStruct)</label>
|
||||||
|
<textarea id="inputStruct" name="InputStruct" placeholder="输入结构体JSON格式" title="模型的输入参数结构体,JSON格式" style="min-height: 80px; resize: vertical;">${this.currentVersion.InputStruct || ''}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="outputStruct">输出结构体 (OutputStruct)</label>
|
||||||
|
<textarea id="outputStruct" name="OutputStruct" placeholder="输出结构体JSON格式" title="模型的输出参数结构体,JSON格式" style="min-height: 80px; resize: vertical;">${this.currentVersion.OutputStruct || ''}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="heartStruct">心跳结构体 (HeartStruct)</label>
|
||||||
|
<textarea id="heartStruct" name="HeartStruct" placeholder="心跳结构体JSON格式" title="模型的心跳参数结构体,JSON格式" style="min-height: 80px; resize: vertical;">${this.currentVersion.HeartStruct || ''}</textarea>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
structSection.appendChild(structHeader);
|
||||||
|
structSection.appendChild(structGrid);
|
||||||
|
|
||||||
// 创建表格标题和工具栏
|
// 创建表格标题和工具栏
|
||||||
const cmdListHeader = document.createElement('div');
|
const cmdListHeader = document.createElement('div');
|
||||||
cmdListHeader.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;';
|
cmdListHeader.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;';
|
||||||
@ -991,6 +1026,7 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
form.appendChild(basicInfoSection);
|
form.appendChild(basicInfoSection);
|
||||||
form.appendChild(advancedSection);
|
form.appendChild(advancedSection);
|
||||||
form.appendChild(cmdListSection);
|
form.appendChild(cmdListSection);
|
||||||
|
form.appendChild(structSection);
|
||||||
form.appendChild(formActions);
|
form.appendChild(formActions);
|
||||||
formContainer.appendChild(form);
|
formContainer.appendChild(form);
|
||||||
container.appendChild(formContainer);
|
container.appendChild(formContainer);
|
||||||
@ -1068,6 +1104,34 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证结构体字段的JSON格式
|
||||||
|
const inputStructInput = form.querySelector('#inputStruct');
|
||||||
|
if (inputStructInput && inputStructInput.value.trim() !== '') {
|
||||||
|
try {
|
||||||
|
JSON.parse(inputStructInput.value);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('InputStruct 必须是有效的 JSON 格式');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputStructInput = form.querySelector('#outputStruct');
|
||||||
|
if (outputStructInput && outputStructInput.value.trim() !== '') {
|
||||||
|
try {
|
||||||
|
JSON.parse(outputStructInput.value);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('OutputStruct 必须是有效的 JSON 格式');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const heartStructInput = form.querySelector('#heartStruct');
|
||||||
|
if (heartStructInput && heartStructInput.value.trim() !== '') {
|
||||||
|
try {
|
||||||
|
JSON.parse(heartStructInput.value);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('HeartStruct 必须是有效的 JSON 格式');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 收集指令列表数据
|
// 收集指令列表数据
|
||||||
const cmdList = [];
|
const cmdList = [];
|
||||||
const cmdRows = this.shadowRoot.querySelectorAll('#cmdListBody tr');
|
const cmdRows = this.shadowRoot.querySelectorAll('#cmdListBody tr');
|
||||||
@ -1097,14 +1161,17 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
Author: form.querySelector('#author').value,
|
Author: form.querySelector('#author').value,
|
||||||
Description: form.querySelector('#description').value,
|
Description: form.querySelector('#description').value,
|
||||||
ChangeTime: form.querySelector('#changeTime').value,
|
ChangeTime: form.querySelector('#changeTime').value,
|
||||||
CodePath: form.querySelector('#codePath').value,
|
|
||||||
RunFreqGroup: form.querySelector('#runFreqGroup').value,
|
RunFreqGroup: form.querySelector('#runFreqGroup').value,
|
||||||
RunNode: form.querySelector('#runNode').value,
|
RunNode: form.querySelector('#runNode').value,
|
||||||
Priority: form.querySelector('#priority').value,
|
Priority: form.querySelector('#priority').value,
|
||||||
DataPackagePath: form.querySelector('#dataPackagePath').value,
|
DataPackagePath: form.querySelector('#dataPackagePath').value,
|
||||||
DataPackageHeaderPath: form.querySelector('#dataPackageHeaderPath').value,
|
DataPackageName: form.querySelector('#dataPackageName').value,
|
||||||
|
DataPackageHeaderName: form.querySelector('#dataPackageHeaderName').value,
|
||||||
DataPackageEntryPoint: form.querySelector('#dataPackageEntryPoint').value,
|
DataPackageEntryPoint: form.querySelector('#dataPackageEntryPoint').value,
|
||||||
DataPackageInterfaceName: form.querySelector('#dataPackageInterfaceName').value,
|
DataPackageInterfaceName: form.querySelector('#dataPackageInterfaceName').value,
|
||||||
|
InputStruct: form.querySelector('#inputStruct').value,
|
||||||
|
OutputStruct: form.querySelector('#outputStruct').value,
|
||||||
|
HeartStruct: form.querySelector('#heartStruct').value,
|
||||||
CmdList: JSON.stringify(cmdList),
|
CmdList: JSON.stringify(cmdList),
|
||||||
isUpdate: this.isEditMode,
|
isUpdate: this.isEditMode,
|
||||||
originalVersion: this.isEditMode ? this.currentVersion.Version : null
|
originalVersion: this.isEditMode ? this.currentVersion.Version : null
|
||||||
@ -1940,14 +2007,17 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
Description: '',
|
Description: '',
|
||||||
CreatTime: this.getCurrentDateTime(),
|
CreatTime: this.getCurrentDateTime(),
|
||||||
ChangeTime: this.getCurrentDateTime(),
|
ChangeTime: this.getCurrentDateTime(),
|
||||||
CodePath: '',
|
|
||||||
RunFreqGroup: '0',
|
RunFreqGroup: '0',
|
||||||
RunNode: '0',
|
RunNode: '0',
|
||||||
Priority: '0',
|
Priority: '0',
|
||||||
DataPackagePath: '',
|
DataPackagePath: '',
|
||||||
DataPackageHeaderPath: '',
|
DataPackageName: '',
|
||||||
|
DataPackageHeaderName: '',
|
||||||
DataPackageEntryPoint: '',
|
DataPackageEntryPoint: '',
|
||||||
DataPackageInterfaceName: '',
|
DataPackageInterfaceName: '',
|
||||||
|
InputStruct: '',
|
||||||
|
OutputStruct: '',
|
||||||
|
HeartStruct: '',
|
||||||
CmdList: [] // 初始化为空数组
|
CmdList: [] // 初始化为空数组
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2152,6 +2222,163 @@ class ModelDevelopment extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传数据包模型
|
||||||
|
*/
|
||||||
|
async uploadDataPackage() {
|
||||||
|
try {
|
||||||
|
// 获取当前选择的构型信息
|
||||||
|
const savedSelection = localStorage.getItem('xnsim-selection');
|
||||||
|
const selection = savedSelection ? JSON.parse(savedSelection) : {};
|
||||||
|
|
||||||
|
if (!selection.configurationName) {
|
||||||
|
alert('请先选择构型!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建文件输入元素
|
||||||
|
const fileInput = document.createElement('input');
|
||||||
|
fileInput.type = 'file';
|
||||||
|
fileInput.webkitdirectory = true;
|
||||||
|
fileInput.directory = true;
|
||||||
|
fileInput.multiple = true;
|
||||||
|
fileInput.style.display = 'none';
|
||||||
|
|
||||||
|
// 添加到DOM
|
||||||
|
document.body.appendChild(fileInput);
|
||||||
|
|
||||||
|
// 监听文件选择
|
||||||
|
fileInput.addEventListener('change', async (event) => {
|
||||||
|
try {
|
||||||
|
const files = Array.from(event.target.files);
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
alert('请选择文件夹!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从第一个文件的webkitRelativePath中获取文件夹名称
|
||||||
|
let folderName = null;
|
||||||
|
if (files.length > 0 && files[0].webkitRelativePath) {
|
||||||
|
const pathParts = files[0].webkitRelativePath.split('/');
|
||||||
|
if (pathParts.length > 1) {
|
||||||
|
folderName = pathParts[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folderName) {
|
||||||
|
alert('无法获取文件夹名称,请重新选择文件夹!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证文件夹内容
|
||||||
|
const headerFiles = files.filter(file => file.name.toLowerCase().endsWith('.h'));
|
||||||
|
const libraryFiles = files.filter(file => file.name.toLowerCase().includes('.so'));
|
||||||
|
|
||||||
|
if (headerFiles.length !== 1) {
|
||||||
|
alert(`文件夹必须包含且仅包含一个.h文件,当前包含 ${headerFiles.length} 个.h文件`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libraryFiles.length !== 1) {
|
||||||
|
alert(`文件夹必须包含且仅包含一个动态库文件,当前包含 ${libraryFiles.length} 个动态库文件`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.length !== 2) {
|
||||||
|
alert(`文件夹只能包含一个.h文件和一个动态库文件,当前包含 ${files.length} 个文件`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建FormData
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('confName', selection.configurationName);
|
||||||
|
formData.append('folderName', folderName);
|
||||||
|
|
||||||
|
// 添加所有文件
|
||||||
|
files.forEach(file => {
|
||||||
|
formData.append('files', file);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示上传进度
|
||||||
|
const uploadButton = this.shadowRoot.querySelector('.toolbar-button:nth-child(3)');
|
||||||
|
if (uploadButton) {
|
||||||
|
const originalText = uploadButton.textContent;
|
||||||
|
uploadButton.textContent = '上传中...';
|
||||||
|
uploadButton.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送上传请求
|
||||||
|
const response = await fetch('/api/filesystem/upload-package', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json();
|
||||||
|
throw new Error(errorData.message || `上传失败: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
// 将返回的值填入对应的输入框
|
||||||
|
const dataPackagePathInput = this.shadowRoot.querySelector('#dataPackagePath');
|
||||||
|
const dataPackageNameInput = this.shadowRoot.querySelector('#dataPackageName');
|
||||||
|
const dataPackageHeaderNameInput = this.shadowRoot.querySelector('#dataPackageHeaderName');
|
||||||
|
const dataPackageEntryPointInput = this.shadowRoot.querySelector('#dataPackageEntryPoint');
|
||||||
|
const dataPackageInterfaceNameInput = this.shadowRoot.querySelector('#dataPackageInterfaceName');
|
||||||
|
|
||||||
|
if (dataPackagePathInput) {
|
||||||
|
dataPackagePathInput.value = result.packagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPackageNameInput) {
|
||||||
|
dataPackageNameInput.value = result.libraryFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPackageHeaderNameInput) {
|
||||||
|
dataPackageHeaderNameInput.value = result.headerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPackageEntryPointInput) {
|
||||||
|
dataPackageEntryPointInput.value = result.entryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPackageInterfaceNameInput) {
|
||||||
|
dataPackageInterfaceNameInput.value = result.paramType;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(`数据包上传成功!\n数据包路径: ${result.packagePath}\n头文件: ${result.headerFile}\n动态库文件: ${result.libraryFile}\n入口点: ${result.entryPoint}\n参数类型: ${result.paramType}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(result.message || '上传失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('数据包上传失败:', error);
|
||||||
|
alert(`数据包上传失败: ${error.message}`);
|
||||||
|
} finally {
|
||||||
|
// 恢复按钮状态
|
||||||
|
const uploadButton = this.shadowRoot.querySelector('.toolbar-button:nth-child(3)');
|
||||||
|
if (uploadButton) {
|
||||||
|
uploadButton.textContent = '数据包模型上传';
|
||||||
|
uploadButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理文件输入元素
|
||||||
|
document.body.removeChild(fileInput);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 触发文件选择对话框
|
||||||
|
fileInput.click();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('数据包上传初始化失败:', error);
|
||||||
|
alert(`数据包上传失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('model-development', ModelDevelopment);
|
customElements.define('model-development', ModelDevelopment);
|
@ -4,8 +4,12 @@ const fsPromises = require('fs').promises;
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
const { promisify } = require('util');
|
||||||
const { getActualLogPath, getUploadPath, saveUploadedFile, isAllowedFileType } = require('../utils/file-utils');
|
const { getActualLogPath, getUploadPath, saveUploadedFile, isAllowedFileType } = require('../utils/file-utils');
|
||||||
|
|
||||||
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
// 获取上传目录路径
|
// 获取上传目录路径
|
||||||
const uploadPath = getUploadPath();
|
const uploadPath = getUploadPath();
|
||||||
|
|
||||||
@ -35,6 +39,17 @@ const fileFilter = (req, file, cb) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 数据包上传文件过滤器
|
||||||
|
const packageFileFilter = (req, file, cb) => {
|
||||||
|
// 允许的文件类型:.h文件和包含.so的文件
|
||||||
|
const fileName = file.originalname.toLowerCase();
|
||||||
|
if (fileName.endsWith('.h') || fileName.includes('.so')) {
|
||||||
|
cb(null, true);
|
||||||
|
} else {
|
||||||
|
cb(new Error('数据包只能包含.h文件和动态库文件'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const upload = multer({
|
const upload = multer({
|
||||||
storage: storage,
|
storage: storage,
|
||||||
fileFilter: fileFilter,
|
fileFilter: fileFilter,
|
||||||
@ -43,6 +58,15 @@ const upload = multer({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 数据包上传专用multer配置
|
||||||
|
const packageUpload = multer({
|
||||||
|
storage: storage,
|
||||||
|
fileFilter: packageFileFilter,
|
||||||
|
limits: {
|
||||||
|
fileSize: 50 * 1024 * 1024 // 限制文件大小为50MB
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 读取目录内容
|
// 读取目录内容
|
||||||
router.get('/readdir', async (req, res) => {
|
router.get('/readdir', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@ -461,4 +485,297 @@ router.get('/download', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 上传数据包文件夹
|
||||||
|
router.post('/upload-package', packageUpload.array('files'), async (req, res) => {
|
||||||
|
try {
|
||||||
|
console.log('接收到的请求体:', req.body);
|
||||||
|
console.log('接收到的文件:', req.files ? req.files.map(f => f.originalname) : '无文件');
|
||||||
|
console.log('文件详细信息:', req.files ? req.files.map(f => ({
|
||||||
|
originalname: f.originalname,
|
||||||
|
webkitRelativePath: f.webkitRelativePath,
|
||||||
|
fieldname: f.fieldname
|
||||||
|
})) : '无文件');
|
||||||
|
|
||||||
|
const { confName } = req.body;
|
||||||
|
const { folderName } = req.body; // 从前端获取文件夹名称
|
||||||
|
|
||||||
|
if (!confName) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: '未提供构型名称'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.files || req.files.length === 0) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: '未提供文件'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否为文件夹上传
|
||||||
|
const hasFolderStructure = req.files.some(file =>
|
||||||
|
file.originalname.includes('/') || file.originalname.includes('\\')
|
||||||
|
);
|
||||||
|
|
||||||
|
// 优先使用前端传递的文件夹名称,如果没有则从文件路径中提取
|
||||||
|
let packageName = null;
|
||||||
|
|
||||||
|
if (folderName) {
|
||||||
|
// 使用前端传递的文件夹名称
|
||||||
|
packageName = folderName;
|
||||||
|
} else if (hasFolderStructure) {
|
||||||
|
// 如果文件路径包含分隔符,从路径中提取
|
||||||
|
for (const file of req.files) {
|
||||||
|
const pathParts = file.originalname.replace(/\\/g, '/').split('/');
|
||||||
|
if (pathParts.length > 1) {
|
||||||
|
packageName = pathParts[0]; // 取第一级目录名作为数据包名称
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果文件路径不包含分隔符,尝试从webkitRelativePath获取
|
||||||
|
if (req.files.length > 0 && req.files[0].webkitRelativePath) {
|
||||||
|
const pathParts = req.files[0].webkitRelativePath.split('/');
|
||||||
|
if (pathParts.length > 1) {
|
||||||
|
packageName = pathParts[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果还是无法获取,使用默认名称
|
||||||
|
if (!packageName) {
|
||||||
|
packageName = 'uploaded_package_' + Date.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packageName) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: '无法从上传的文件中提取文件夹名称'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证文件夹内容
|
||||||
|
const fileTypes = {
|
||||||
|
headerFiles: [], // .h文件
|
||||||
|
libraryFiles: [] // 动态库文件
|
||||||
|
};
|
||||||
|
|
||||||
|
req.files.forEach(file => {
|
||||||
|
const fileName = path.basename(file.originalname);
|
||||||
|
const ext = path.extname(fileName).toLowerCase();
|
||||||
|
|
||||||
|
if (ext === '.h') {
|
||||||
|
fileTypes.headerFiles.push(file);
|
||||||
|
} else if (fileName.toLowerCase().includes('.so')) {
|
||||||
|
fileTypes.libraryFiles.push(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 验证文件数量
|
||||||
|
if (fileTypes.headerFiles.length !== 1) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: `文件夹必须包含且仅包含一个.h文件,当前包含 ${fileTypes.headerFiles.length} 个.h文件`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileTypes.libraryFiles.length !== 1) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: `文件夹必须包含且仅包含一个动态库文件,当前包含 ${fileTypes.libraryFiles.length} 个动态库文件`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证总文件数量
|
||||||
|
const totalFiles = fileTypes.headerFiles.length + fileTypes.libraryFiles.length;
|
||||||
|
if (totalFiles !== req.files.length) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: `文件夹只能包含一个.h文件和一个动态库文件,当前包含 ${req.files.length} 个文件`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据包路径
|
||||||
|
const { getPackagesPath } = require('../utils/file-utils');
|
||||||
|
const packagesPath = getPackagesPath(confName);
|
||||||
|
|
||||||
|
if (!packagesPath) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: '无法获取数据包路径'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建目标数据包目录
|
||||||
|
const targetPackagePath = path.join(packagesPath, packageName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fsPromises.mkdir(targetPackagePath, { recursive: true });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== 'EEXIST') {
|
||||||
|
console.error('创建数据包目录失败:', error);
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: '创建数据包目录失败: ' + error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadedFiles = [];
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
// 处理每个上传的文件
|
||||||
|
for (const file of req.files) {
|
||||||
|
try {
|
||||||
|
// 从文件的相对路径中提取目标路径
|
||||||
|
let targetPath;
|
||||||
|
if (file.originalname.includes('/') || file.originalname.includes('\\')) {
|
||||||
|
// 如果文件名包含路径分隔符,说明是文件夹上传
|
||||||
|
const relativePath = file.originalname.replace(/\\/g, '/');
|
||||||
|
targetPath = path.join(targetPackagePath, relativePath);
|
||||||
|
} else {
|
||||||
|
// 单个文件,直接放在数据包根目录
|
||||||
|
targetPath = path.join(targetPackagePath, file.originalname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保目标目录存在
|
||||||
|
const targetDir = path.dirname(targetPath);
|
||||||
|
try {
|
||||||
|
await fsPromises.mkdir(targetDir, { recursive: true });
|
||||||
|
} catch (mkdirError) {
|
||||||
|
if (mkdirError.code !== 'EEXIST') {
|
||||||
|
throw mkdirError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动文件到目标位置
|
||||||
|
await fsPromises.copyFile(file.path, targetPath);
|
||||||
|
|
||||||
|
// 删除临时文件
|
||||||
|
try {
|
||||||
|
await fsPromises.unlink(file.path);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
console.warn('删除临时文件失败:', unlinkError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件信息
|
||||||
|
const stats = await fsPromises.stat(targetPath);
|
||||||
|
const fileName = path.basename(targetPath);
|
||||||
|
const ext = path.extname(fileName).toLowerCase();
|
||||||
|
|
||||||
|
uploadedFiles.push({
|
||||||
|
name: fileName,
|
||||||
|
path: path.relative(targetPackagePath, targetPath),
|
||||||
|
size: stats.size,
|
||||||
|
created: stats.birthtime,
|
||||||
|
modified: stats.mtime,
|
||||||
|
type: ext === '.h' ? 'header' : 'library'
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (fileError) {
|
||||||
|
console.error(`处理文件 ${file.originalname} 失败:`, fileError);
|
||||||
|
errors.push({
|
||||||
|
file: file.originalname,
|
||||||
|
error: fileError.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对动态库执行nm -D命令获取入口点函数信息
|
||||||
|
let entryPointInfo = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 找到动态库文件路径
|
||||||
|
const libraryFile = uploadedFiles.find(file => file.type === 'library');
|
||||||
|
if (libraryFile) {
|
||||||
|
const libraryPath = path.join(targetPackagePath, libraryFile.path);
|
||||||
|
entryPointInfo = await getEntryPointInfo(libraryPath);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('获取动态库入口点信息失败:', error.message);
|
||||||
|
// 不阻止上传流程,只记录警告
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回上传结果
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: `成功上传数据包 ${packageName},包含 ${fileTypes.headerFiles.length} 个头文件和 ${fileTypes.libraryFiles.length} 个动态库文件`,
|
||||||
|
packagePath: packageName, // 相对于Packages目录的路径
|
||||||
|
headerFile: path.basename(fileTypes.headerFiles[0].originalname),
|
||||||
|
libraryFile: path.basename(fileTypes.libraryFiles[0].originalname),
|
||||||
|
entryPoint: entryPointInfo ? entryPointInfo.symbolName : null,
|
||||||
|
paramType: entryPointInfo ? entryPointInfo.paramType : null
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('数据包上传失败:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: '数据包上传失败: ' + error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取动态库入口点函数信息
|
||||||
|
* @param {string} libraryPath - 动态库文件路径
|
||||||
|
* @returns {Promise<Object|null>} 入口点信息对象或null
|
||||||
|
*/
|
||||||
|
async function getEntryPointInfo(libraryPath) {
|
||||||
|
try {
|
||||||
|
// 执行nm -D命令获取动态符号表
|
||||||
|
const { stdout } = await execAsync(`nm -D "${libraryPath}" | grep EntryPoint`);
|
||||||
|
|
||||||
|
if (!stdout.trim()) {
|
||||||
|
console.log('未找到EntryPoint相关的符号');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析nm输出,只取第一个匹配的入口点
|
||||||
|
const lines = stdout.trim().split('\n');
|
||||||
|
|
||||||
|
if (lines.length > 0) {
|
||||||
|
const line = lines[0]; // 只处理第一行
|
||||||
|
// nm输出格式: 地址 类型 符号名
|
||||||
|
const parts = line.trim().split(/\s+/);
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
const symbolName = parts[2];
|
||||||
|
|
||||||
|
// 尝试从函数名中提取参数类型信息
|
||||||
|
// 函数名格式示例: _Z28SACSCWeightBalanceEntryPointP20ComacDataStructure_S
|
||||||
|
let paramType = null;
|
||||||
|
|
||||||
|
if (symbolName.startsWith('_Z')) {
|
||||||
|
// 解析C++符号名格式
|
||||||
|
const match = symbolName.match(/_Z\d+([A-Za-z0-9_]+)P(\d+)([A-Za-z0-9_]+)/);
|
||||||
|
if (match) {
|
||||||
|
paramType = match[3];
|
||||||
|
} else {
|
||||||
|
// 如果无法解析,使用原始符号名
|
||||||
|
paramType = symbolName;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// C函数名,使用原始符号名
|
||||||
|
paramType = symbolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entryPoint = {
|
||||||
|
symbolName: symbolName,
|
||||||
|
paramType: paramType
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('动态库入口点信息:', entryPoint);
|
||||||
|
return entryPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('获取动态库入口点信息失败:', error.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
@ -49,32 +49,64 @@ function getXNCorePath() {
|
|||||||
return xnCorePath;
|
return xnCorePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模型项目文件目录路径
|
// 获取当前构型路径
|
||||||
function getProjectModelPath() {
|
function getCurrentConfPath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
const xnCorePath = getXNCorePath();
|
const xnCorePath = getXNCorePath();
|
||||||
if (!xnCorePath) return '';
|
if (!xnCorePath) return '';
|
||||||
return path.join(xnCorePath, 'Project', 'Model');
|
return path.join(xnCorePath, 'Configuration', confName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模型项目文件目录路径
|
||||||
|
function getProjectModelPath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const xnCorePath = getXNCorePath();
|
||||||
|
if (!xnCorePath) return '';
|
||||||
|
return path.join(xnCorePath, 'Configuration', confName, 'ModelProjects');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模型文件目录路径
|
// 模型文件目录路径
|
||||||
function getModelPath() {
|
function getModelPath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
const xnCorePath = getXNCorePath();
|
const xnCorePath = getXNCorePath();
|
||||||
if (!xnCorePath) return '';
|
if (!xnCorePath) return '';
|
||||||
return path.join(xnCorePath, 'Models');
|
return path.join(xnCorePath, 'Configuration', confName, 'Models');
|
||||||
}
|
}
|
||||||
|
|
||||||
//服务项目文件目录路径
|
//服务项目文件目录路径
|
||||||
function getProjectServicePath() {
|
function getProjectServicePath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
const xnCorePath = getXNCorePath();
|
const xnCorePath = getXNCorePath();
|
||||||
if (!xnCorePath) return '';
|
if (!xnCorePath) return '';
|
||||||
return path.join(xnCorePath, 'Project', 'Service');
|
return path.join(xnCorePath, 'Configuration', confName, 'ServiceProjects');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务文件目录路径
|
// 服务文件目录路径
|
||||||
function getServicePath() {
|
function getServicePath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
const xnCorePath = getXNCorePath();
|
const xnCorePath = getXNCorePath();
|
||||||
if (!xnCorePath) return '';
|
if (!xnCorePath) return '';
|
||||||
return path.join(xnCorePath, 'Services');
|
return path.join(xnCorePath, 'Configuration', confName, 'Services');
|
||||||
|
}
|
||||||
|
|
||||||
|
//数据包路径
|
||||||
|
function getPackagesPath(confName) {
|
||||||
|
if (!confName) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const xnCorePath = getXNCorePath();
|
||||||
|
if (!xnCorePath) return '';
|
||||||
|
return path.join(xnCorePath, 'Configuration', confName, 'Packages');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日志目录路径处理
|
// 日志目录路径处理
|
||||||
@ -152,9 +184,12 @@ function isAllowedFileType(fileName, allowedTypes = []) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getXNCorePath,
|
getXNCorePath,
|
||||||
|
getCurrentConfPath,
|
||||||
getModelPath,
|
getModelPath,
|
||||||
getProjectModelPath,
|
getProjectModelPath,
|
||||||
|
getProjectServicePath,
|
||||||
getServicePath,
|
getServicePath,
|
||||||
|
getPackagesPath,
|
||||||
getActualLogPath,
|
getActualLogPath,
|
||||||
isPathSafe,
|
isPathSafe,
|
||||||
ensureDirectoryExists,
|
ensureDirectoryExists,
|
||||||
|
@ -59,10 +59,10 @@ function getModelVersionsByClassName(className, planeName) {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
PlaneName, ClassName, Name, Version, CodePath, Author, Description,
|
PlaneName, ClassName, Name, ConfID, Version, Author, Description,
|
||||||
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
||||||
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName,
|
DataPackagePath, DataPackageName, DataPackageHeaderName, DataPackageEntryPoint, DataPackageInterfaceName,
|
||||||
ConfID, CmdList
|
InputStruct, OutputStruct, HeartStruct, CmdList
|
||||||
FROM 'XNModelsVersion'
|
FROM 'XNModelsVersion'
|
||||||
WHERE ClassName = ? AND PlaneName = ?
|
WHERE ClassName = ? AND PlaneName = ?
|
||||||
ORDER BY Version DESC
|
ORDER BY Version DESC
|
||||||
@ -124,8 +124,8 @@ function saveModelVersion(versionData) {
|
|||||||
PlaneName = ?,
|
PlaneName = ?,
|
||||||
ClassName = ?,
|
ClassName = ?,
|
||||||
Name = ?,
|
Name = ?,
|
||||||
|
ConfID = ?,
|
||||||
Version = ?,
|
Version = ?,
|
||||||
CodePath = ?,
|
|
||||||
Author = ?,
|
Author = ?,
|
||||||
Description = ?,
|
Description = ?,
|
||||||
CreatTime = ?,
|
CreatTime = ?,
|
||||||
@ -134,18 +134,21 @@ function saveModelVersion(versionData) {
|
|||||||
RunNode = ?,
|
RunNode = ?,
|
||||||
Priority = ?,
|
Priority = ?,
|
||||||
DataPackagePath = ?,
|
DataPackagePath = ?,
|
||||||
DataPackageHeaderPath = ?,
|
DataPackageName = ?,
|
||||||
|
DataPackageHeaderName = ?,
|
||||||
DataPackageEntryPoint = ?,
|
DataPackageEntryPoint = ?,
|
||||||
DataPackageInterfaceName = ?,
|
DataPackageInterfaceName = ?,
|
||||||
ConfID = ?,
|
InputStruct = ?,
|
||||||
|
OutputStruct = ?,
|
||||||
|
HeartStruct = ?,
|
||||||
CmdList = ?
|
CmdList = ?
|
||||||
WHERE ClassName = ? AND Version = ? AND PlaneName = ?
|
WHERE ClassName = ? AND Version = ? AND PlaneName = ?
|
||||||
`).run(
|
`).run(
|
||||||
versionData.PlaneName,
|
versionData.PlaneName,
|
||||||
versionData.ClassName,
|
versionData.ClassName,
|
||||||
versionData.Name,
|
versionData.Name,
|
||||||
|
versionData.ConfID,
|
||||||
versionData.Version,
|
versionData.Version,
|
||||||
versionData.CodePath || '',
|
|
||||||
versionData.Author,
|
versionData.Author,
|
||||||
versionData.Description || '',
|
versionData.Description || '',
|
||||||
versionData.CreatTime || changeTime,
|
versionData.CreatTime || changeTime,
|
||||||
@ -154,10 +157,13 @@ function saveModelVersion(versionData) {
|
|||||||
versionData.RunNode || '',
|
versionData.RunNode || '',
|
||||||
versionData.Priority || '0',
|
versionData.Priority || '0',
|
||||||
versionData.DataPackagePath || '',
|
versionData.DataPackagePath || '',
|
||||||
versionData.DataPackageHeaderPath || '',
|
versionData.DataPackageName || '',
|
||||||
|
versionData.DataPackageHeaderName || '',
|
||||||
versionData.DataPackageEntryPoint || '',
|
versionData.DataPackageEntryPoint || '',
|
||||||
versionData.DataPackageInterfaceName || '',
|
versionData.DataPackageInterfaceName || '',
|
||||||
versionData.ConfID,
|
versionData.InputStruct || '',
|
||||||
|
versionData.OutputStruct || '',
|
||||||
|
versionData.HeartStruct || '',
|
||||||
versionData.CmdList || '[]',
|
versionData.CmdList || '[]',
|
||||||
versionData.ClassName,
|
versionData.ClassName,
|
||||||
versionData.originalVersion || versionData.Version,
|
versionData.originalVersion || versionData.Version,
|
||||||
@ -210,17 +216,17 @@ function saveNewVersion(db, versionData) {
|
|||||||
// 插入新版本
|
// 插入新版本
|
||||||
const insertResult = db.prepare(`
|
const insertResult = db.prepare(`
|
||||||
INSERT INTO 'XNModelsVersion' (
|
INSERT INTO 'XNModelsVersion' (
|
||||||
PlaneName, ClassName, Name, Version, CodePath, Author, Description,
|
PlaneName, ClassName, Name, ConfID, Version, Author, Description,
|
||||||
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
||||||
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName,
|
DataPackagePath, DataPackageName, DataPackageHeaderName, DataPackageEntryPoint, DataPackageInterfaceName,
|
||||||
ConfID, CmdList
|
InputStruct, OutputStruct, HeartStruct, CmdList
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
`).run(
|
`).run(
|
||||||
versionData.PlaneName,
|
versionData.PlaneName,
|
||||||
versionData.ClassName,
|
versionData.ClassName,
|
||||||
versionData.Name,
|
versionData.Name,
|
||||||
|
versionData.ConfID,
|
||||||
versionData.Version,
|
versionData.Version,
|
||||||
versionData.CodePath || '',
|
|
||||||
versionData.Author,
|
versionData.Author,
|
||||||
versionData.Description || '',
|
versionData.Description || '',
|
||||||
createTime,
|
createTime,
|
||||||
@ -229,10 +235,13 @@ function saveNewVersion(db, versionData) {
|
|||||||
versionData.RunNode || '',
|
versionData.RunNode || '',
|
||||||
versionData.Priority || '0',
|
versionData.Priority || '0',
|
||||||
versionData.DataPackagePath || '',
|
versionData.DataPackagePath || '',
|
||||||
versionData.DataPackageHeaderPath || '',
|
versionData.DataPackageName || '',
|
||||||
|
versionData.DataPackageHeaderName || '',
|
||||||
versionData.DataPackageEntryPoint || '',
|
versionData.DataPackageEntryPoint || '',
|
||||||
versionData.DataPackageInterfaceName || '',
|
versionData.DataPackageInterfaceName || '',
|
||||||
versionData.ConfID,
|
versionData.InputStruct || '',
|
||||||
|
versionData.OutputStruct || '',
|
||||||
|
versionData.HeartStruct || '',
|
||||||
versionData.CmdList || '[]'
|
versionData.CmdList || '[]'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user