1753 lines
49 KiB
JavaScript
1753 lines
49 KiB
JavaScript
const Database = require('better-sqlite3');
|
||
const { getXNCorePath } = require('./file-utils');
|
||
|
||
// 查询ATAChapters表
|
||
function getATAChapters() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 直接使用ATAChapters表名查询
|
||
const chapters = db.prepare("SELECT ID, Name, Name_CN FROM 'ATAChapters' ORDER BY ID").all();
|
||
|
||
db.close();
|
||
|
||
return chapters;
|
||
} catch (error) {
|
||
console.error('获取ATA章节数据失败:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 根据章节ID查询XNModels表中的模型
|
||
function getModelsByChapterId(chapterId, productName) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 根据productName是否为空构建不同的查询
|
||
let query;
|
||
let params;
|
||
|
||
if (!productName || productName === '' || productName === 'undefined') {
|
||
query = `
|
||
SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName
|
||
FROM 'XNModels'
|
||
WHERE Chapters_ID = ?
|
||
ORDER BY ModelName
|
||
`;
|
||
params = [chapterId];
|
||
} else {
|
||
query = `
|
||
SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName
|
||
FROM 'XNModels'
|
||
WHERE Chapters_ID = ? AND ProductName = ?
|
||
ORDER BY ModelName
|
||
`;
|
||
params = [chapterId, productName];
|
||
}
|
||
|
||
const models = db.prepare(query).all(...params);
|
||
|
||
db.close();
|
||
|
||
return models;
|
||
} catch (error) {
|
||
console.error(`获取章节${chapterId}的模型数据失败:`, error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 根据ClassName查询XNModelsVersion表中的模型版本
|
||
function getModelVersionsByClassName(className, productName) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 根据productName是否为空构建不同的查询
|
||
let query;
|
||
let params;
|
||
|
||
if (!productName || productName === '') {
|
||
query = `
|
||
SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description,
|
||
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
||
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
|
||
FROM 'XNModelsVersion'
|
||
WHERE ClassName = ?
|
||
ORDER BY Version DESC
|
||
`;
|
||
params = [className];
|
||
} else {
|
||
query = `
|
||
SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description,
|
||
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
||
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
|
||
FROM 'XNModelsVersion'
|
||
WHERE ClassName = ? AND ProductName = ?
|
||
ORDER BY Version DESC
|
||
`;
|
||
params = [className, productName];
|
||
}
|
||
|
||
const versions = db.prepare(query).all(...params);
|
||
|
||
db.close();
|
||
|
||
return versions;
|
||
} catch (error) {
|
||
console.error(`获取模型${className}的版本数据失败:`, error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 保存或更新模型版本信息
|
||
function saveModelVersion(versionData) {
|
||
try {
|
||
// 验证必填字段
|
||
const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'ProductName'];
|
||
for (const field of requiredFields) {
|
||
if (!versionData[field]) {
|
||
throw new Error(`${field} 是必填字段`);
|
||
}
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 检查是否为更新模式
|
||
if (versionData.isUpdate) {
|
||
// 查询是否存在要更新的版本
|
||
const existingVersion = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNModelsVersion'
|
||
WHERE ClassName = ? AND Version = ? AND ProductName = ?
|
||
`).get(versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.ProductName);
|
||
|
||
if (existingVersion.count === 0) {
|
||
// 不存在要更新的版本,创建新版本
|
||
return saveNewVersion(db, versionData);
|
||
}
|
||
|
||
// 使用前端传来的修改时间,如果没有则生成当前时间
|
||
let changeTime = versionData.ChangeTime;
|
||
if (!changeTime) {
|
||
// 生成当前时间,格式为YYYY-MM-DD HH:MM:SS
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
}
|
||
|
||
// 更新现有版本
|
||
const updateResult = db.prepare(`
|
||
UPDATE 'XNModelsVersion'
|
||
SET
|
||
Name = ?,
|
||
Version = ?,
|
||
Author = ?,
|
||
Description = ?,
|
||
CodePath = ?,
|
||
ChangeTime = ?,
|
||
RunFreqGroup = ?,
|
||
RunNode = ?,
|
||
Priority = ?,
|
||
DataPackagePath = ?,
|
||
DataPackageHeaderPath = ?,
|
||
DataPackageEntryPoint = ?,
|
||
DataPackageInterfaceName = ?,
|
||
ProductName = ?
|
||
WHERE ClassName = ? AND Version = ? AND ProductName = ?
|
||
`).run(
|
||
versionData.Name,
|
||
versionData.Version,
|
||
versionData.Author,
|
||
versionData.Description || '',
|
||
versionData.CodePath || '',
|
||
changeTime,
|
||
versionData.RunFreqGroup || '',
|
||
versionData.RunNode || '',
|
||
versionData.Priority || '0',
|
||
versionData.DataPackagePath || '',
|
||
versionData.DataPackageHeaderPath || '',
|
||
versionData.DataPackageEntryPoint || '',
|
||
versionData.DataPackageInterfaceName || '',
|
||
versionData.ProductName,
|
||
versionData.ClassName,
|
||
versionData.originalVersion || versionData.Version,
|
||
versionData.ProductName
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
isNew: false,
|
||
changes: updateResult.changes,
|
||
message: '模型版本更新成功'
|
||
};
|
||
} else {
|
||
// 创建新版本
|
||
return saveNewVersion(db, versionData);
|
||
}
|
||
} catch (error) {
|
||
console.error('保存模型版本时出错:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 内部函数:保存新版本
|
||
function saveNewVersion(db, versionData) {
|
||
try {
|
||
// 检查版本是否已存在
|
||
const existingVersion = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNModelsVersion'
|
||
WHERE ClassName = ? AND Version = ? AND ProductName = ?
|
||
`).get(versionData.ClassName, versionData.Version, versionData.ProductName);
|
||
|
||
if (existingVersion.count > 0) {
|
||
db.close();
|
||
throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`);
|
||
}
|
||
|
||
// 生成当前时间,格式为YYYY-MM-DD HH:MM:SS
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
|
||
// 使用前端传来的时间或生成的时间
|
||
const createTime = versionData.CreatTime || formattedDateTime;
|
||
const changeTime = versionData.ChangeTime || formattedDateTime;
|
||
|
||
// 插入新版本
|
||
const insertResult = db.prepare(`
|
||
INSERT INTO 'XNModelsVersion' (
|
||
ProductName, ClassName, Name, Version, CodePath, Author, Description,
|
||
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
|
||
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
|
||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||
`).run(
|
||
versionData.ProductName,
|
||
versionData.ClassName,
|
||
versionData.Name,
|
||
versionData.Version,
|
||
versionData.CodePath || '',
|
||
versionData.Author,
|
||
versionData.Description || '',
|
||
createTime,
|
||
changeTime,
|
||
versionData.RunFreqGroup || '',
|
||
versionData.RunNode || '',
|
||
versionData.Priority || '0',
|
||
versionData.DataPackagePath || '',
|
||
versionData.DataPackageHeaderPath || '',
|
||
versionData.DataPackageEntryPoint || '',
|
||
versionData.DataPackageInterfaceName || ''
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
isNew: true,
|
||
id: insertResult.lastInsertRowid,
|
||
message: '模型版本创建成功'
|
||
};
|
||
} catch (error) {
|
||
if (db) db.close();
|
||
console.error('创建模型版本失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 查询XNServices表中的所有服务
|
||
function getServices() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 查询所有服务
|
||
const services = db.prepare(`
|
||
SELECT ServiceName, ServiceName_CN, Description, ClassName
|
||
FROM 'XNServices'
|
||
ORDER BY ServiceName
|
||
`).all();
|
||
|
||
db.close();
|
||
|
||
return services;
|
||
} catch (error) {
|
||
console.error('获取服务列表数据失败:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 根据ClassName查询XNServiceVersion表中的服务版本
|
||
function getServiceVersionsByClassName(className) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 查询该类名下的所有版本
|
||
const versions = db.prepare(`
|
||
SELECT ClassName, Name, Version, CodePath, Author, Description,
|
||
CreatTime, ChangeTime
|
||
FROM 'XNServiceVersion'
|
||
WHERE ClassName = ?
|
||
ORDER BY Version DESC
|
||
`).all(className);
|
||
|
||
db.close();
|
||
|
||
return versions;
|
||
} catch (error) {
|
||
console.error(`获取服务${className}的版本数据失败:`, error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 保存或更新服务版本信息
|
||
function saveServiceVersion(versionData) {
|
||
try {
|
||
// 验证必填字段
|
||
const requiredFields = ['ClassName', 'Name', 'Version', 'Author'];
|
||
for (const field of requiredFields) {
|
||
if (!versionData[field]) {
|
||
throw new Error(`${field} 是必填字段`);
|
||
}
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 检查是否为更新模式
|
||
if (versionData.isUpdate) {
|
||
// 查询是否存在要更新的版本
|
||
const existingVersion = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNServiceVersion'
|
||
WHERE ClassName = ? AND Version = ?
|
||
`).get(versionData.ClassName, versionData.originalVersion || versionData.Version);
|
||
|
||
if (existingVersion.count === 0) {
|
||
// 不存在要更新的版本,创建新版本
|
||
return saveNewServiceVersion(db, versionData);
|
||
}
|
||
|
||
// 使用前端传来的修改时间,如果没有则生成当前时间
|
||
let changeTime = versionData.ChangeTime;
|
||
if (!changeTime) {
|
||
// 生成当前时间,格式为YYYY-MM-DD HH:MM:SS
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
}
|
||
|
||
// 更新现有版本
|
||
const updateResult = db.prepare(`
|
||
UPDATE 'XNServiceVersion'
|
||
SET
|
||
Name = ?,
|
||
Version = ?,
|
||
Author = ?,
|
||
Description = ?,
|
||
CodePath = ?,
|
||
ChangeTime = ?
|
||
WHERE ClassName = ? AND Version = ?
|
||
`).run(
|
||
versionData.Name,
|
||
versionData.Version,
|
||
versionData.Author,
|
||
versionData.Description || '',
|
||
versionData.CodePath || '',
|
||
changeTime, // 使用前端传来的时间或生成的当前时间
|
||
versionData.ClassName,
|
||
versionData.originalVersion || versionData.Version
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
isNew: false,
|
||
changes: updateResult.changes,
|
||
message: '服务版本更新成功'
|
||
};
|
||
} else {
|
||
// 创建新版本
|
||
return saveNewServiceVersion(db, versionData);
|
||
}
|
||
} catch (error) {
|
||
console.error('保存服务版本时出错:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 内部函数:保存新的服务版本
|
||
function saveNewServiceVersion(db, versionData) {
|
||
try {
|
||
// 检查版本是否已存在
|
||
const existingVersion = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNServiceVersion'
|
||
WHERE ClassName = ? AND Version = ?
|
||
`).get(versionData.ClassName, versionData.Version);
|
||
|
||
if (existingVersion.count > 0) {
|
||
db.close();
|
||
throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`);
|
||
}
|
||
|
||
// 生成当前时间,格式为YYYY-MM-DD HH:MM:SS
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
|
||
// 使用前端传来的时间或生成的时间
|
||
const createTime = versionData.CreatTime || formattedDateTime;
|
||
const changeTime = versionData.ChangeTime || formattedDateTime;
|
||
|
||
// 插入新版本
|
||
const insertResult = db.prepare(`
|
||
INSERT INTO 'XNServiceVersion' (
|
||
ClassName, Name, Version, CodePath, Author, Description,
|
||
CreatTime, ChangeTime
|
||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||
`).run(
|
||
versionData.ClassName,
|
||
versionData.Name,
|
||
versionData.Version,
|
||
versionData.CodePath || '',
|
||
versionData.Author,
|
||
versionData.Description || '',
|
||
createTime, // 使用前端传来的创建时间或生成的当前时间
|
||
changeTime // 使用前端传来的修改时间或生成的当前时间
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
isNew: true,
|
||
id: insertResult.lastInsertRowid,
|
||
message: '服务版本创建成功'
|
||
};
|
||
} catch (error) {
|
||
if (db) db.close();
|
||
console.error('创建服务版本失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 创建新服务
|
||
function createService(serviceData) {
|
||
try {
|
||
// 验证必填字段
|
||
const requiredFields = ['ClassName', 'ServiceName', 'ServiceName_CN'];
|
||
for (const field of requiredFields) {
|
||
if (!serviceData[field]) {
|
||
throw new Error(`${field} 是必填字段`);
|
||
}
|
||
}
|
||
|
||
// 验证类名是否以XN开头
|
||
if (!serviceData.ClassName.startsWith('XN')) {
|
||
throw new Error('服务类名必须以XN开头');
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 检查服务类名是否已存在
|
||
const existingService = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNServices'
|
||
WHERE ClassName = ?
|
||
`).get(serviceData.ClassName);
|
||
|
||
if (existingService.count > 0) {
|
||
db.close();
|
||
throw new Error(`服务类名 ${serviceData.ClassName} 已存在,请使用其他类名`);
|
||
}
|
||
|
||
// 检查服务名称是否已存在
|
||
const existingServiceName = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'XNServices'
|
||
WHERE ServiceName = ?
|
||
`).get(serviceData.ServiceName);
|
||
|
||
if (existingServiceName.count > 0) {
|
||
db.close();
|
||
throw new Error(`服务名称 ${serviceData.ServiceName} 已存在,请使用其他名称`);
|
||
}
|
||
|
||
// 插入新服务
|
||
const insertResult = db.prepare(`
|
||
INSERT INTO 'XNServices' (
|
||
ClassName, ServiceName, ServiceName_CN, Description
|
||
) VALUES (?, ?, ?, ?)
|
||
`).run(
|
||
serviceData.ClassName,
|
||
serviceData.ServiceName,
|
||
serviceData.ServiceName_CN,
|
||
serviceData.Description || ''
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
id: insertResult.lastInsertRowid,
|
||
message: '服务创建成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('创建服务失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 查询Products表中的所有产品
|
||
function getProducts() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 查询所有产品
|
||
const products = db.prepare(`
|
||
SELECT ProductName, Description
|
||
FROM 'Products'
|
||
ORDER BY ProductName
|
||
`).all();
|
||
|
||
db.close();
|
||
|
||
return products;
|
||
} catch (error) {
|
||
console.error('获取产品列表数据失败:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取接口列表
|
||
function getDataInterfaces(systemName = 'XNSim', productName) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 根据是否传入 productName 构建不同的查询
|
||
let query;
|
||
let params;
|
||
|
||
if (!productName || productName === '') {
|
||
query = `
|
||
SELECT SystemName, ProductName, ATAName, ModelStructName, InterfaceName,
|
||
InterfaceType, InterfaceOption, InterfaceIsArray,
|
||
InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes
|
||
FROM 'DataInterface'
|
||
WHERE SystemName = ?
|
||
ORDER BY ProductName, ATAName, ModelStructName, InterfaceName
|
||
`;
|
||
params = [systemName];
|
||
} else {
|
||
query = `
|
||
SELECT SystemName, ProductName, ATAName, ModelStructName, InterfaceName,
|
||
InterfaceType, InterfaceOption, InterfaceIsArray,
|
||
InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes
|
||
FROM 'DataInterface'
|
||
WHERE SystemName = ? AND ProductName = ?
|
||
ORDER BY ATAName, ModelStructName, InterfaceName
|
||
`;
|
||
params = [systemName, productName];
|
||
}
|
||
|
||
const interfaces = db.prepare(query).all(...params);
|
||
|
||
db.close();
|
||
|
||
return interfaces;
|
||
} catch (error) {
|
||
console.error('获取接口列表数据失败:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 添加接口
|
||
function addDataInterface(interfaceData) {
|
||
try {
|
||
// 验证必填字段
|
||
const requiredFields = [
|
||
'SystemName',
|
||
'ProductName',
|
||
'ATAName',
|
||
'ModelStructName',
|
||
'InterfaceName',
|
||
'InterfaceType',
|
||
'InterfaceOption',
|
||
'InterfaceIsArray',
|
||
'InterfaceArraySize_1',
|
||
'InterfaceArraySize_2'
|
||
];
|
||
|
||
for (const field of requiredFields) {
|
||
if (interfaceData[field] === undefined || interfaceData[field] === null) {
|
||
throw new Error(`${field} 是必填字段`);
|
||
}
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 检查接口是否已存在
|
||
const existingInterface = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'DataInterface'
|
||
WHERE SystemName = ? AND ProductName = ? AND ATAName = ?
|
||
AND ModelStructName = ? AND InterfaceName = ?
|
||
`).get(
|
||
interfaceData.SystemName,
|
||
interfaceData.ProductName,
|
||
interfaceData.ATAName,
|
||
interfaceData.ModelStructName,
|
||
interfaceData.InterfaceName
|
||
);
|
||
|
||
if (existingInterface.count > 0) {
|
||
db.close();
|
||
throw new Error('接口已存在');
|
||
}
|
||
|
||
// 插入新接口
|
||
const insertResult = db.prepare(`
|
||
INSERT INTO 'DataInterface' (
|
||
SystemName, ProductName, ATAName, ModelStructName, InterfaceName,
|
||
InterfaceType, InterfaceOption, InterfaceIsArray,
|
||
InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes
|
||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||
`).run(
|
||
interfaceData.SystemName,
|
||
interfaceData.ProductName,
|
||
interfaceData.ATAName,
|
||
interfaceData.ModelStructName,
|
||
interfaceData.InterfaceName,
|
||
interfaceData.InterfaceType,
|
||
interfaceData.InterfaceOption,
|
||
interfaceData.InterfaceIsArray,
|
||
interfaceData.InterfaceArraySize_1,
|
||
interfaceData.InterfaceArraySize_2,
|
||
interfaceData.InterfaceNotes || null
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
id: insertResult.lastInsertRowid,
|
||
message: '接口添加成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('添加接口失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 更新接口
|
||
function updateDataInterface(interfaceData) {
|
||
try {
|
||
// 验证必填字段
|
||
const requiredFields = [
|
||
'SystemName',
|
||
'ProductName',
|
||
'ATAName',
|
||
'ModelStructName',
|
||
'InterfaceName',
|
||
'InterfaceType',
|
||
'InterfaceOption',
|
||
'InterfaceIsArray',
|
||
'InterfaceArraySize_1',
|
||
'InterfaceArraySize_2'
|
||
];
|
||
|
||
// 检查数据结构
|
||
if (!interfaceData.currentData || !interfaceData.originalData) {
|
||
throw new Error('数据格式错误:缺少 currentData 或 originalData');
|
||
}
|
||
|
||
// 验证 currentData 中的必填字段
|
||
for (const field of requiredFields) {
|
||
if (interfaceData.currentData[field] === undefined || interfaceData.currentData[field] === null) {
|
||
throw new Error(`${field} 是必填字段`);
|
||
}
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 首先检查记录是否存在
|
||
const existingRecord = db.prepare(`
|
||
SELECT COUNT(*) as count FROM 'DataInterface'
|
||
WHERE SystemName = ? AND ProductName = ? AND ATAName = ?
|
||
AND ModelStructName = ? AND InterfaceName = ?
|
||
`).get(
|
||
interfaceData.originalData.SystemName,
|
||
interfaceData.originalData.ProductName,
|
||
interfaceData.originalData.ATAName,
|
||
interfaceData.originalData.ModelStructName,
|
||
interfaceData.originalData.InterfaceName
|
||
);
|
||
|
||
if (existingRecord.count === 0) {
|
||
db.close();
|
||
throw new Error('要更新的记录不存在');
|
||
}
|
||
|
||
// 更新接口,包括所有字段
|
||
const updateResult = db.prepare(`
|
||
UPDATE 'DataInterface'
|
||
SET SystemName = ?,
|
||
ProductName = ?,
|
||
ATAName = ?,
|
||
ModelStructName = ?,
|
||
InterfaceName = ?,
|
||
InterfaceType = ?,
|
||
InterfaceOption = ?,
|
||
InterfaceIsArray = ?,
|
||
InterfaceArraySize_1 = ?,
|
||
InterfaceArraySize_2 = ?,
|
||
InterfaceNotes = ?
|
||
WHERE SystemName = ? AND ProductName = ? AND ATAName = ?
|
||
AND ModelStructName = ? AND InterfaceName = ?
|
||
`).run(
|
||
interfaceData.currentData.SystemName,
|
||
interfaceData.currentData.ProductName,
|
||
interfaceData.currentData.ATAName,
|
||
interfaceData.currentData.ModelStructName,
|
||
interfaceData.currentData.InterfaceName,
|
||
interfaceData.currentData.InterfaceType,
|
||
interfaceData.currentData.InterfaceOption,
|
||
interfaceData.currentData.InterfaceIsArray,
|
||
interfaceData.currentData.InterfaceArraySize_1,
|
||
interfaceData.currentData.InterfaceArraySize_2,
|
||
interfaceData.currentData.InterfaceNotes || null,
|
||
interfaceData.originalData.SystemName,
|
||
interfaceData.originalData.ProductName,
|
||
interfaceData.originalData.ATAName,
|
||
interfaceData.originalData.ModelStructName,
|
||
interfaceData.originalData.InterfaceName
|
||
);
|
||
|
||
db.close();
|
||
|
||
if (updateResult.changes === 0) {
|
||
throw new Error('更新失败:没有记录被修改');
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
changes: updateResult.changes,
|
||
message: '接口更新成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('更新接口失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 删除接口
|
||
function deleteDataInterface(systemName, productName, ataName, modelStructName, interfaceName) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 删除接口
|
||
const deleteResult = db.prepare(`
|
||
DELETE FROM 'DataInterface'
|
||
WHERE SystemName = ? AND ProductName = ? AND ATAName = ?
|
||
AND ModelStructName = ? AND InterfaceName = ?
|
||
`).run(
|
||
systemName || 'XNSim',
|
||
productName || 'C909',
|
||
ataName,
|
||
modelStructName,
|
||
interfaceName
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
changes: deleteResult.changes,
|
||
message: '接口删除成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('删除接口失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取接口结构体列表
|
||
function getDataInterfaceStructs(systemName = 'XNSim', productName, ataName) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 根据是否传入 productName 构建不同的查询
|
||
let query;
|
||
let params;
|
||
|
||
if (!productName || productName === '') {
|
||
query = `
|
||
SELECT SystemName, ProductName, ATAName, ModelStructName
|
||
FROM 'DataInterface'
|
||
WHERE SystemName = ?
|
||
GROUP BY ModelStructName
|
||
ORDER BY ProductName, ATAName, ModelStructName
|
||
`;
|
||
params = [systemName];
|
||
} else {
|
||
query = `
|
||
SELECT SystemName, ProductName, ATAName, ModelStructName
|
||
FROM 'DataInterface'
|
||
WHERE SystemName = ? AND ProductName = ?
|
||
GROUP BY ModelStructName
|
||
ORDER BY ATAName, ModelStructName
|
||
`;
|
||
params = [systemName, productName];
|
||
}
|
||
|
||
if (ataName) {
|
||
query = query.replace('GROUP BY', 'AND ATAName = ? GROUP BY');
|
||
params.push(ataName);
|
||
}
|
||
|
||
const structs = db.prepare(query).all(...params);
|
||
|
||
db.close();
|
||
|
||
return structs;
|
||
} catch (error) {
|
||
console.error('获取接口结构体列表数据失败:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取所有问题
|
||
function getQuestions() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
const questions = db.prepare(`
|
||
SELECT q.*,
|
||
COUNT(a.id) as answer_count,
|
||
MAX(a.created_at) as last_answer_time
|
||
FROM questions q
|
||
LEFT JOIN answers a ON q.id = a.question_id
|
||
GROUP BY q.id
|
||
ORDER BY q.created_at DESC
|
||
`).all();
|
||
|
||
// 获取每个问题的回答
|
||
questions.forEach(question => {
|
||
question.answers = db.prepare(`
|
||
SELECT * FROM answers
|
||
WHERE question_id = ?
|
||
ORDER BY created_at ASC
|
||
`).all(question.id);
|
||
});
|
||
|
||
db.close();
|
||
return questions;
|
||
} catch (error) {
|
||
console.error('获取问题列表失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 创建新问题
|
||
function createQuestion(title, content, author) {
|
||
try {
|
||
if (!title || !content) {
|
||
throw new Error('标题和内容不能为空');
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare(`
|
||
INSERT INTO questions (title, content, author)
|
||
VALUES (?, ?, ?)
|
||
`).run(title, content, author || '匿名用户');
|
||
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
questionId: result.lastInsertRowid,
|
||
message: '问题创建成功'
|
||
};
|
||
} else {
|
||
throw new Error('问题创建失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('创建问题失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 添加回答
|
||
function addAnswer(questionId, content, author) {
|
||
try {
|
||
if (!content) {
|
||
throw new Error('回答内容不能为空');
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 检查问题是否存在
|
||
const question = db.prepare('SELECT id FROM questions WHERE id = ?').get(questionId);
|
||
if (!question) {
|
||
db.close();
|
||
throw new Error('问题不存在');
|
||
}
|
||
|
||
const result = db.prepare(`
|
||
INSERT INTO answers (question_id, content, author)
|
||
VALUES (?, ?, ?)
|
||
`).run(questionId, content, author || '匿名用户');
|
||
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
answerId: result.lastInsertRowid,
|
||
message: '回答添加成功'
|
||
};
|
||
} else {
|
||
throw new Error('回答添加失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('添加回答失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 删除问题
|
||
function deleteQuestion(questionId) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare('DELETE FROM questions WHERE id = ?').run(questionId);
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
message: '问题删除成功'
|
||
};
|
||
} else {
|
||
throw new Error('问题不存在');
|
||
}
|
||
} catch (error) {
|
||
console.error('删除问题失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 删除回答
|
||
function deleteAnswer(answerId) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare('DELETE FROM answers WHERE id = ?').run(answerId);
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
message: '回答删除成功'
|
||
};
|
||
} else {
|
||
throw new Error('回答不存在');
|
||
}
|
||
} catch (error) {
|
||
console.error('删除回答失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取所有待办事项
|
||
function getTodos() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 创建todos表(如果不存在)
|
||
db.prepare(`
|
||
CREATE TABLE IF NOT EXISTS todos (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
project TEXT NOT NULL DEFAULT '其它',
|
||
subproject TEXT NOT NULL DEFAULT '其它',
|
||
title TEXT NOT NULL,
|
||
text TEXT,
|
||
adduser TEXT NOT NULL,
|
||
exeuser TEXT,
|
||
completed BOOLEAN DEFAULT 0,
|
||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
sche_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
complete_time DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
)
|
||
`).run();
|
||
|
||
const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all();
|
||
db.close();
|
||
|
||
return todos;
|
||
} catch (error) {
|
||
console.error('获取待办事项失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 添加待办事项
|
||
function addTodo(todoData) {
|
||
try {
|
||
if (!todoData.title) {
|
||
throw new Error('待办事项标题不能为空');
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 获取当前本地时间
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
|
||
// 处理计划时间
|
||
let scheTime = todoData.sche_time;
|
||
if (scheTime) {
|
||
// 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式
|
||
if (scheTime.includes('T')) {
|
||
const [datePart, timePart] = scheTime.split('T');
|
||
scheTime = `${datePart} ${timePart}:00`;
|
||
}
|
||
} else {
|
||
scheTime = localDateTime;
|
||
}
|
||
|
||
const result = db.prepare(`
|
||
INSERT INTO todos (
|
||
project, subproject, title, text, adduser,
|
||
exeuser, completed, created_at, sche_time
|
||
) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
|
||
`).run(
|
||
todoData.project || '其它',
|
||
todoData.subproject || '其它',
|
||
todoData.title,
|
||
todoData.text || '',
|
||
todoData.adduser || '系统',
|
||
todoData.exeuser || null,
|
||
localDateTime,
|
||
scheTime
|
||
);
|
||
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
id: result.lastInsertRowid,
|
||
message: '待办事项添加成功'
|
||
};
|
||
} else {
|
||
throw new Error('待办事项添加失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('添加待办事项失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 更新待办事项状态
|
||
function updateTodoStatus(id, completed, exeuser, title, text, sche_time) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 获取当前本地时间
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
|
||
// 处理计划时间
|
||
let scheTime = sche_time;
|
||
if (scheTime) {
|
||
// 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式
|
||
if (scheTime.includes('T')) {
|
||
const [datePart, timePart] = scheTime.split('T');
|
||
scheTime = `${datePart} ${timePart}`;
|
||
}
|
||
}
|
||
|
||
const result = db.prepare(`
|
||
UPDATE todos
|
||
SET completed = ?,
|
||
exeuser = ?,
|
||
title = ?,
|
||
text = ?,
|
||
sche_time = ?,
|
||
complete_time = CASE WHEN ? = 1 THEN ? ELSE complete_time END
|
||
WHERE id = ?
|
||
`).run(
|
||
completed ? 1 : 0,
|
||
exeuser || null,
|
||
title,
|
||
text || '',
|
||
scheTime || null,
|
||
completed ? 1 : 0,
|
||
completed ? localDateTime : null,
|
||
id
|
||
);
|
||
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
message: '待办事项更新成功'
|
||
};
|
||
} else {
|
||
throw new Error('待办事项不存在');
|
||
}
|
||
} catch (error) {
|
||
console.error('更新待办事项失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 删除待办事项
|
||
function deleteTodo(id) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare('DELETE FROM todos WHERE id = ?').run(id);
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
message: result.changes > 0 ? '待办事项删除成功' : '待办事项不存在或已被删除'
|
||
};
|
||
} catch (error) {
|
||
console.error('删除待办事项失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取所有用户信息
|
||
function getUsers() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
const users = db.prepare(`
|
||
SELECT
|
||
id,
|
||
username,
|
||
password,
|
||
access_level,
|
||
full_name,
|
||
phone,
|
||
email,
|
||
department,
|
||
position
|
||
FROM users
|
||
ORDER BY id ASC
|
||
`).all();
|
||
|
||
db.close();
|
||
|
||
return users;
|
||
} catch (error) {
|
||
console.error('获取用户信息失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取所有系统日志
|
||
function getSystemLogs() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
const logs = db.prepare(`
|
||
SELECT id, time, level, user, source, log
|
||
FROM SystemLog
|
||
ORDER BY time DESC
|
||
`).all();
|
||
|
||
db.close();
|
||
|
||
return logs;
|
||
} catch (error) {
|
||
console.error('获取系统日志失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 添加系统日志
|
||
function addSystemLog(logData) {
|
||
try {
|
||
// 验证必填字段
|
||
if (!logData.level || !logData.source) {
|
||
throw new Error('日志级别和来源是必填字段');
|
||
}
|
||
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 获取当前本地时间
|
||
const now = new Date();
|
||
const year = now.getFullYear();
|
||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
|
||
// 在插入日志时添加时间
|
||
const result = db.prepare(`
|
||
INSERT INTO SystemLog (level, user, source, log, time)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
`).run(
|
||
logData.level,
|
||
logData.user || null,
|
||
logData.source,
|
||
logData.log || null,
|
||
localDateTime
|
||
);
|
||
|
||
db.close();
|
||
|
||
if (result.changes > 0) {
|
||
return {
|
||
success: true,
|
||
id: result.lastInsertRowid,
|
||
message: '系统日志添加成功'
|
||
};
|
||
} else {
|
||
throw new Error('系统日志添加失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('添加系统日志失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取运行中的XNEngine进程
|
||
function getRunningXNEngineProcess(pid) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
// 创建进程表(如果不存在)
|
||
db.prepare(`
|
||
CREATE TABLE IF NOT EXISTS xnengine_processes (
|
||
pid INTEGER PRIMARY KEY,
|
||
log_file TEXT,
|
||
start_time TEXT,
|
||
cmd TEXT,
|
||
status TEXT DEFAULT 'running',
|
||
scenario_file TEXT
|
||
)
|
||
`).run();
|
||
|
||
const process = db.prepare('SELECT * FROM xnengine_processes WHERE pid = ?').get(pid);
|
||
db.close();
|
||
|
||
return process;
|
||
} catch (error) {
|
||
console.error('获取XNEngine进程信息失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 保存XNEngine进程信息
|
||
function saveXNEngineProcess(processData) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
// 创建进程表(如果不存在)
|
||
db.prepare(`
|
||
CREATE TABLE IF NOT EXISTS xnengine_processes (
|
||
pid INTEGER PRIMARY KEY,
|
||
log_file TEXT,
|
||
start_time TEXT,
|
||
cmd TEXT,
|
||
status TEXT DEFAULT 'running',
|
||
scenario_file TEXT
|
||
)
|
||
`).run();
|
||
|
||
const result = db.prepare(`
|
||
INSERT INTO xnengine_processes (pid, log_file, start_time, cmd, scenario_file)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
`).run(
|
||
processData.pid,
|
||
processData.log_file,
|
||
processData.start_time,
|
||
processData.cmd,
|
||
processData.scenario_file || null
|
||
);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
message: 'XNEngine进程信息保存成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('保存XNEngine进程信息失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 更新XNEngine进程状态
|
||
function updateXNEngineProcessStatus(pid, status) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare(`
|
||
UPDATE xnengine_processes
|
||
SET status = ?
|
||
WHERE pid = ?
|
||
`).run(status, pid);
|
||
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
message: 'XNEngine进程状态更新成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('更新XNEngine进程状态失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 删除XNEngine进程信息
|
||
function deleteXNEngineProcess(pid) {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath);
|
||
|
||
const result = db.prepare('DELETE FROM xnengine_processes WHERE pid = ?').run(pid);
|
||
db.close();
|
||
|
||
return {
|
||
success: true,
|
||
message: 'XNEngine进程信息删除成功'
|
||
};
|
||
} catch (error) {
|
||
console.error('删除XNEngine进程信息失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 获取最新的运行中XNEngine进程
|
||
function getLatestRunningXNEngineProcess() {
|
||
try {
|
||
const xnCorePath = getXNCorePath();
|
||
if (!xnCorePath) {
|
||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||
}
|
||
|
||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||
if (!dbPath) {
|
||
throw new Error('无法找到数据库文件');
|
||
}
|
||
|
||
// 打开数据库连接
|
||
const db = new Database(dbPath, { readonly: true });
|
||
|
||
const process = db.prepare(`
|
||
SELECT * FROM xnengine_processes
|
||
WHERE status = ?
|
||
ORDER BY start_time DESC
|
||
LIMIT 1
|
||
`).get('running');
|
||
|
||
db.close();
|
||
|
||
return process;
|
||
} catch (error) {
|
||
console.error('获取最新XNEngine进程信息失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
getATAChapters,
|
||
getModelsByChapterId,
|
||
getModelVersionsByClassName,
|
||
saveModelVersion,
|
||
getServices,
|
||
getServiceVersionsByClassName,
|
||
saveServiceVersion,
|
||
createService,
|
||
getProducts,
|
||
getDataInterfaces,
|
||
addDataInterface,
|
||
updateDataInterface,
|
||
deleteDataInterface,
|
||
getDataInterfaceStructs,
|
||
getQuestions,
|
||
createQuestion,
|
||
addAnswer,
|
||
deleteQuestion,
|
||
deleteAnswer,
|
||
getTodos,
|
||
addTodo,
|
||
updateTodoStatus,
|
||
deleteTodo,
|
||
getUsers,
|
||
getSystemLogs,
|
||
addSystemLog,
|
||
getRunningXNEngineProcess,
|
||
saveXNEngineProcess,
|
||
updateXNEngineProcessStatus,
|
||
deleteXNEngineProcess,
|
||
getLatestRunningXNEngineProcess
|
||
};
|