feat(web,backend,lua,installer): 新增Lua脚本版本管理功能及相关优化

- 升级售票机、检票机内置Lua脚本版本至v1.5.8
- 新增后端配置的lua_versions字段,统一管理售票机、检票机的Lua脚本版本
- 前端新增版本管理配置页面,支持版本号配置和一键补丁升级
- 为售票机、检票机添加远程版本检测功能,屏幕显示版本匹配状态标记
- 简化installer配置交互流程,优化站点代码输入方式
- 重构后端配置规范化处理逻辑,统一配置初始化与存储流程
- 优化售票机外设检测、支付检测逻辑,修复部分已知问题
This commit is contained in:
2026-06-28 16:30:17 +08:00
parent 81debd3b55
commit 07e4200c17
9 changed files with 480 additions and 136 deletions
+29 -2
View File
@@ -44,7 +44,11 @@ createApp({
const fares = ref([]);
const tickets = ref([]);
const stats = reactive({ sold_tickets: 0, revenue: 0 });
const config = reactive({ api_base: '', promotion: { name: '', discount: 1 } });
const config = reactive({
api_base: '',
promotion: { name: '', discount: 1 },
lua_versions: { ticketmachine: 'v1.5.8', gate: 'v1.5.8' }
});
const logs = ref([]);
const logCategory = ref('');
const logTypeFilter = ref('');
@@ -224,6 +228,20 @@ createApp({
}
};
const normalizeLuaVersion = (value) => {
let text = String(value || '').trim();
if (!text) text = 'v1.0.0';
if (!/^v/i.test(text)) text = `v${text}`;
return text;
};
const bumpPatchVersion = (value) => {
const normalized = normalizeLuaVersion(value);
const matched = /^v?(\d+)\.(\d+)\.(\d+)$/i.exec(normalized);
if (!matched) return normalized;
return `v${matched[1]}.${matched[2]}.${Number(matched[3]) + 1}`;
};
// Methods
const formatTime = (ts) => {
if (ts == null || ts === '') return '---';
@@ -1344,10 +1362,18 @@ createApp({
const saveConfig = async () => {
await runMutation(async () => {
config.lua_versions.ticketmachine = normalizeLuaVersion(config.lua_versions.ticketmachine);
config.lua_versions.gate = normalizeLuaVersion(config.lua_versions.gate);
await requestJson('/api/config', { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) }, { expectOk: true });
}, { successMessage: '保存成功' });
};
const bumpLuaVersion = async (device) => {
if (!config.lua_versions[device]) config.lua_versions[device] = 'v1.0.0';
config.lua_versions[device] = bumpPatchVersion(config.lua_versions[device]);
await saveConfig();
};
const exportData = () => {
window.open('/api/export', '_blank');
};
@@ -1390,6 +1416,7 @@ createApp({
});
socket.on('config:updated', (data) => {
Object.assign(config, data);
if (!config.lua_versions) config.lua_versions = { ticketmachine: 'v1.5.8', gate: 'v1.5.8' };
coreLoaded = true;
fareMapLoaded = false;
if (currentView.value === 'faremap') {
@@ -1579,7 +1606,7 @@ createApp({
saveCurrentFare, deleteCurrentFare, closeFareModal,
saveConfig, exportData, exportFareMap,
saveConfig, bumpLuaVersion, exportData, exportFareMap,
formatTime, formatLogDetail, getStationName, getStationInfo, loadFareMap, fetchData, refreshData: fetchData,
fareMapScale, fareMapLoading, fareMapError, zoomFareMapIn, zoomFareMapOut, zoomFareMapReset,
isTransferStation, getTransferTitleSuffix, getTransferLineBadges