feat(web,backend,lua,installer): 新增Lua脚本版本管理功能及相关优化
- 升级售票机、检票机内置Lua脚本版本至v1.5.8 - 新增后端配置的lua_versions字段,统一管理售票机、检票机的Lua脚本版本 - 前端新增版本管理配置页面,支持版本号配置和一键补丁升级 - 为售票机、检票机添加远程版本检测功能,屏幕显示版本匹配状态标记 - 简化installer配置交互流程,优化站点代码输入方式 - 重构后端配置规范化处理逻辑,统一配置初始化与存储流程 - 优化售票机外设检测、支付检测逻辑,修复部分已知问题
This commit is contained in:
+12
-4
@@ -148,14 +148,16 @@ const resolveCurrentStationCode = (body, resolveStation) => {
|
||||
|
||||
// Config
|
||||
router.get('/config', (req, res) => {
|
||||
const cfg = DataService.getConfig();
|
||||
res.json({
|
||||
api_base: DataService.getConfig().api_base,
|
||||
current_station: DataService.getConfig().current_station,
|
||||
api_base: cfg.api_base,
|
||||
current_station: cfg.current_station,
|
||||
stations: DataService.getStations(),
|
||||
lines: DataService.getLines(),
|
||||
fares: DataService.getFares(),
|
||||
transfers: DataService.getConfig().transfers || [],
|
||||
promotion: DataService.getConfig().promotion || { name: '', discount: 1 }
|
||||
transfers: cfg.transfers || [],
|
||||
promotion: cfg.promotion || { name: '', discount: 1 },
|
||||
lua_versions: cfg.lua_versions || {}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -219,6 +221,12 @@ router.put('/config', async (req, res) => {
|
||||
if (!(d >= 0 && d <= 1)) return res.status(400).json({ ok: false, error: 'promotion.discount must be between 0 and 1' });
|
||||
cfg.promotion = { name: String(p.name || ''), discount: d };
|
||||
}
|
||||
if (incoming.lua_versions && typeof incoming.lua_versions === 'object') {
|
||||
cfg.lua_versions = {
|
||||
...(cfg.lua_versions || {}),
|
||||
...(incoming.lua_versions || {})
|
||||
};
|
||||
}
|
||||
await DataService.saveConfig(cfg);
|
||||
appendReqLog(req, { category: 'admin', type: 'update_config_generic', detail: incoming });
|
||||
io.emit('config:updated', cfg);
|
||||
|
||||
@@ -221,7 +221,8 @@ router.get('/fares/query', (req, res) => {
|
||||
router.get('/config', (req, res) => {
|
||||
const cfg = DataService.getConfig();
|
||||
res.json({
|
||||
promotion: { name: cfg.promotion?.name || '', discount: cfg.promotion?.discount ?? 1 }
|
||||
promotion: { name: cfg.promotion?.name || '', discount: cfg.promotion?.discount ?? 1 },
|
||||
lua_versions: cfg.lua_versions || {}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+34
-9
@@ -21,14 +21,39 @@ const pool = mysql.createPool({
|
||||
queueLimit: 0
|
||||
});
|
||||
|
||||
const DEFAULT_LUA_VERSIONS = {
|
||||
ticketmachine: 'v1.5.8',
|
||||
gate: 'v1.5.8'
|
||||
};
|
||||
|
||||
function normalizeLuaVersions(input) {
|
||||
const src = (input && typeof input === 'object') ? input : {};
|
||||
return {
|
||||
ticketmachine: String(src.ticketmachine || DEFAULT_LUA_VERSIONS.ticketmachine),
|
||||
gate: String(src.gate || DEFAULT_LUA_VERSIONS.gate)
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeConfig(input) {
|
||||
const src = (input && typeof input === 'object') ? input : {};
|
||||
return {
|
||||
...src,
|
||||
api_base: String(src.api_base || 'http://127.0.0.1:23333/api'),
|
||||
current_station: (src.current_station && typeof src.current_station === 'object')
|
||||
? src.current_station
|
||||
: { name: 'Station1', code: '01-01' },
|
||||
transfers: Array.isArray(src.transfers) ? src.transfers : [],
|
||||
promotion: {
|
||||
name: String(src?.promotion?.name || ''),
|
||||
discount: Number(src?.promotion?.discount ?? 1)
|
||||
},
|
||||
lua_versions: normalizeLuaVersions(src.lua_versions)
|
||||
};
|
||||
}
|
||||
|
||||
// In-memory cache for synchronous read access
|
||||
const cache = {
|
||||
config: {
|
||||
api_base: 'http://127.0.0.1:23333/api',
|
||||
current_station: { name: 'Station1', code: '01-01' },
|
||||
transfers: [],
|
||||
promotion: { name: '', discount: 1 }
|
||||
},
|
||||
config: normalizeConfig({}),
|
||||
stations: [],
|
||||
lines: [],
|
||||
fares: [],
|
||||
@@ -66,7 +91,7 @@ const DataService = {
|
||||
|
||||
// Load Cache
|
||||
const [configs] = await conn.query('SELECT v FROM kv_store WHERE k = ?', ['config']);
|
||||
if (configs.length > 0) cache.config = configs[0].v;
|
||||
if (configs.length > 0) cache.config = normalizeConfig(configs[0].v);
|
||||
else await conn.query('INSERT INTO kv_store (k, v) VALUES (?, ?)', ['config', JSON.stringify(cache.config)]);
|
||||
|
||||
const [stations] = await conn.query('SELECT data FROM stations');
|
||||
@@ -114,8 +139,8 @@ const DataService = {
|
||||
// Config
|
||||
getConfig: () => cache.config,
|
||||
saveConfig: async (cfg) => {
|
||||
cache.config = cfg;
|
||||
await pool.query('INSERT INTO kv_store (k, v) VALUES (?, ?) ON DUPLICATE KEY UPDATE v = ?', ['config', JSON.stringify(cfg), JSON.stringify(cfg)]);
|
||||
cache.config = normalizeConfig(cfg);
|
||||
await pool.query('INSERT INTO kv_store (k, v) VALUES (?, ?) ON DUPLICATE KEY UPDATE v = ?', ['config', JSON.stringify(cache.config), JSON.stringify(cache.config)]);
|
||||
},
|
||||
|
||||
// Stations
|
||||
|
||||
Reference in New Issue
Block a user