feat: 添加多项功能和修复

功能新增:
- OSS 存储使用情况显示(文件页面)
- OSS 当日流量统计(阿里云云监控API)
- 分享页面路由修复(/s/xxx 格式支持)

Bug修复:
- 修复分享页面资源路径(相对路径改绝对路径)
- 修复分享码获取逻辑(支持路径格式)
- 修复OSS配额undefined显示问题
- 修复登录流程OSS配置检查
- 修复文件数为null时的显示问题

依赖更新:
- 添加 @alicloud/cms20190101 云监控SDK
- 添加 @alicloud/openapi-client

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-22 21:04:22 +08:00
parent a86903fcdc
commit b135987fe8
3410 changed files with 494007 additions and 11 deletions

View File

@@ -1289,6 +1289,25 @@
}"></div>
</div>
</div>
<!-- OSS 存储使用情况 -->
<div v-if="storageType === 'oss'" style="display: flex; align-items: center; gap: 15px;">
<div v-if="ossUsage" style="font-size: 13px; color: var(--text-secondary);">
<i class="fas fa-database" style="color: #667eea;"></i>
已用: <span style="font-weight: 600; color: var(--text-primary);">{{ ossUsage.totalSizeFormatted }}</span>
<span v-if="ossUsage.fileCount" style="margin-left: 8px;">{{ ossUsage.fileCount }} 个文件</span>
<span v-if="ossQuota > 0" style="margin-left: 8px;">
/ 配额: <span style="font-weight: 600;">{{ formatBytes(ossQuota) }}</span>
({{ Math.round((ossUsage.totalSize / ossQuota) * 100) }}%)
</span>
</div>
<div v-else style="font-size: 13px; color: var(--text-muted);">
<i class="fas fa-database"></i> 加载存储信息中...
</div>
<span v-if="ossTraffic" style="margin-left: 15px; padding-left: 15px; border-left: 1px solid var(--glass-border);"><i class="fas fa-exchange-alt" style="color: #22c55e;"></i> 今日流量: <span style="font-weight: 600; color: var(--text-primary);">↓{{ ossTraffic.downloadFormatted }} ↑{{ ossTraffic.uploadFormatted }}</span></span>
<button class="btn btn-secondary" @click="loadOssUsage(); loadOssTraffic();" :disabled="ossUsageLoading" style="padding: 4px 10px; font-size: 12px;">
<i :class="ossUsageLoading ? 'fas fa-sync-alt fa-spin' : 'fas fa-sync-alt'"></i>
</button>
</div>
</div>
<!-- 路径导航 (面包屑) -->
@@ -3520,6 +3539,6 @@
}
</style>
<script src="app.js?v=20260122002"></script>
<script src="app.js?v=20260122007"></script>
</body>
</html>

View File

@@ -300,6 +300,8 @@ createApp({
ossUsage: null, // { totalSize, totalSizeFormatted, fileCount, dirCount }
ossUsageLoading: false,
ossUsageError: null,
ossTraffic: null, // 当日流量统计
ossTrafficLoading: false,
// 主题设置
currentTheme: 'dark', // 当前生效的主题: 'dark' 或 'light'
@@ -683,13 +685,17 @@ handleDragLeave(e) {
else {
// 如果用户可以使用本地存储,直接进入文件页面
if (this.storagePermission === 'local_only' || this.storagePermission === 'user_choice') {
this.currentView = 'files';
this.currentView = "files";
this.loadOssUsage();
this.loadOssTraffic(); // 加载当日流量 // 加载OSS使用情况
this.loadFiles('/');
}
// 如果仅OSS模式需要检查是否配置了OSS包括系统级统一配置
else if (this.storagePermission === 'oss_only') {
if (this.user?.oss_config_source !== 'none') {
this.currentView = 'files';
this.currentView = "files";
this.loadOssUsage();
this.loadOssTraffic(); // 加载当日流量 // 加载OSS使用情况
this.loadFiles('/');
} else {
this.currentView = 'settings';
@@ -698,7 +704,9 @@ handleDragLeave(e) {
}
} else {
// 默认行为:跳转到文件页面
this.currentView = 'files';
this.currentView = "files";
this.loadOssUsage();
this.loadOssTraffic(); // 加载当日流量 // 加载OSS使用情况
this.loadFiles('/');
}
}
@@ -2487,11 +2495,30 @@ handleDragLeave(e) {
}
},
// 加载 OSS 当日流量统计
async loadOssTraffic() {
if (this.ossTrafficLoading) return;
if (!this.user || this.user?.oss_config_source === "none") return;
this.ossTrafficLoading = true;
try {
const response = await axios.get(`${this.apiBase}/api/oss/traffic`);
if (response.data.success) {
this.ossTraffic = response.data.traffic;
}
} catch (error) {
console.error("[OSS流量] 加载失败:", error);
this.ossTraffic = null;
} finally {
this.ossTrafficLoading = false;
}
},
// 刷新存储空间使用统计(根据当前存储类型)
async refreshStorageUsage() {
if (this.storageType === 'oss' && this.user?.oss_config_source !== 'none') {
// 刷新 OSS 空间统计
await this.loadOssUsage();
this.loadOssTraffic(); // 加载当日流量
} else if (this.storageType === 'local') {
// 刷新本地存储统计(通过重新获取用户信息)
await this.loadUserProfile();
@@ -2622,6 +2649,11 @@ handleDragLeave(e) {
// 根据视图类型自动加载对应数据
switch (view) {
case 'files':
// 如果是 OSS 存储,加载使用情况
if (this.storageType === 'oss') {
this.loadOssUsage();
this.loadOssTraffic(); // 加载当日流量
}
// 切换到文件视图时,重新加载文件列表
this.loadFiles(this.currentPath);
break;
@@ -3222,3 +3254,4 @@ handleDragLeave(e) {
}
}
}).mount('#app');

View File

@@ -4,9 +4,9 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件分享 - 玩玩云</title>
<script src="libs/vue.global.prod.js"></script>
<script src="libs/axios.min.js"></script>
<link rel="stylesheet" href="libs/fontawesome/css/all.min.css">
<script src="/libs/vue.global.prod.js"></script>
<script src="/libs/axios.min.js"></script>
<link rel="stylesheet" href="/libs/fontawesome/css/all.min.css">
<style>
/* 防止 Vue 初始化前显示原始模板 */
[v-cloak] { display: none !important; }
@@ -776,8 +776,14 @@
methods: {
async init() {
const urlParams = new URLSearchParams(window.location.search);
this.shareCode = urlParams.get('code');
// 支持两种URL格式: /s/xxx 或 /s/?code=xxx
const pathMatch = window.location.pathname.match(/\/s\/([^/]+)/);
if (pathMatch) {
this.shareCode = pathMatch[1];
} else {
const urlParams = new URLSearchParams(window.location.search);
this.shareCode = urlParams.get('code');
}
if (!this.shareCode) {
this.errorMessage = '无效的分享链接';