feat(V0.2): 版本方案落地 —— 前端/外壳解绑, build 标识统一, 外壳版本展示
Docker Build and Push / build-image (push) Successful in 1m5s
Docker Build and Push / build-image (push) Successful in 1m5s
- check-version: 分组校验 (前端 package.json / 外壳 tauri.conf+Cargo), 两组不再要求相等; 分支前缀校验只针对前端版本 - build-ota: build_id 改为 YYYYMMDDHHmmss (北京时间, 与前端 BUILD_ID 同格式); sequence 保持毫秒仅用于判新 - 我的页: 当前版本恢复 v0.2.0 · build <原始BUILD_ID>; 新版本附 OTA build_id; 底部替换为外壳版本 (Tauri getVersion, Web 端 —) - README: 合并遗留 readme 全部内容并按决议重写版本管理章节; 新增 CHANGELOG.md (PATCH 仅明确提出时自增)
This commit is contained in:
+15
-12
@@ -2,10 +2,10 @@ import { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Avatar, Button, List, ProgressBar, Switch, Toast } from 'antd-mobile'
|
||||
import { useAuth } from '../auth/AuthContext.jsx'
|
||||
import { APP_VERSION, BUILD_ID } from '../version.js'
|
||||
import {
|
||||
applyOtaUpdate,
|
||||
checkOtaUpdate,
|
||||
fmtBuildId,
|
||||
getCurrentVersionInfo,
|
||||
getOtaDevMode,
|
||||
getOtaVersionInfo,
|
||||
@@ -14,14 +14,7 @@ import {
|
||||
setOtaDevMode,
|
||||
} from '../api/ota.js'
|
||||
|
||||
// seq/build 时间戳 → 'MM-dd HH:mm' (sequence 为毫秒时间戳, build_id 形如 seq-<ms>)
|
||||
export function fmtSeqTime(v) {
|
||||
const ms = typeof v === 'string' && v.startsWith('seq-') ? Number(v.slice(4)) : Number(v)
|
||||
if (!Number.isFinite(ms) || ms <= 0) return ''
|
||||
const p = (n) => String(n).padStart(2, '0')
|
||||
const d = new Date(ms)
|
||||
return `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
|
||||
}
|
||||
const inTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window
|
||||
|
||||
// "我" 页: 顶部 NavBar + 用户头像卡片 + 信息列表 + OTA 升级区
|
||||
// OTA 区:
|
||||
@@ -47,6 +40,16 @@ export default function MePage() {
|
||||
const [otaInfo, setOtaInfo] = useState(null) // 检查结果中的 info
|
||||
const [otaVersion, setOtaVersion] = useState(null) // hotswap 当前激活的覆盖包版本
|
||||
const [progress, setProgress] = useState({ received: 0, total: 0 })
|
||||
const [shellVersion, setShellVersion] = useState('') // 外壳 (APK/桌面包) 版本, 独立维护
|
||||
|
||||
// 外壳版本: 经 Tauri API 读取 (Web 端为空, 底部显示 —)
|
||||
useEffect(() => {
|
||||
if (!inTauri) return
|
||||
import('@tauri-apps/api/app')
|
||||
.then((m) => m.getVersion())
|
||||
.then(setShellVersion)
|
||||
.catch((e) => console.warn('[shell] getVersion failed:', e))
|
||||
}, [])
|
||||
const [error, setError] = useState('')
|
||||
// 判新模式: false(默认)=版本号比较, true=build sequence 比较; 值持久化在设备端
|
||||
const [devMode, setDevMode] = useState(() => getOtaDevMode())
|
||||
@@ -146,7 +149,7 @@ export default function MePage() {
|
||||
|
||||
{/* OTA 升级区 */}
|
||||
<List className="me-list" mode="card" header="前端升级 (OTA)">
|
||||
<List.Item extra={'v' + cur.version + (fmtSeqTime(cur.build) ? ' · ' + fmtSeqTime(cur.build) : '')}>当前版本</List.Item>
|
||||
<List.Item extra={'v' + cur.version + (cur.build ? ' · build ' + cur.build : '')}>当前版本</List.Item>
|
||||
<List.Item extra={otaVersion?.active ? 'v' + (otaVersion.version || '?') : '内置'}>
|
||||
运行资源
|
||||
</List.Item>
|
||||
@@ -206,7 +209,7 @@ export default function MePage() {
|
||||
</div>
|
||||
</List.Item>
|
||||
{otaState === 'available' && otaInfo && (
|
||||
<List.Item extra={'v' + otaInfo.version + (fmtSeqTime(otaInfo.sequence) ? ' · ' + fmtSeqTime(otaInfo.sequence) : '')}>
|
||||
<List.Item extra={'v' + otaInfo.version + (otaInfo.build ? ' · build ' + otaInfo.build : '')}>
|
||||
新版本
|
||||
{otaInfo.bundle_size ? ` (${(otaInfo.bundle_size / 1024).toFixed(0)} KB)` : ''}
|
||||
</List.Item>
|
||||
@@ -253,7 +256,7 @@ export default function MePage() {
|
||||
退出登录
|
||||
</List.Item>
|
||||
</List>
|
||||
<div className="me-version">v{APP_VERSION} · build {BUILD_ID}</div>
|
||||
<div className="me-version">外壳 v{shellVersion || '—'}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user