feat(web,installer): 更新下载源、升级资源缓存版本、本地化界面并新增管理功能

- 更新 update_machine.lua 和 installer.lua 中的远程资源下载地址,从旧云存储链接切换为 Gitea 仓库提交镜像地址
- 新增双向闸机专用安装脚本 installer_bi.lua
- 为所有网页HTML文件更新静态资源的缓存版本号,避免浏览器加载过期的静态文件缓存
- 修复登录页面的乱码文本,替换为标准简体中文内容,修正ICP备案标识文本
- 新增管理后台概览板块、快捷操作按钮,优化IC卡管理界面与响应式布局样式
This commit is contained in:
2026-06-21 10:37:25 +08:00
parent 108435e90d
commit 7fea8807b8
19 changed files with 2095 additions and 205 deletions
+94 -7
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="zh-CN">
<!-- 充满未知和不稳定的票务系统! -->
@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FSE铁路票务系统控制台</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="style.css?v=12">
<link rel="stylesheet" href="style.css?v=13">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
@@ -112,10 +112,22 @@
</div>
</div>
<div class="jr-admin-header-side">
<div class="jr-admin-sync-meta">
<span class="jr-admin-sync-label">当前模块</span>
<strong>{{ viewTitle }}</strong>
</div>
<div class="jr-admin-sync-meta">
<span class="jr-admin-sync-label">最近同步</span>
<strong>{{ lastSyncText }}</strong>
</div>
<span class="jr-admin-header-pill" :class="connected ? 'is-online' : 'is-offline'">
<i class="fas fa-circle"></i>
{{ connected ? '服务器在线' : '服务器离线' }}
</span>
<button class="btn primary" @click="refreshData" :disabled="isViewBusy">
<i class="fas" :class="isViewBusy ? 'fa-spinner fa-spin' : 'fa-rotate-right'"></i>
{{ isViewBusy ? '同步中' : '刷新视图' }}
</button>
</div>
</div>
<div class="content">
@@ -131,6 +143,32 @@
</div>
<p>当前模块:{{ viewTitle }},已加载 {{ lines.length }} 条线路、{{ stations.length }} 个站点。需要做批量调整时,可先在左侧切换模块再进入对应卡片操作区。</p>
</section>
<section class="jr-admin-overview-grid">
<article class="jr-admin-overview-card">
<span class="jr-admin-overview-label">当前模块</span>
<strong class="jr-admin-overview-value">{{ viewTitle }}</strong>
<p class="jr-admin-overview-note">{{ currentViewSummary }}</p>
</article>
<article class="jr-admin-overview-card">
<span class="jr-admin-overview-label">线路与站点</span>
<strong class="jr-admin-overview-value">{{ lines.length }} / {{ stations.length }}</strong>
<p class="jr-admin-overview-note">后台操作统一建立在线路、站点与票价的核心数据之上。</p>
</article>
<article class="jr-admin-overview-card">
<span class="jr-admin-overview-label">同步状态</span>
<strong class="jr-admin-overview-value">{{ isViewBusy ? '正在更新' : '数据已就绪' }}</strong>
<p class="jr-admin-overview-note">切换模块时只拉取当前视图需要的数据,减少等待与无效刷新。</p>
</article>
<article class="jr-admin-overview-card is-actions">
<span class="jr-admin-overview-label">快捷操作</span>
<div class="jr-admin-overview-actions">
<button class="btn" @click="currentView = 'management'"><i class="fas fa-network-wired"></i> 线路管理</button>
<button class="btn" @click="currentView = 'iccards'"><i class="fas fa-credit-card"></i> IC 卡务</button>
<button class="btn" @click="currentView = 'logs'"><i class="fas fa-list"></i> 查看日志</button>
<button class="btn primary" @click="refreshData" :disabled="isViewBusy"><i class="fas fa-rotate-right"></i> 立即同步</button>
</div>
</article>
</section>
<!-- 仪表盘-->
<div v-if="currentView === 'dashboard'">
<div class="grid">
@@ -479,6 +517,17 @@
</div>
<div v-if="currentView === 'iccards'">
<section class="jr-admin-section-toolbar">
<div class="jr-admin-section-toolbar-copy">
<span class="jr-admin-overview-label">IC CARD DESK</span>
<strong>{{ currentViewSummary }}</strong>
<p>把检索、充值、状态维护和事件核对集中在同一工作流里,减少在列表和详情之间来回跳转的成本。</p>
</div>
<div class="jr-admin-overview-actions">
<button class="btn" @click="fetchIcCards(false)" :disabled="isViewBusy"><i class="fas fa-list"></i> 刷新列表</button>
<button class="btn primary" @click="loadIcCard(icSelectedId)" :disabled="!icSelectedId || isViewBusy"><i class="fas fa-id-card"></i> 刷新详情</button>
</div>
</section>
<div class="grid">
<div class="card">
<div class="stat-label">IC 卡总数</div>
@@ -500,9 +549,24 @@
<div class="management-container ic-admin-layout">
<div class="management-sidebar">
<div class="card" style="margin-bottom:0; display:flex; flex-direction:column; min-height: 520px;">
<div class="card jr-admin-note-card">
<div class="flex between mb-4">
<h4>卡片列表</h4>
<h4>操作说明</h4>
<span class="badge">只读入口</span>
</div>
<p class="jr-admin-card-note">本模块不提供后台快速建卡,卡片发放流程保持在线上购卡或既有开卡流程中完成,后台仅负责检索、维护、充值与记录核对。</p>
<div class="jr-admin-note-list">
<div>1. 先检索卡号、订单号或持卡人。</div>
<div>2. 在详情面板修改状态并保存。</div>
<div>3. 需要补款时直接使用充值入口。</div>
</div>
</div>
<div class="card jr-admin-list-card" style="margin-bottom:0; display:flex; flex-direction:column; min-height: 520px;">
<div class="flex between mb-4">
<div>
<h4>卡片列表</h4>
<div class="jr-admin-list-meta">支持按卡号、订单号、凭证码和持卡人姓名检索。</div>
</div>
<span class="badge">{{ icCards.length }}</span>
</div>
<div class="flex mb-4" style="flex-wrap:wrap;">
@@ -536,8 +600,13 @@
<div class="management-main">
<div class="card">
<div class="flex between mb-4">
<h4>卡片详情</h4>
<div>
<h4>卡片详情</h4>
<div class="jr-admin-list-meta">在同一面板直接处理状态维护、充值和记录核对。</div>
</div>
<div class="flex" style="gap:8px;">
<button class="btn" @click="loadIcCard(icSelectedId)" :disabled="!icSelectedCard || isViewBusy"><i class="fas fa-rotate-right"></i> 刷新</button>
<button class="btn" @click="topupIcCard" :disabled="!icSelectedCard || isViewBusy"><i class="fas fa-wallet"></i> 充值</button>
<button class="btn danger" @click="deleteIcCard" :disabled="!icSelectedCard"><i class="fas fa-trash"></i> 删除卡</button>
<button class="btn primary" @click="saveIcCard" :disabled="!icSelectedCard"><i class="fas fa-save"></i> 保存</button>
</div>
@@ -554,6 +623,23 @@
</div>
<span class="badge" :class="icStatusInfo(icSelectedCard.status).className">{{ icStatusInfo(icSelectedCard.status).text }}</span>
</div>
<div class="jr-admin-summary-grid">
<div class="jr-admin-summary-item">
<span>当前余额</span>
<strong>{{ formatMoney(icSelectedCard.balance) }}</strong>
<small>支持直接发起充值。</small>
</div>
<div class="jr-admin-summary-item">
<span>事件记录</span>
<strong>{{ icSelectedEvents.length }}</strong>
<small>用于追踪开卡与状态变更。</small>
</div>
<div class="jr-admin-summary-item">
<span>订单来源</span>
<strong>{{ cardOrderCode(icSelectedCard) }}</strong>
<small>自动识别线上订单或现场办卡。</small>
</div>
</div>
<div class="ic-detail-grid">
<label class="ic-field">
<span>持卡人</span>
@@ -841,9 +927,9 @@
</div>
</main>
</div>
<script src="/custom-dialog.js?v=11"></script>
<script src="/custom-dialog.js?v=12"></script>
<script src="/public-status.js?v=13"></script>
<script src="index.js?v=2"></script>
<script src="index.js?v=3"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const isDomain = location.hostname.includes('fse-media.group');
@@ -873,3 +959,4 @@