const express = require('express');
const cors = require('cors');
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
// 创建服务器
const app = express();
app.use(express.json());
// 修复CORS配置 - 添加详细配置
app.use(cors({
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
// 处理预检请求
app.options('*', cors());
// 连接SQLite数据库
const db = new sqlite3.Database('./archive.db', (err) => {
if (err) {
console.error('数据库连接错误:', err.message);
} else {
console.log('成功连接SQLite数据库');
// 初始化档案表
db.run(`CREATE TABLE IF NOT EXISTS archives (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fileNumber TEXT NOT NULL,
documentNumber TEXT,
responsiblePerson TEXT,
title TEXT NOT NULL,
date TEXT,
projectDate TEXT,
securityLevel TEXT,
pages INTEGER,
retentionPeriod TEXT,
carrierForm TEXT,
notes TEXT,
type TEXT NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(fileNumber, type)
)`);
}
});
// 获取档案数据 (添加错误处理)
app.get('/api/archives', (req, res) => {
const type = req.query.type || 'document';
db.all('SELECT * FROM archives WHERE type = ? ORDER BY createdAt DESC', [type], (err, rows) => {
if (err) {
console.error('数据库查询错误:', err);
res.status(500).json({ error: '数据库查询失败' });
} else {
res.json(rows);
}
});
});
// 添加新档案
app.post('/api/archives', (req, res) => {
const {
fileNumber,
documentNumber,
responsiblePerson,
title,
date,
projectDate,
securityLevel,
pages,
retentionPeriod,
carrierForm,
notes,
type
} = req.body;
// 验证必填字段
if (!fileNumber || !title || !type) {
return res.status(400).json({
error: '档号、题名和类型为必填项'
});
}
const sql = `
INSERT INTO archives (
fileNumber, documentNumber, responsiblePerson, title, date,
projectDate, securityLevel, pages, retentionPeriod, carrierForm,
notes, type
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
const values = [
fileNumber,
documentNumber || null,
responsiblePerson || null,
title,
date || null,
projectDate || null,
securityLevel || null,
pages ? parseInt(pages) : null,
retentionPeriod || null,
carrierForm || null,
notes || null,
type
];
db.run(sql, values, function(err) {
if (err) {
// 处理唯一键冲突(档号重复)
if (err.code === 'SQLITE_CONSTRAINT') {
return res.status(409).json({
error: '该档号已存在,请使用其他档号'
});
}
return res.status(500).json({ error: err.message });
}
res.status(201).json({
id: this.lastID,
...req.body
});
});
});
// 更新档案
app.put('/api/archives/:id', (req, res) => {
const id = req.params.id;
const {
fileNumber,
documentNumber,
responsiblePerson,
title,
date,
projectDate,
securityLevel,
pages,
retentionPeriod,
carrierForm,
notes,
type
} = req.body;
// 验证必填字段
if (!fileNumber || !title || !type) {
return res.status(400).json({
error: '档号、题名和类型为必填项'
});
}
const sql = `
UPDATE archives SET
fileNumber = ?,
documentNumber = ?,
responsiblePerson = ?,
title = ?,
date = ?,
projectDate = ?,
securityLevel = ?,
pages = ?,
retentionPeriod = ?,
carrierForm = ?,
notes = ?,
type = ?
WHERE id = ?
`;
const values = [
fileNumber,
documentNumber || null,
responsiblePerson || null,
title,
date || null,
projectDate || null,
securityLevel || null,
pages ? parseInt(pages) : null,
retentionPeriod || null,
carrierForm || null,
notes || null,
type,
id
];
db.run(sql, values, function(err) {
if (err) {
// 处理唯一键冲突(档号重复)
if (err.code === 'SQLITE_CONSTRAINT') {
return res.status(409).json({
error: '该档号已存在,请使用其他档号'
});
}
return res.status(500).json({ error: err.message });
}
if (this.changes === 0) {
return res.status(404).json({ error: '档案未找到' });
}
res.json({
id: id,
...req.body
});
});
});
// 删除档案
app.delete('/api/archives/:id', (req, res) => {
const id = req.params.id;
db.run('DELETE FROM archives WHERE id = ?', [id], function(err) {
if (err) {
return res.status(500).json({ error: err.message });
}
if (this.changes === 0) {
return res.status(404).json({ error: '档案未找到' });
}
res.json({ success: true });
});
});
// 批量导入档案
app.post('/api/archives/batch-import', (req, res) => {
const data = req.body.data || [];
if (data.length === 0) {
return res.status(400).json({ error: '没有提供导入数据' });
}
let insertedCount = 0;
let skippedCount = 0;
let processed = 0;
// 开始事务
db.serialize(() => {
db.run('BEGIN TRANSACTION');
data.forEach(item => {
const {
fileNumber,
documentNumber,
responsiblePerson,
title,
date,
projectDate,
securityLevel,
pages,
retentionPeriod,
carrierForm,
notes,
type
} = item;
// 检查是否已存在相同档号和类型的档案
db.get('SELECT id FROM archives WHERE fileNumber = ? AND type = ?',
[fileNumber, type], (err, row) => {
if (err) {
// 错误处理
return;
}
if (row) {
// 跳过已存在的档案
skippedCount++;
checkComplete();
return;
}
// 插入新档案
const sql = `
INSERT INTO archives (
fileNumber, documentNumber, responsiblePerson, title, date,
projectDate, securityLevel, pages, retentionPeriod, carrierForm,
notes, type
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
const values = [
fileNumber,
documentNumber || null,
responsiblePerson || null,
title,
date || null,
projectDate || null,
securityLevel || null,
pages ? parseInt(pages) : null,
retentionPeriod || null,
carrierForm || null,
notes || null,
type
];
db.run(sql, values, function(err) {
if (!err) {
insertedCount++;
}
checkComplete();
});
});
});
function checkComplete() {
processed++;
if (processed === data.length) {
db.run('COMMIT', (err) => {
if (err) {
return res.status(500).json({ error: '导入失败' });
}
res.json({
insertedCount,
skippedCount
});
});
}
}
});
});
// 启动服务器
const port = 3000;
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
运行这个js文件报错,throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
最新发布