Files
training/website/server/store.mjs
T
Pine 97054a9699 feat: 培训业务 Web(Vite+React)
- user 端:课程/活动/报名/测评/政策/调研
- 后端已并入 server-core/app/training,/api/* 走 opc.pinesound.cn
2026-08-23 22:32:42 +08:00

85 lines
2.5 KiB
JavaScript

/**
* 数据存储层(JSON 文件落盘)
* -------------------------------------------------------------
* 集合:
* bookings —— 公益课报名 / 沙龙预约(前端预约表单)
* events —— 公益课 + 沙龙排期(后台可增删改)
* tests —— OPC 测评记录(前端测评上报)
* 说明:
* - 同步读写在数据量小的阶段足够;迁移真实数据库时替换本文件实现即可。
* - 带内存缓存,避免每次请求都读文件。
*/
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
const DIR = path.dirname(fileURLToPath(import.meta.url));
const FILES = {
accounts: path.join(DIR, 'accounts.json'),
bookings: path.join(DIR, 'bookings.json'),
events: path.join(DIR, 'events.json'),
tests: path.join(DIR, 'tests.json'),
policyLogs: path.join(DIR, 'policyLogs.json'),
planLogs: path.join(DIR, 'planLogs.json'),
surveyLogs: path.join(DIR, 'surveyLogs.json')
};
const CACHE = {};
function ensureFile(key) {
const file = FILES[key];
if (!file) throw new Error('unknown store: ' + key);
if (!existsSync(file)) {
mkdirSync(path.dirname(file), { recursive: true });
writeFileSync(file, '[]', 'utf8');
}
return file;
}
export function loadAll(key) {
if (CACHE[key] !== undefined) return CACHE[key];
const file = ensureFile(key);
try {
CACHE[key] = JSON.parse(readFileSync(file, 'utf8') || '[]');
} catch {
CACHE[key] = [];
}
if (!Array.isArray(CACHE[key])) CACHE[key] = [];
return CACHE[key];
}
export function save(key, list) {
CACHE[key] = Array.isArray(list) ? list : [];
const file = ensureFile(key);
writeFileSync(file, JSON.stringify(CACHE[key], null, 2), 'utf8');
}
export function add(key, entry) {
const list = loadAll(key);
list.push(entry);
save(key, list);
return entry;
}
export function update(key, id, patch) {
const list = loadAll(key);
const i = list.findIndex((x) => x.id === id);
if (i < 0) return null;
list[i] = { ...list[i], ...patch, id };
save(key, list);
return list[i];
}
export function remove(key, id) {
const list = loadAll(key);
const next = list.filter((x) => x.id !== id);
if (next.length === list.length) return false;
save(key, next);
return true;
}
/** 首次运行注入种子数据(仅当集合为空时) */
export function seedIfEmpty(key, seed) {
if (loadAll(key).length === 0) save(key, seed);
}