新增加教学数据查询API
This commit is contained in:
122
dsxapi/dsxapi.js
122
dsxapi/dsxapi.js
@@ -529,7 +529,7 @@ app.post('/api/competition/start', (req, res) => {
|
||||
}
|
||||
|
||||
// 启动定时备份
|
||||
const backupInterval = setInterval(() => {
|
||||
const backupInterval = setInterval(() => {
|
||||
if (!competitionStatus.isRunning) {
|
||||
clearInterval(backupInterval);
|
||||
return;
|
||||
@@ -541,7 +541,6 @@ app.post('/api/competition/start', (req, res) => {
|
||||
competitionStatus
|
||||
};
|
||||
|
||||
// 编码数据
|
||||
const dataStr = JSON.stringify(backupData, null, 2);
|
||||
const encodedData = encodeURIComponent(dataStr).split('').reverse().join('');
|
||||
const finalData = `EST_ENCODED_DATA:${encodedData}`;
|
||||
@@ -550,6 +549,32 @@ app.post('/api/competition/start', (req, res) => {
|
||||
path.join(tmpDirPath, `backup_${timestamp}.est`),
|
||||
finalData
|
||||
);
|
||||
try {
|
||||
const maxAgeMs = 60 * 60 * 1000;
|
||||
const now = Date.now();
|
||||
const files = fs.readdirSync(tmpDirPath).filter(f => f.endsWith('.est'));
|
||||
for (const f of files) {
|
||||
const fp = path.join(tmpDirPath, f);
|
||||
const stat = fs.statSync(fp);
|
||||
if (now - stat.mtimeMs > maxAgeMs) {
|
||||
fs.unlinkSync(fp);
|
||||
}
|
||||
}
|
||||
const remaining = fs.readdirSync(tmpDirPath)
|
||||
.filter(f => f.endsWith('.est'))
|
||||
.map(f => {
|
||||
const fp = path.join(tmpDirPath, f);
|
||||
const stat = fs.statSync(fp);
|
||||
return { fp, mtimeMs: stat.mtimeMs };
|
||||
})
|
||||
.sort((a, b) => a.mtimeMs - b.mtimeMs);
|
||||
if (remaining.length > 60) {
|
||||
const excess = remaining.length - 60;
|
||||
for (let i = 0; i < excess; i++) {
|
||||
fs.unlinkSync(remaining[i].fp);
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
}, 60000); // 每分钟备份一次
|
||||
|
||||
//console.log(`[COMPETITION] 比赛开始 - UUID: ${competitionStatus.UUID}`);
|
||||
@@ -613,6 +638,9 @@ app.get('/api/competition/status', (req, res) => {
|
||||
res.json(response);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// 比赛数据上传API
|
||||
app.post('/api/competition/data', (req, res) => {
|
||||
const { UUID, fingerprint, timestamp, data } = req.body;
|
||||
@@ -684,6 +712,94 @@ app.get('/api/competition/data', (req, res) => {
|
||||
res.json(competitionStatus.statisticsData);
|
||||
});
|
||||
|
||||
|
||||
// -----------------**************--------教学数据-----------***************--------------
|
||||
|
||||
// 教学数据查询API
|
||||
const teachingDir = path.join(__dirname, 'teaching_data');
|
||||
|
||||
app.post('/api/teaching/data', (req, res) => {
|
||||
const { fingerprint, scenario, timestamp, data } = req.body;
|
||||
if (!fingerprint || !scenario || !data) {
|
||||
return res.status(400).json({ error: '缺少必要参数' });
|
||||
}
|
||||
try {
|
||||
if (!fs.existsSync(teachingDir)) {
|
||||
fs.mkdirSync(teachingDir);
|
||||
}
|
||||
const filePath = path.join(teachingDir, `${scenario}.json`);
|
||||
let store = {};
|
||||
if (fs.existsSync(filePath)) {
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
store = JSON.parse(content || '{}');
|
||||
} catch {
|
||||
store = {};
|
||||
}
|
||||
}
|
||||
store[fingerprint] = { ...data, lastUpdate: timestamp };
|
||||
fs.writeFileSync(filePath, JSON.stringify(store, null, 2));
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('保存教学数据失败:', error);
|
||||
res.status(500).json({ error: '服务器内部错误' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/teaching/data', (req, res) => {
|
||||
const { scenario, fingerprint, org } = req.query;
|
||||
if (!scenario) {
|
||||
return res.status(400).json({ error: '缺少scenario参数' });
|
||||
}
|
||||
try {
|
||||
if (!fs.existsSync(teachingDir)) {
|
||||
if (fingerprint) {
|
||||
return res.status(404).json({ error: '未找到指定指纹数据' });
|
||||
}
|
||||
if (!org) {
|
||||
return res.status(400).json({ error: '缺少org参数' });
|
||||
}
|
||||
return res.json({});
|
||||
}
|
||||
const filePath = path.join(teachingDir, `${scenario}.json`);
|
||||
if (!fs.existsSync(filePath)) {
|
||||
if (fingerprint) {
|
||||
return res.status(404).json({ error: '未找到指定指纹数据' });
|
||||
}
|
||||
if (!org) {
|
||||
return res.status(400).json({ error: '缺少org参数' });
|
||||
}
|
||||
return res.json({});
|
||||
}
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const store = JSON.parse(content || '{}');
|
||||
if (fingerprint) {
|
||||
const entry = store[fingerprint] || null;
|
||||
if (!entry) {
|
||||
return res.status(404).json({ error: '未找到指定指纹数据' });
|
||||
}
|
||||
if (org && String(entry.org || '').toLowerCase() !== String(org).toLowerCase()) {
|
||||
return res.status(404).json({ error: '未找到指定指纹数据' });
|
||||
}
|
||||
return res.json(entry);
|
||||
}
|
||||
if (!org) {
|
||||
return res.status(400).json({ error: '缺少org参数' });
|
||||
}
|
||||
const filtered = Object.fromEntries(
|
||||
Object.entries(store).filter(([_, v]) => String((v && v.org) || '').toLowerCase() === String(org).toLowerCase())
|
||||
);
|
||||
return res.json(filtered);
|
||||
} catch (error) {
|
||||
console.error('读取教学数据失败:', error);
|
||||
res.status(500).json({ error: '服务器内部错误' });
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------**************--------------------------***************--------------
|
||||
|
||||
|
||||
|
||||
// 启动服务器
|
||||
if (require.main === module) {
|
||||
app.listen(PORT, () => {
|
||||
@@ -696,4 +812,4 @@ if (require.main === module) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = app;
|
||||
module.exports = app;
|
||||
|
||||
Reference in New Issue
Block a user