190 lines
6.6 KiB
JavaScript
190 lines
6.6 KiB
JavaScript
|
const express = require('express');
|
||
|
const path = require('path');
|
||
|
const fs = require('fs').promises;
|
||
|
const xlsx = require('xlsx');
|
||
|
const multer = require('multer');
|
||
|
const { getDataInterfaces, addDataInterface, updateDataInterface, deleteDataInterface } = require('../utils/db-utils');
|
||
|
|
||
|
const router = express.Router();
|
||
|
const upload = multer({ storage: multer.memoryStorage() });
|
||
|
|
||
|
// 数据文件路径
|
||
|
const DATA_FILE = path.join(__dirname, '../data/interface.json');
|
||
|
|
||
|
// 确保数据目录存在
|
||
|
async function ensureDataDirectory() {
|
||
|
const dataDir = path.dirname(DATA_FILE);
|
||
|
try {
|
||
|
await fs.access(dataDir);
|
||
|
} catch {
|
||
|
await fs.mkdir(dataDir, { recursive: true });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 读取数据
|
||
|
async function readData() {
|
||
|
try {
|
||
|
await ensureDataDirectory();
|
||
|
const data = await fs.readFile(DATA_FILE, 'utf8');
|
||
|
return JSON.parse(data);
|
||
|
} catch (error) {
|
||
|
if (error.code === 'ENOENT') {
|
||
|
return [];
|
||
|
}
|
||
|
throw error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 保存数据
|
||
|
async function saveData(data) {
|
||
|
await ensureDataDirectory();
|
||
|
await fs.writeFile(DATA_FILE, JSON.stringify(data, null, 2));
|
||
|
}
|
||
|
|
||
|
// 获取接口列表
|
||
|
router.get('/list', async (req, res) => {
|
||
|
try {
|
||
|
const { systemName, productName } = req.query;
|
||
|
const interfaces = await getDataInterfaces(systemName, productName);
|
||
|
res.json(interfaces);
|
||
|
} catch (error) {
|
||
|
console.error('获取接口列表失败:', error);
|
||
|
res.status(500).json({ error: '获取接口列表失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 添加接口
|
||
|
router.post('/add', async (req, res) => {
|
||
|
try {
|
||
|
const result = await addDataInterface(req.body);
|
||
|
res.json(result);
|
||
|
} catch (error) {
|
||
|
console.error('添加接口失败:', error);
|
||
|
res.status(500).json({ error: error.message || '添加接口失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 更新接口
|
||
|
router.put('/update', async (req, res) => {
|
||
|
try {
|
||
|
const result = await updateDataInterface(req.body);
|
||
|
res.json(result);
|
||
|
} catch (error) {
|
||
|
console.error('更新接口失败:', error);
|
||
|
res.status(500).json({ error: error.message || '更新接口失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 删除接口
|
||
|
router.delete('/delete', async (req, res) => {
|
||
|
try {
|
||
|
const { systemName, productName, ataName, modelStructName, interfaceName } = req.query;
|
||
|
const result = await deleteDataInterface(systemName, productName, ataName, modelStructName, interfaceName);
|
||
|
res.json(result);
|
||
|
} catch (error) {
|
||
|
console.error('删除接口失败:', error);
|
||
|
res.status(500).json({ error: error.message || '删除接口失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 下载模板
|
||
|
router.get('/template', async (req, res) => {
|
||
|
try {
|
||
|
const workbook = xlsx.utils.book_new();
|
||
|
const worksheet = xlsx.utils.json_to_sheet([
|
||
|
{
|
||
|
'系统名称': 'XNSim',
|
||
|
'产品名称': 'C909',
|
||
|
'ATA章节': '',
|
||
|
'模型结构名': '',
|
||
|
'接口名': '',
|
||
|
'接口类型': '',
|
||
|
'接口选项': '',
|
||
|
'是否为数组': '',
|
||
|
'数组大小1': '',
|
||
|
'数组大小2': '',
|
||
|
'备注': ''
|
||
|
}
|
||
|
]);
|
||
|
xlsx.utils.book_append_sheet(workbook, worksheet, '接口变量模板');
|
||
|
|
||
|
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||
|
res.setHeader('Content-Disposition', 'attachment; filename=接口变量模板.xlsx');
|
||
|
|
||
|
const buffer = xlsx.write(workbook, { type: 'buffer', bookType: 'xlsx' });
|
||
|
res.send(buffer);
|
||
|
} catch (error) {
|
||
|
console.error('下载模板失败:', error);
|
||
|
res.status(500).json({ error: '下载模板失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 导入数据
|
||
|
router.post('/import', upload.single('file'), async (req, res) => {
|
||
|
try {
|
||
|
if (!req.file) {
|
||
|
return res.status(400).json({ error: '未上传文件' });
|
||
|
}
|
||
|
|
||
|
const workbook = xlsx.read(req.file.buffer);
|
||
|
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||
|
const data = xlsx.utils.sheet_to_json(worksheet);
|
||
|
|
||
|
const results = [];
|
||
|
for (const item of data) {
|
||
|
try {
|
||
|
// 验证所有必填字段
|
||
|
const requiredFields = {
|
||
|
'系统名称': 'SystemName',
|
||
|
'产品名称': 'ProductName',
|
||
|
'ATA章节': 'ATAName',
|
||
|
'模型结构名': 'ModelStructName',
|
||
|
'接口名': 'InterfaceName',
|
||
|
'接口类型': 'InterfaceType',
|
||
|
'接口选项': 'InterfaceOption',
|
||
|
'是否为数组': 'InterfaceIsArray',
|
||
|
'数组大小1': 'InterfaceArraySize_1',
|
||
|
'数组大小2': 'InterfaceArraySize_2',
|
||
|
'备注': 'InterfaceNotes'
|
||
|
};
|
||
|
|
||
|
// 检查所有必填字段是否存在
|
||
|
for (const [excelField, dbField] of Object.entries(requiredFields)) {
|
||
|
if (item[excelField] === undefined || item[excelField] === null || item[excelField] === '') {
|
||
|
throw new Error(`字段 "${excelField}" 是必填字段`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const interfaceData = {
|
||
|
SystemName: item['系统名称'],
|
||
|
ProductName: item['产品名称'],
|
||
|
ATAName: item['ATA章节'],
|
||
|
ModelStructName: item['模型结构名'],
|
||
|
InterfaceName: item['接口名'],
|
||
|
InterfaceType: item['接口类型'],
|
||
|
InterfaceOption: item['接口选项'],
|
||
|
InterfaceIsArray: item['是否为数组'] === '是' ? 1 : 0,
|
||
|
InterfaceArraySize_1: item['数组大小1'],
|
||
|
InterfaceArraySize_2: item['数组大小2'],
|
||
|
InterfaceNotes: item['备注']
|
||
|
};
|
||
|
|
||
|
const result = await addDataInterface(interfaceData);
|
||
|
results.push({ success: true, data: interfaceData });
|
||
|
} catch (error) {
|
||
|
results.push({ success: false, error: error.message, data: item });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
res.json({
|
||
|
success: true,
|
||
|
results,
|
||
|
message: `导入完成,成功: ${results.filter(r => r.success).length}, 失败: ${results.filter(r => !r.success).length}`
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('导入数据失败:', error);
|
||
|
res.status(500).json({ error: '导入数据失败' });
|
||
|
}
|
||
|
});
|
||
|
|
||
|
module.exports = router;
|