feat: v3.1.0 OSS直连优化与代码质量提升
- 🚀 OSS 直连上传下载(用户直连OSS,不经过后端) - ✨ 新增 Presigned URL 签名接口 - ✨ 支持自定义 OSS endpoint 配置 - 🐛 修复 buildS3Config 不支持自定义 endpoint 的问题 - 🐛 清理残留的 basic-ftp 依赖 - ♻️ 更新 package.json 项目描述和版本号 - 📝 完善 README.md 更新日志和 CORS 配置说明 - 🔒 安全性增强:签名 URL 15分钟/1小时有效期 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1322,7 +1322,7 @@
|
||||
<button v-if="storageType === 'local'" class="btn btn-primary" @click="showCreateFolderModal = true">
|
||||
<i class="fas fa-folder-plus"></i> 新建文件夹
|
||||
</button>
|
||||
<!-- SFTP存储:显示下载上传工具按钮 -->
|
||||
<!-- OSS存储:显示下载上传工具按钮 -->
|
||||
<button v-else class="btn btn-primary" @click="downloadUploadTool" :disabled="downloadingTool">
|
||||
<i :class="downloadingTool ? 'fas fa-spinner fa-spin' : 'fas fa-download'"></i>
|
||||
{{ downloadingTool ? '生成中...' : '下载上传工具' }}
|
||||
@@ -1617,83 +1617,83 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SFTP 配置引导弹窗 -->
|
||||
<div v-if="showSftpGuideModal" class="modal-overlay" @mousedown.self="handleModalMouseDown" @mouseup.self="handleModalMouseUp('showSftpGuideModal')">
|
||||
<!-- OSS 配置引导弹窗 -->
|
||||
<div v-if="showOssGuideModal" class="modal-overlay" @mousedown.self="handleModalMouseDown" @mouseup.self="handleModalMouseUp('showOssGuideModal')">
|
||||
<div class="modal-content" @click.stop style="max-width: 520px; border-radius: 16px; overflow: hidden;">
|
||||
<div style="background: linear-gradient(135deg,#667eea,#764ba2); color: white; padding: 18px;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<i class="fas fa-server" style="font-size: 20px;"></i>
|
||||
<h3 style="margin: 0; font-size: 20px;">切换到 SFTP 存储</h3>
|
||||
<i class="fas fa-cloud" style="font-size: 20px;"></i>
|
||||
<h3 style="margin: 0; font-size: 20px;">切换到 OSS 存储</h3>
|
||||
</div>
|
||||
<p style="margin: 8px 0 0 0; opacity: 0.9; font-size: 14px;">先配置连接信息,再切换到你的专属 SFTP 空间。</p>
|
||||
<p style="margin: 8px 0 0 0; opacity: 0.9; font-size: 14px;">先配置云服务信息,再切换到你的专属 OSS 空间。</p>
|
||||
</div>
|
||||
<div style="padding: 18px;">
|
||||
<p style="color: var(--text-secondary); line-height: 1.6; margin-bottom: 16px;">
|
||||
我们会在你填写完成后再切换,确保过程平滑无干扰。
|
||||
支持阿里云 OSS、腾讯云 COS、AWS S3 等兼容 S3 协议的云存储服务。
|
||||
</p>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<button class="btn btn-secondary" @click="closeSftpGuideModal">稍后再说</button>
|
||||
<button class="btn btn-primary" @click="proceedSftpGuide">
|
||||
<i class="fas fa-tools"></i> 去配置 SFTP
|
||||
<button class="btn btn-secondary" @click="closeOssGuideModal">稍后再说</button>
|
||||
<button class="btn btn-primary" @click="proceedOssGuide">
|
||||
<i class="fas fa-tools"></i> 去配置 OSS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SFTP 配置弹窗 -->
|
||||
<div v-if="showSftpConfigModal" class="modal-overlay" @mousedown.self="handleModalMouseDown" @mouseup.self="handleModalMouseUp('showSftpConfigModal')">
|
||||
<!-- OSS 配置弹窗 -->
|
||||
<div v-if="showOssConfigModal" class="modal-overlay" @mousedown.self="handleModalMouseDown" @mouseup.self="handleModalMouseUp('showOssConfigModal')">
|
||||
<div class="modal-content" @click.stop style="max-width: 720px; border-radius: 16px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
|
||||
<div>
|
||||
<h3 style="margin: 0 0 6px 0;">配置 SFTP 存储</h3>
|
||||
<p style="margin: 0; color: var(--text-muted); font-size: 13px;">填写连接信息或导入 .inf 配置,保存后即可切换到 SFTP 模式。</p>
|
||||
<h3 style="margin: 0 0 6px 0;">配置 OSS 存储</h3>
|
||||
<p style="margin: 0; color: var(--text-muted); font-size: 13px;">填写云服务配置信息,保存后即可切换到 OSS 模式。</p>
|
||||
</div>
|
||||
<button class="btn btn-secondary" style="padding: 6px 10px;" @click="closeSftpConfigModal">
|
||||
<button class="btn btn-secondary" style="padding: 6px 10px;" @click="closeOssConfigModal">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr; gap: 14px;">
|
||||
<div style="border: 1px dashed var(--glass-border); border-radius: 12px; padding: 16px; background: rgba(255,255,255,0.03); text-align: center; cursor: pointer; transition: all .3s;"
|
||||
@click="$refs.configFileInput.click()"
|
||||
@dragover.prevent="$event.currentTarget.style.background='#eef2ff'"
|
||||
@dragleave.prevent="$event.currentTarget.style.background='#f8fafc'"
|
||||
@drop.prevent="handleConfigFileDrop">
|
||||
<i class="fas fa-cloud-upload-alt" style="font-size: 36px; color: #667eea; margin-bottom: 8px;"></i>
|
||||
<div style="font-weight: 600; color: var(--text-primary);">导入配置文件</div>
|
||||
<div style="color: var(--text-muted); font-size: 13px; margin-top: 4px;">点击选择或拖拽 .inf 文件</div>
|
||||
<input type="file" accept=".inf" @change="handleConfigFileUpload" ref="configFileInput" style="display: none;">
|
||||
<form @submit.prevent="updateOssConfig" style="display: grid; gap: 12px;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">云服务商</label>
|
||||
<select class="form-input" v-model="ossConfigForm.oss_provider" required style="cursor: pointer;">
|
||||
<option value="aliyun">阿里云 OSS</option>
|
||||
<option value="tencent">腾讯云 COS</option>
|
||||
<option value="aws">AWS S3</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="updateFtpConfig" style="display: grid; gap: 12px;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">主机地址</label>
|
||||
<input type="text" class="form-input" v-model="ftpConfigForm.ftp_host" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">端口</label>
|
||||
<input type="number" class="form-input" v-model="ftpConfigForm.ftp_port" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">用户名</label>
|
||||
<input type="text" class="form-input" v-model="ftpConfigForm.ftp_user" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">密码 (留空保留现有密码)</label>
|
||||
<input type="password" class="form-input" v-model="ftpConfigForm.ftp_password" placeholder="留空保留现有密码">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">HTTP下载基础URL (可选)</label>
|
||||
<input type="text" class="form-input" v-model="ftpConfigForm.http_download_base_url" placeholder="例如: http://example.com/files">
|
||||
<small style="color: var(--text-secondary); font-size: 12px; margin-top: 5px; display: block;">
|
||||
配置后可通过 HTTP 直接下载,例如: 基础URL/文件路径。
|
||||
</small>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 4px;">
|
||||
<button type="button" class="btn btn-secondary" @click="closeSftpConfigModal">取消</button>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> 保存配置
|
||||
<div class="form-group">
|
||||
<label class="form-label">地域</label>
|
||||
<input type="text" class="form-input" v-model="ossConfigForm.oss_region" placeholder="如: oss-cn-hangzhou / ap-guangzhou / us-east-1" required>
|
||||
<small style="color: var(--text-secondary); font-size: 12px; margin-top: 5px; display: block;">
|
||||
阿里云: oss-cn-hangzhou, 腾讯云: ap-guangzhou, AWS: us-east-1
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Access Key ID</label>
|
||||
<input type="text" class="form-input" v-model="ossConfigForm.oss_access_key_id" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Access Key Secret (留空保留现有密钥)</label>
|
||||
<input type="password" class="form-input" v-model="ossConfigForm.oss_access_key_secret" placeholder="留空保留现有密钥">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">存储桶名称</label>
|
||||
<input type="text" class="form-input" v-model="ossConfigForm.oss_bucket" placeholder="如: my-storage-bucket" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">自定义 Endpoint (可选)</label>
|
||||
<input type="text" class="form-input" v-model="ossConfigForm.oss_endpoint" placeholder="兼容 S3 的服务可填写自定义地址">
|
||||
<small style="color: var(--text-secondary); font-size: 12px; margin-top: 5px; display: block;">
|
||||
一般不需要填写,仅在使用自定义 S3 兼容服务时需要。
|
||||
</small>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 4px;">
|
||||
<button type="button" class="btn btn-secondary" @click="closeOssConfigModal">取消</button>
|
||||
<button type="submit" class="btn btn-primary" :disabled="ossConfigSaving" :style="{ opacity: ossConfigSaving ? 0.7 : 1 }">
|
||||
<i class="fas" :class="ossConfigSaving ? 'fa-spinner fa-spin' : 'fa-save'"></i>
|
||||
{{ ossConfigSaving ? '保存中...' : '保存配置' }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1730,9 +1730,9 @@
|
||||
</div>
|
||||
<div v-if="storageSwitching" style="color: #4b5fc9; font-weight: 600; display: inline-flex; align-items: center; gap: 8px;">
|
||||
<i class="fas fa-sync-alt fa-spin"></i>
|
||||
正在切换到 {{ storageSwitchTarget === 'sftp' ? 'SFTP 存储' : '本地存储' }}...
|
||||
正在切换到 {{ storageSwitchTarget === 'oss' ? 'OSS 存储' : '本地存储' }}...
|
||||
</div>
|
||||
<div v-else style="color: var(--text-secondary); font-size: 13px;">本地存储适合快速读写,SFTP 适合独立服务器空间</div>
|
||||
<div v-else style="color: var(--text-secondary); font-size: 13px;">本地存储适合快速读写,OSS 适合云存储扩展</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 16px; background: var(--bg-secondary); border-radius: 12px; padding: 12px; border: 1px solid var(--glass-border);">
|
||||
@@ -1782,53 +1782,53 @@
|
||||
<div style="background: var(--bg-secondary); border: 1px solid var(--glass-border); border-radius: 12px; padding: 16px; box-shadow: 0 6px 20px rgba(0,0,0,0.15); display: flex; flex-direction: column; height: 100%;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: 700; color: var(--text-primary); display: flex; gap: 8px; align-items: center;">
|
||||
<i class="fas fa-server" style="color: var(--accent-1);"></i> SFTP 存储
|
||||
<i class="fas fa-cloud" style="color: var(--accent-1);"></i> OSS 存储
|
||||
</div>
|
||||
<span v-if="storageType === 'sftp'" style="font-size: 12px; color: var(--accent-1); background: rgba(102,126,234,0.15); padding: 4px 8px; border-radius: 999px;">当前</span>
|
||||
<span v-if="storageType === 'oss'" style="font-size: 12px; color: var(--accent-1); background: rgba(102,126,234,0.15); padding: 4px 8px; border-radius: 999px;">当前</span>
|
||||
</div>
|
||||
<div style="color: var(--text-secondary); font-size: 13px; margin-bottom: 10px;">使用你自己的服务器空间,独立存储更灵活。</div>
|
||||
<div v-if="user?.has_ftp_config" style="font-size: 13px; color: var(--text-primary); margin-bottom: 10px;">
|
||||
已配置: {{ user.ftp_host }}:{{ user.ftp_port }}
|
||||
<div style="color: var(--text-secondary); font-size: 13px; margin-bottom: 10px;">使用云存储服务,安全可靠扩展性强。</div>
|
||||
<div v-if="user?.has_oss_config" style="font-size: 13px; color: var(--text-primary); margin-bottom: 10px;">
|
||||
已配置: {{ user.oss_provider }} / {{ user.oss_bucket }}
|
||||
</div>
|
||||
<div v-else style="font-size: 13px; color: #f59e0b; background: rgba(245, 158, 11, 0.1); border: 1px dashed rgba(245,158,11,0.4); padding: 10px; border-radius: 8px; margin-bottom: 10px;">
|
||||
<i class="fas fa-exclamation-circle"></i> 先填写 SFTP 连接信息再切换
|
||||
<i class="fas fa-exclamation-circle"></i> 先填写 OSS 配置信息再切换
|
||||
</div>
|
||||
<!-- SFTP空间使用统计(user_choice模式) -->
|
||||
<div v-if="user?.has_ftp_config" style="margin-bottom: 10px; padding: 10px; background: rgba(255,255,255,0.03); border-radius: 8px; border: 1px solid var(--glass-border);">
|
||||
<!-- OSS空间使用统计(user_choice模式) -->
|
||||
<div v-if="user?.has_oss_config" style="margin-bottom: 10px; padding: 10px; background: rgba(255,255,255,0.03); border-radius: 8px; border: 1px solid var(--glass-border);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
||||
<span style="font-size: 12px; color: var(--text-muted);">空间统计</span>
|
||||
<button
|
||||
style="background: none; border: none; color: #4b5fc9; cursor: pointer; font-size: 12px; padding: 2px 6px;"
|
||||
@click.stop="loadSftpUsage()"
|
||||
:disabled="sftpUsageLoading">
|
||||
<i :class="sftpUsageLoading ? 'fas fa-sync-alt fa-spin' : 'fas fa-sync-alt'"></i>
|
||||
@click.stop="loadOssUsage()"
|
||||
:disabled="ossUsageLoading">
|
||||
<i :class="ossUsageLoading ? 'fas fa-sync-alt fa-spin' : 'fas fa-sync-alt'"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="sftpUsageLoading && !sftpUsage" style="text-align: center; color: #667eea; font-size: 12px;">
|
||||
<div v-if="ossUsageLoading && !ossUsage" style="text-align: center; color: #667eea; font-size: 12px;">
|
||||
<i class="fas fa-spinner fa-spin"></i> 统计中...
|
||||
</div>
|
||||
<div v-else-if="sftpUsageError" style="font-size: 12px; color: #ef4444;">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ sftpUsageError }}
|
||||
<div v-else-if="ossUsageError" style="font-size: 12px; color: #ef4444;">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ ossUsageError }}
|
||||
</div>
|
||||
<div v-else-if="sftpUsage" style="font-size: 13px; font-weight: 600; color: #4b5fc9;">
|
||||
{{ sftpUsage.totalSizeFormatted }}
|
||||
<span style="font-weight: 400; color: var(--text-muted); font-size: 12px;">({{ sftpUsage.fileCount }} 文件)</span>
|
||||
<div v-else-if="ossUsage" style="font-size: 13px; font-weight: 600; color: #4b5fc9;">
|
||||
{{ ossUsage.totalSizeFormatted }}
|
||||
<span style="font-weight: 400; color: var(--text-muted); font-size: 12px;">({{ ossUsage.fileCount }} 文件)</span>
|
||||
</div>
|
||||
<div v-else style="font-size: 12px; color: var(--text-muted);">点击刷新查看</div>
|
||||
</div>
|
||||
<div style="margin-top: auto;">
|
||||
<button
|
||||
class="btn"
|
||||
:class="user?.has_ftp_config ? 'btn-primary' : 'btn-secondary'"
|
||||
:class="user?.has_oss_config ? 'btn-primary' : 'btn-secondary'"
|
||||
style="width: 100%; border-radius: 10px;"
|
||||
:disabled="storageType === 'sftp' || storageSwitching"
|
||||
@click="switchStorage('sftp')">
|
||||
:disabled="storageType === 'oss' || storageSwitching"
|
||||
@click="switchStorage('oss')">
|
||||
<i class="fas fa-random"></i>
|
||||
{{ user?.has_ftp_config ? '切到 SFTP 存储' : '去配置 SFTP' }}
|
||||
{{ user?.has_oss_config ? '切到 OSS 存储' : '去配置 OSS' }}
|
||||
</button>
|
||||
<div style="margin-top: 8px; text-align: center;">
|
||||
<a style="color: #4b5fc9; font-size: 13px; text-decoration: none; cursor: pointer;" @click.prevent="openSftpConfigModal">
|
||||
<i class="fas fa-tools"></i> 配置 / 修改 SFTP
|
||||
<a style="color: #4b5fc9; font-size: 13px; text-decoration: none; cursor: pointer;" @click.prevent="openOssConfigModal">
|
||||
<i class="fas fa-tools"></i> 配置 / 修改 OSS
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1837,7 +1837,7 @@
|
||||
|
||||
<div style="margin-top: 12px; padding: 10px 12px; background: rgba(255,255,255,0.05); border-radius: 10px; font-size: 13px; color: var(--text-secondary);">
|
||||
<i class="fas fa-info-circle" style="color: #4b5fc9;"></i>
|
||||
本地存储速度快但受配额限制;SFTP 需先配置连接,切换过程中可继续查看文件列表。
|
||||
本地存储速度快但受配额限制;OSS 支持多家云服务商,切换过程中可继续查看文件列表。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1872,44 +1872,44 @@
|
||||
|
||||
<div style="padding: 10px; background: rgba(59, 130, 246, 0.15); border-left: 4px solid #3b82f6; border-radius: 6px; font-size: 13px; color: #93c5fd;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>说明:</strong> 管理员已将您的存储权限设置为"仅本地存储",您的文件存储在服务器本地,速度快但有配额限制。如需使用SFTP存储,请联系管理员修改权限设置。
|
||||
<strong>说明:</strong> 管理员已将您的存储权限设置为"仅本地存储",您的文件存储在服务器本地,速度快但有配额限制。如需使用OSS存储,请联系管理员修改权限设置。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SFTP 概览 / 配置入口 - 仅SFTP权限 -->
|
||||
<div v-if="user && !user.is_admin && storagePermission === 'sftp_only'" style="margin-bottom: 40px;">
|
||||
<!-- OSS 概览 / 配置入口 - 仅OSS权限 -->
|
||||
<div v-if="user && !user.is_admin && storagePermission === 'oss_only'" style="margin-bottom: 40px;">
|
||||
<h3 style="margin-bottom: 20px;">
|
||||
<i class="fas fa-server"></i> SFTP存储
|
||||
<i class="fas fa-cloud"></i> OSS存储
|
||||
</h3>
|
||||
<div style="background: rgba(255,255,255,0.03); padding: 20px; border-radius: 12px; border: 1px solid var(--glass-border);">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px;">
|
||||
<div>
|
||||
<div style="font-weight: 700; color: var(--text-primary); display: flex; gap: 8px; align-items: center;">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
仅 SFTP 模式
|
||||
仅 OSS 模式
|
||||
</div>
|
||||
<div style="color: var(--text-secondary); font-size: 13px; margin-top: 6px;">
|
||||
{{ user.has_ftp_config ? '已配置服务器,可正常使用 SFTP 存储。' : '还未配置 SFTP,请先填写连接信息。' }}
|
||||
{{ user.has_oss_config ? '已配置云服务,可正常使用 OSS 存储。' : '还未配置 OSS,请先填写配置信息。' }}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" @click="openSftpConfigModal()" style="border-radius: 10px;">
|
||||
<i class="fas fa-tools"></i> 配置 / 修改 SFTP
|
||||
<button class="btn btn-primary" @click="openOssConfigModal()" style="border-radius: 10px;">
|
||||
<i class="fas fa-tools"></i> 配置 / 修改 OSS
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 服务器信息 -->
|
||||
<div v-if="user.has_ftp_config" style="margin-bottom: 12px; padding: 12px; background: var(--bg-secondary); border-radius: 10px; border: 1px solid var(--glass-border);">
|
||||
<!-- OSS服务器信息 -->
|
||||
<div v-if="user.has_oss_config" style="margin-bottom: 12px; padding: 12px; background: var(--bg-secondary); border-radius: 10px; border: 1px solid var(--glass-border);">
|
||||
<div style="font-weight: 600; color: var(--text-primary); margin-bottom: 8px;">
|
||||
<i class="fas fa-server" style="color: var(--accent-1);"></i> 服务器信息
|
||||
<i class="fas fa-cloud" style="color: var(--accent-1);"></i> 云服务信息
|
||||
</div>
|
||||
<div style="color: var(--text-secondary); font-size: 14px;">
|
||||
{{ user.ftp_host }}:{{ user.ftp_port }}
|
||||
{{ user.oss_provider }} / {{ user.oss_bucket }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SFTP空间使用统计 -->
|
||||
<div v-if="user.has_ftp_config" style="margin-bottom: 12px; padding: 12px; background: var(--bg-secondary); border-radius: 10px; border: 1px solid var(--glass-border);">
|
||||
<!-- OSS空间使用统计 -->
|
||||
<div v-if="user.has_oss_config" style="margin-bottom: 12px; padding: 12px; background: var(--bg-secondary); border-radius: 10px; border: 1px solid var(--glass-border);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: 600; color: var(--text-primary);">
|
||||
<i class="fas fa-chart-pie" style="color: #667eea;"></i> 空间使用统计
|
||||
@@ -1917,51 +1917,47 @@
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
style="padding: 4px 10px; font-size: 12px; border-radius: 6px;"
|
||||
@click="loadSftpUsage()"
|
||||
:disabled="sftpUsageLoading">
|
||||
<i :class="sftpUsageLoading ? 'fas fa-sync-alt fa-spin' : 'fas fa-sync-alt'"></i>
|
||||
{{ sftpUsageLoading ? '统计中...' : '刷新' }}
|
||||
@click="loadOssUsage()"
|
||||
:disabled="ossUsageLoading">
|
||||
<i :class="ossUsageLoading ? 'fas fa-sync-alt fa-spin' : 'fas fa-sync-alt'"></i>
|
||||
{{ ossUsageLoading ? '统计中...' : '刷新' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<div v-if="sftpUsageLoading && !sftpUsage" style="text-align: center; padding: 20px; color: #667eea;">
|
||||
<div v-if="ossUsageLoading && !ossUsage" style="text-align: center; padding: 20px; color: #667eea;">
|
||||
<i class="fas fa-spinner fa-spin" style="font-size: 24px;"></i>
|
||||
<div style="margin-top: 8px; font-size: 13px;">正在统计 SFTP 空间使用情况...</div>
|
||||
<div style="margin-top: 8px; font-size: 13px;">正在统计 OSS 空间使用情况...</div>
|
||||
<div style="margin-top: 4px; font-size: 12px; color: var(--text-muted);">(文件较多时可能需要一些时间)</div>
|
||||
</div>
|
||||
|
||||
<!-- 错误提示 -->
|
||||
<div v-else-if="sftpUsageError" style="padding: 12px; background: rgba(239, 68, 68, 0.1); border-radius: 8px; color: #ef4444; font-size: 13px;">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ sftpUsageError }}
|
||||
<div v-else-if="ossUsageError" style="padding: 12px; background: rgba(239, 68, 68, 0.1); border-radius: 8px; color: #ef4444; font-size: 13px;">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ ossUsageError }}
|
||||
</div>
|
||||
|
||||
<!-- 统计结果 -->
|
||||
<div v-else-if="sftpUsage" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px;">
|
||||
<div v-else-if="ossUsage" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px;">
|
||||
<div style="text-align: center; padding: 12px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white;">
|
||||
<div style="font-size: 20px; font-weight: 700;">{{ sftpUsage.totalSizeFormatted }}</div>
|
||||
<div style="font-size: 20px; font-weight: 700;">{{ ossUsage.totalSizeFormatted }}</div>
|
||||
<div style="font-size: 12px; opacity: 0.9; margin-top: 4px;">总使用空间</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 12px; background: rgba(59, 130, 246, 0.1); border-radius: 10px; border: 1px solid rgba(59,130,246,0.2);">
|
||||
<div style="font-size: 20px; font-weight: 700; color: #3b82f6;">{{ sftpUsage.fileCount }}</div>
|
||||
<div style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">文件数</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 12px; background: rgba(245, 158, 11, 0.1); border-radius: 10px; border: 1px solid rgba(245,158,11,0.3);">
|
||||
<div style="font-size: 20px; font-weight: 700; color: #f59e0b;">{{ sftpUsage.dirCount }}</div>
|
||||
<div style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">文件夹数</div>
|
||||
<div style="font-size: 20px; font-weight: 700; color: #3b82f6;">{{ ossUsage.fileCount }}</div>
|
||||
<div style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">对象数</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 未统计提示 -->
|
||||
<div v-else style="text-align: center; padding: 16px; color: var(--text-muted); font-size: 13px;">
|
||||
<i class="fas fa-database" style="font-size: 24px; color: var(--text-muted); margin-bottom: 8px; display: block;"></i>
|
||||
点击"刷新"按钮统计 SFTP 空间使用情况
|
||||
点击"刷新"按钮统计 OSS 空间使用情况
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 10px; background: rgba(102, 126, 234, 0.1); border-radius: 10px; color: var(--text-secondary); font-size: 13px;">
|
||||
<i class="fas fa-info-circle" style="color: #4b5fc9;"></i>
|
||||
数据存储在你的 SFTP 服务器上,如需切换回本地请联系管理员调整权限。
|
||||
数据存储在云服务上,安全可靠扩展性强。如需切换回本地请联系管理员调整权限。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2701,7 +2697,7 @@
|
||||
<td style="padding: 10px; font-size: 12px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" :title="u.email">{{ u.email }}</td>
|
||||
<td style="padding: 10px; text-align: center; font-size: 12px;">
|
||||
<span v-if="u.storage_permission === 'local_only'" style="background: #667eea; color: white; padding: 3px 8px; border-radius: 4px;">仅本地</span>
|
||||
<span v-else-if="u.storage_permission === 'sftp_only'" style="background: #6c757d; color: white; padding: 3px 8px; border-radius: 4px;">仅SFTP</span>
|
||||
<span v-else-if="u.storage_permission === 'oss_only'" style="background: #6c757d; color: white; padding: 3px 8px; border-radius: 4px;">仅OSS</span>
|
||||
<span v-else style="background: #22c55e; color: white; padding: 3px 8px; border-radius: 4px;">用户选择</span>
|
||||
</td>
|
||||
<td style="padding: 10px; text-align: center; font-size: 12px;">
|
||||
@@ -2709,7 +2705,7 @@
|
||||
<i class="fas fa-hard-drive"></i> 本地
|
||||
</span>
|
||||
<span v-else style="color: #6c757d;">
|
||||
<i class="fas fa-server"></i> SFTP
|
||||
<i class="fas fa-cloud"></i> OSS
|
||||
</span>
|
||||
</td>
|
||||
<td style="padding: 10px; text-align: center; font-size: 12px;">
|
||||
@@ -2737,7 +2733,7 @@
|
||||
<button v-else class="btn" style="background: #22c55e; color: white; font-size: 11px; padding: 5px 10px;" @click="banUser(u.id, false)">
|
||||
<i class="fas fa-check"></i> 解封
|
||||
</button>
|
||||
<button v-if="u.has_ftp_config" class="btn" style="background: #3b82f6; color: white; font-size: 11px; padding: 5px 10px;" @click="openFileInspection(u)">
|
||||
<button v-if="u.has_oss_config" class="btn" style="background: #3b82f6; color: white; font-size: 11px; padding: 5px 10px;" @click="openFileInspection(u)">
|
||||
<i class="fas fa-folder-open"></i> 文件
|
||||
</button>
|
||||
<button class="btn" style="background: #ef4444; color: white; font-size: 11px; padding: 5px 10px;" @click="deleteUser(u.id)">
|
||||
@@ -3066,11 +3062,11 @@
|
||||
<label class="form-label">存储权限</label>
|
||||
<select class="form-input" v-model="editStorageForm.storage_permission">
|
||||
<option value="local_only">仅本地存储</option>
|
||||
<option value="sftp_only">仅SFTP存储</option>
|
||||
<option value="oss_only">仅OSS存储</option>
|
||||
<option value="user_choice">用户选择</option>
|
||||
</select>
|
||||
<small style="color: var(--text-secondary); font-size: 12px; margin-top: 5px; display: block;">
|
||||
仅本地:用户只能使用本地存储 | 仅SFTP:用户只能使用SFTP | 用户选择:用户可自由切换
|
||||
仅本地:用户只能使用本地存储 | 仅OSS:用户只能使用OSS | 用户选择:用户可自由切换
|
||||
</small>
|
||||
</div>
|
||||
|
||||
@@ -3092,9 +3088,9 @@
|
||||
<div style="font-size: 13px; color: var(--text-secondary); line-height: 1.6;">
|
||||
<strong style="color: var(--text-primary);">配额说明:</strong><br>
|
||||
• 默认配额: 1GB<br>
|
||||
• 当前配额: {{ editStorageForm.local_storage_quota_value }} {{ editStorageForm.quota_unit }}
|
||||
• 当前配额: {{ editStorageForm.local_storage_quota_value }} {{ editStorageForm.quota_unit }}
|
||||
({{ editStorageForm.quota_unit === 'GB' ? (editStorageForm.local_storage_quota_value * 1024).toFixed(0) : editStorageForm.local_storage_quota_value }} MB)<br>
|
||||
• 配额仅影响本地存储,SFTP存储不受此限制
|
||||
• 配额仅影响本地存储,OSS存储不受此限制
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user