feat: add web entry to download desktop client
This commit is contained in:
@@ -1796,6 +1796,10 @@
|
|||||||
{{ isLogin ? '还没有账号?' : '已有账号?' }}
|
{{ isLogin ? '还没有账号?' : '已有账号?' }}
|
||||||
<a @click="toggleAuthMode">{{ isLogin ? '立即注册' : '去登录' }}</a>
|
<a @click="toggleAuthMode">{{ isLogin ? '立即注册' : '去登录' }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="button" class="btn btn-secondary" style="margin-top: 12px;" :disabled="desktopClientDownloading" @click="downloadDesktopClient">
|
||||||
|
<i :class="desktopClientDownloading ? 'fas fa-spinner fa-spin' : 'fas fa-desktop'"></i>
|
||||||
|
{{ desktopClientDownloading ? '获取安装包...' : '下载桌面客户端' }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 导航栏 -->
|
<!-- 导航栏 -->
|
||||||
@@ -1818,6 +1822,10 @@
|
|||||||
|
|
||||||
<i class="fas fa-cog"></i> 设置
|
<i class="fas fa-cog"></i> 设置
|
||||||
</div>
|
</div>
|
||||||
|
<button class="btn btn-secondary" :disabled="desktopClientDownloading" @click="downloadDesktopClient">
|
||||||
|
<i :class="desktopClientDownloading ? 'fas fa-spinner fa-spin' : 'fas fa-download'"></i>
|
||||||
|
{{ desktopClientDownloading ? '准备中...' : '下载客户端' }}
|
||||||
|
</button>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
<span>{{ user.username }}</span>
|
<span>{{ user.username }}</span>
|
||||||
@@ -2480,6 +2488,21 @@
|
|||||||
<p class="settings-page-subtitle">管理存储策略、主题外观与账号安全</p>
|
<p class="settings-page-subtitle">管理存储策略、主题外观与账号安全</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3 class="settings-section-title" style="margin-bottom: 20px;">
|
||||||
|
<i class="fas fa-desktop"></i> 客户端下载
|
||||||
|
</h3>
|
||||||
|
<div class="settings-panel" style="background: var(--bg-card); padding: 20px; border-radius: 12px; border: 1px solid var(--glass-border); margin-bottom: 30px;">
|
||||||
|
<div style="display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;">
|
||||||
|
<div style="color: var(--text-secondary); font-size: 13px;">
|
||||||
|
下载最新版桌面客户端(Windows x64)
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" :disabled="desktopClientDownloading" @click="downloadDesktopClient">
|
||||||
|
<i :class="desktopClientDownloading ? 'fas fa-spinner fa-spin' : 'fas fa-download'"></i>
|
||||||
|
{{ desktopClientDownloading ? '获取安装包...' : '下载桌面客户端' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 存储管理 - 仅用户可选择 -->
|
<!-- 存储管理 - 仅用户可选择 -->
|
||||||
<div v-if="user && !user.is_admin && storagePermission === 'user_choice'" class="settings-section settings-storage-choice" style="margin-bottom: 40px;">
|
<div v-if="user && !user.is_admin && storagePermission === 'user_choice'" class="settings-section settings-storage-choice" style="margin-bottom: 40px;">
|
||||||
<h3 class="settings-section-title" style="margin-bottom: 20px;">
|
<h3 class="settings-section-title" style="margin-bottom: 20px;">
|
||||||
|
|||||||
@@ -271,6 +271,8 @@ createApp({
|
|||||||
error: '',
|
error: '',
|
||||||
lastLoadedAt: ''
|
lastLoadedAt: ''
|
||||||
},
|
},
|
||||||
|
desktopClientDownloading: false,
|
||||||
|
desktopClientDownloadUrl: '',
|
||||||
|
|
||||||
// 健康检测
|
// 健康检测
|
||||||
healthCheck: {
|
healthCheck: {
|
||||||
@@ -731,6 +733,70 @@ createApp({
|
|||||||
this._debouncedLoadUserProfile();
|
this._debouncedLoadUserProfile();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resolveDesktopClientUrl(rawUrl) {
|
||||||
|
const trimmed = String(rawUrl || '').trim();
|
||||||
|
if (!trimmed) return '';
|
||||||
|
try {
|
||||||
|
return new URL(trimmed, `${this.apiBase}/`).toString();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[客户端下载] 下载地址格式异常:', trimmed, error);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
triggerDesktopClientDownload(url) {
|
||||||
|
const resolved = this.resolveDesktopClientUrl(url);
|
||||||
|
if (!resolved) return false;
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = resolved;
|
||||||
|
link.target = '_blank';
|
||||||
|
link.rel = 'noopener noreferrer';
|
||||||
|
link.download = '';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchDesktopClientDownloadUrl() {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${this.apiBase}/api/client/desktop-update`, {
|
||||||
|
params: {
|
||||||
|
currentVersion: '0.0.0',
|
||||||
|
platform: 'windows-x64',
|
||||||
|
channel: 'stable'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const resolved = this.resolveDesktopClientUrl(response.data?.downloadUrl);
|
||||||
|
if (resolved) {
|
||||||
|
this.desktopClientDownloadUrl = resolved;
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[客户端下载] 获取最新版下载地址失败:', error?.message || error);
|
||||||
|
}
|
||||||
|
return this.resolveDesktopClientUrl(this.desktopClientDownloadUrl);
|
||||||
|
},
|
||||||
|
|
||||||
|
async downloadDesktopClient() {
|
||||||
|
if (this.desktopClientDownloading) return;
|
||||||
|
this.desktopClientDownloading = true;
|
||||||
|
try {
|
||||||
|
const downloadUrl = await this.fetchDesktopClientDownloadUrl();
|
||||||
|
if (!downloadUrl) {
|
||||||
|
this.showToast('warning', '暂无安装包', '服务器尚未配置客户端安装包下载地址');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.triggerDesktopClientDownload(downloadUrl)) {
|
||||||
|
this.showToast('error', '下载失败', '下载地址无效,请稍后重试');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.showToast('success', '开始下载', '客户端安装包已开始下载');
|
||||||
|
} finally {
|
||||||
|
this.desktopClientDownloading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// ========== 主题管理 ==========
|
// ========== 主题管理 ==========
|
||||||
// 初始化主题
|
// 初始化主题
|
||||||
async initTheme() {
|
async initTheme() {
|
||||||
|
|||||||
Reference in New Issue
Block a user