feat: 删除SFTP上传工具,修复OSS配置bug
主要变更: - 删除管理员工具栏及上传工具相关功能(后端API + 前端UI) - 删除upload-tool目录及相关文件 - 修复OSS配置测试连接bug(testUser缺少has_oss_config标志) - 新增backend/utils加密和缓存工具模块 - 更新.gitignore排除测试报告文件 技术改进: - 统一使用OSS存储,废弃SFTP上传方式 - 修复OSS配置保存和测试连接时的错误处理 - 完善代码库文件管理,排除临时报告文件
This commit is contained in:
@@ -1315,18 +1315,13 @@
|
||||
<!-- 工具栏 -->
|
||||
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<!-- 本地存储:显示网页上传按钮 -->
|
||||
<button v-if="storageType === 'local'" class="btn btn-primary" @click="$refs.fileUploadInput.click()">
|
||||
<!-- 网页上传按钮(支持本地和OSS存储) -->
|
||||
<button class="btn btn-primary" @click="$refs.fileUploadInput.click()">
|
||||
<i class="fas fa-upload"></i> 上传文件
|
||||
</button>
|
||||
<button v-if="storageType === 'local'" class="btn btn-primary" @click="showCreateFolderModal = true">
|
||||
<button class="btn btn-primary" @click="showCreateFolderModal = true">
|
||||
<i class="fas fa-folder-plus"></i> 新建文件夹
|
||||
</button>
|
||||
<!-- 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 ? '生成中...' : '下载上传工具' }}
|
||||
</button>
|
||||
<button class="btn btn-primary" @click="showShareAllModal = true">
|
||||
<i class="fas fa-share-nodes"></i> 分享所有文件
|
||||
</button>
|
||||
@@ -2192,10 +2187,6 @@
|
||||
:style="{ padding: '15px 25px', border: 'none', background: adminTab === 'users' ? '#667eea' : 'transparent', color: adminTab === 'users' ? 'white' : '#666', cursor: 'pointer', fontWeight: '600', fontSize: '14px', borderRadius: adminTab === 'users' ? '8px 8px 0 0' : '0', transition: 'all 0.2s' }">
|
||||
<i class="fas fa-users"></i> 用户
|
||||
</button>
|
||||
<button @click="adminTab = 'tools'"
|
||||
:style="{ padding: '15px 25px', border: 'none', background: adminTab === 'tools' ? '#667eea' : 'transparent', color: adminTab === 'tools' ? 'white' : '#666', cursor: 'pointer', fontWeight: '600', fontSize: '14px', borderRadius: adminTab === 'tools' ? '8px 8px 0 0' : '0', transition: 'all 0.2s' }">
|
||||
<i class="fas fa-tools"></i> 工具
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2842,76 +2833,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- 用户标签页结束 -->
|
||||
|
||||
<!-- ========== 工具标签页 ========== -->
|
||||
<div v-show="adminTab === 'tools'">
|
||||
<!-- 上传工具管理区域 -->
|
||||
<div class="card">
|
||||
<h3 style="margin-bottom: 20px;">
|
||||
<i class="fas fa-cloud-upload-alt"></i> 上传工具管理
|
||||
</h3>
|
||||
|
||||
<!-- 工具状态显示 -->
|
||||
<div v-if="uploadToolStatus !== null">
|
||||
<div v-if="uploadToolStatus.exists" style="padding: 15px; background: rgba(34, 197, 94, 0.15); border-left: 4px solid #22c55e; border-radius: 6px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between;">
|
||||
<div>
|
||||
<div style="color: #86efac; font-weight: 600; margin-bottom: 5px;">
|
||||
<i class="fas fa-check-circle"></i> 上传工具已存在
|
||||
</div>
|
||||
<div style="color: #86efac; font-size: 13px;">
|
||||
文件大小: {{ uploadToolStatus.fileInfo.sizeMB }} MB
|
||||
</div>
|
||||
<div style="color: #86efac; font-size: 12px; margin-top: 3px;">
|
||||
最后修改: {{ formatDate(uploadToolStatus.fileInfo.modifiedAt) }}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" @click="checkUploadTool" style="background: #22c55e;">
|
||||
<i class="fas fa-sync-alt"></i> 重新检测
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else style="padding: 15px; background: rgba(245, 158, 11, 0.15); border-left: 4px solid #f59e0b; border-radius: 6px; margin-bottom: 20px;">
|
||||
<div style="color: #fbbf24; font-weight: 600; margin-bottom: 5px;">
|
||||
<i class="fas fa-exclamation-triangle"></i> 上传工具不存在
|
||||
</div>
|
||||
<div style="color: #fbbf24; font-size: 13px;">
|
||||
普通用户将无法下载上传工具,请上传工具文件
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮组 -->
|
||||
<div style="display: flex; gap: 10px; margin-top: 15px; flex-wrap: wrap;">
|
||||
<button class="btn btn-primary" @click="checkUploadTool" :disabled="checkingUploadTool" style="background: #3b82f6;">
|
||||
<i class="fas fa-search" v-if="!checkingUploadTool"></i>
|
||||
<i class="fas fa-spinner fa-spin" v-else></i>
|
||||
{{ checkingUploadTool ? '检测中...' : '检测上传工具' }}
|
||||
</button>
|
||||
|
||||
<button v-if="uploadToolStatus && !uploadToolStatus.exists" class="btn btn-primary" @click="$refs.uploadToolInput.click()" :disabled="uploadingTool" style="background: #22c55e;">
|
||||
<i class="fas fa-upload" v-if="!uploadingTool"></i>
|
||||
<i class="fas fa-spinner fa-spin" v-else></i>
|
||||
{{ uploadingTool ? '上传中...' : '上传工具文件' }}
|
||||
</button>
|
||||
|
||||
<input ref="uploadToolInput" type="file" accept=".exe" style="display: none;" @change="handleUploadToolFile">
|
||||
</div>
|
||||
|
||||
<!-- 使用说明 -->
|
||||
<div style="margin-top: 20px; padding: 12px; background: rgba(59, 130, 246, 0.1); border-left: 4px solid #3b82f6; border-radius: 6px;">
|
||||
<div style="color: #93c5fd; font-size: 13px; line-height: 1.6;">
|
||||
<strong><i class="fas fa-info-circle"></i> 说明:</strong>
|
||||
<ul style="margin: 8px 0 0 20px; padding-left: 0;">
|
||||
<li>上传工具文件应为 .exe 格式,大小通常在 20-50 MB</li>
|
||||
<li>上传后,普通用户可以在设置页面下载该工具</li>
|
||||
<li>如果安装脚本下载失败,可以在这里手动上传</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- 工具标签页结束 -->
|
||||
</div><!-- 管理员视图结束 -->
|
||||
|
||||
<!-- 忘记密码模态框 -->
|
||||
|
||||
120
frontend/app.js
120
frontend/app.js
@@ -5,7 +5,7 @@ createApp({
|
||||
// 预先确定管理员标签页,避免刷新时状态丢失导致闪烁
|
||||
const initialAdminTab = (() => {
|
||||
const saved = localStorage.getItem('adminTab');
|
||||
return (saved && ['overview', 'settings', 'monitor', 'users', 'tools'].includes(saved)) ? saved : 'overview';
|
||||
return (saved && ['overview', 'settings', 'monitor', 'users'].includes(saved)) ? saved : 'overview';
|
||||
})();
|
||||
|
||||
return {
|
||||
@@ -28,7 +28,7 @@ createApp({
|
||||
fileViewMode: 'grid', // 文件显示模式: grid 大图标, list 列表
|
||||
shareViewMode: 'list', // 分享显示模式: grid 大图标, list 列表
|
||||
debugMode: false, // 调试模式(管理员可切换)
|
||||
adminTab: initialAdminTab, // 管理员页面当前标签:overview, settings, monitor, users, tools
|
||||
adminTab: initialAdminTab, // 管理员页面当前标签:overview, settings, monitor, users
|
||||
|
||||
// 表单数据
|
||||
loginForm: {
|
||||
@@ -142,9 +142,6 @@ createApp({
|
||||
isDragging: false,
|
||||
modalMouseDownTarget: null, // 模态框鼠标按下的目标
|
||||
|
||||
// 上传工具下载
|
||||
downloadingTool: false,
|
||||
|
||||
// 管理员
|
||||
adminUsers: [],
|
||||
showResetPwdModal: false,
|
||||
@@ -287,11 +284,6 @@ createApp({
|
||||
// 定期检查用户配置更新的定时器
|
||||
profileCheckInterval: null,
|
||||
|
||||
// 上传工具管理
|
||||
uploadToolStatus: null, // 上传工具状态 { exists, fileInfo: { size, sizeMB, modifiedAt } }
|
||||
checkingUploadTool: false, // 是否正在检测上传工具
|
||||
uploadingTool: false, // 是否正在上传工具
|
||||
|
||||
// 存储切换状态
|
||||
storageSwitching: false,
|
||||
storageSwitchTarget: null,
|
||||
@@ -1768,31 +1760,6 @@ handleDragLeave(e) {
|
||||
}
|
||||
},
|
||||
|
||||
downloadUploadTool() {
|
||||
try {
|
||||
this.downloadingTool = true;
|
||||
this.showToast('info', '提示', '正在生成上传工具,下载即将开始...');
|
||||
|
||||
// 使用<a>标签下载,通过URL参数传递token,浏览器会显示下载进度
|
||||
const link = document.createElement('a');
|
||||
link.href = `${this.apiBase}/api/upload/download-tool`;
|
||||
link.setAttribute('download', `玩玩云上传工具_${this.user.username}.zip`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// 延迟重置按钮状态,给下载一些启动时间
|
||||
setTimeout(() => {
|
||||
this.downloadingTool = false;
|
||||
this.showToast('success', '提示', '下载已开始,请查看浏览器下载进度');
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
console.error('下载上传工具失败:', error);
|
||||
this.showToast('error', '错误', '下载失败');
|
||||
this.downloadingTool = false;
|
||||
}
|
||||
},
|
||||
|
||||
// ===== 分享功能 =====
|
||||
|
||||
openShareFileModal(file) {
|
||||
@@ -3072,89 +3039,6 @@ handleDragLeave(e) {
|
||||
}
|
||||
},
|
||||
|
||||
// ===== 上传工具管理 =====
|
||||
|
||||
// 检测上传工具是否存在
|
||||
async checkUploadTool() {
|
||||
this.checkingUploadTool = true;
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${this.apiBase}/api/admin/check-upload-tool`,
|
||||
);
|
||||
|
||||
if (response.data.success) {
|
||||
this.uploadToolStatus = response.data;
|
||||
if (response.data.exists) {
|
||||
this.showToast('success', '检测完成', '上传工具文件存在');
|
||||
} else {
|
||||
this.showToast('warning', '提示', '上传工具文件不存在,请上传');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('检测上传工具失败:', error);
|
||||
this.showToast('error', '错误', '检测失败: ' + (error.response?.data?.message || error.message));
|
||||
} finally {
|
||||
this.checkingUploadTool = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理上传工具文件
|
||||
async handleUploadToolFile(event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
// 验证文件类型
|
||||
if (!file.name.toLowerCase().endsWith('.exe')) {
|
||||
this.showToast('error', '错误', '只能上传 .exe 文件');
|
||||
event.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证文件大小(至少20MB)
|
||||
const minSizeMB = 20;
|
||||
const fileSizeMB = file.size / (1024 * 1024);
|
||||
if (fileSizeMB < minSizeMB) {
|
||||
this.showToast('error', '错误', `文件大小过小(${fileSizeMB.toFixed(2)}MB),上传工具通常大于${minSizeMB}MB`);
|
||||
event.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 确认上传
|
||||
if (!confirm(`确定要上传 ${file.name} (${fileSizeMB.toFixed(2)}MB) 吗?`)) {
|
||||
event.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploadingTool = true;
|
||||
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
const response = await axios.post(
|
||||
`${this.apiBase}/api/admin/upload-tool`,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data.success) {
|
||||
this.showToast('success', '成功', '上传工具已上传');
|
||||
// 重新检测
|
||||
await this.checkUploadTool();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传工具失败:', error);
|
||||
this.showToast('error', '错误', error.response?.data?.message || '上传失败');
|
||||
} finally {
|
||||
this.uploadingTool = false;
|
||||
event.target.value = ''; // 清空input,允许重复上传
|
||||
}
|
||||
},
|
||||
|
||||
// ===== 调试模式管理 =====
|
||||
|
||||
// 切换调试模式
|
||||
|
||||
Reference in New Issue
Block a user