🔥 移除旧密码重置审核系统 & ✨ 优化存储管理UI
后端改进: - 移除需要管理员审核的密码重置请求功能 - 简化密码重置流程,直接使用邮件重置 - 删除 password_reset_requests 表及相关代码 前端优化: - 重新设计存储管理界面,采用现代化渐变风格 - 改进存储方式切换交互,添加动画效果 - 优化视觉层次和信息展示 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1111,45 +1111,120 @@
|
||||
<i class="fas fa-database"></i> 存储管理
|
||||
</h3>
|
||||
|
||||
<div style="background: #f8f9fa; padding: 20px; border-radius: 8px;">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<span style="font-weight: 600; color: #333;">当前存储方式: </span>
|
||||
<span style="color: #667eea; font-weight: 600;">{{ storageTypeText }}</span>
|
||||
<div style="background: linear-gradient(135deg, #f3f5ff 0%, #eef7ff 100%); padding: 22px; border-radius: 14px; box-shadow: 0 10px 30px rgba(102,126,234,0.12); border: 1px solid #e3e9ff;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span style="font-weight: 700; color: #334155;">当前模式</span>
|
||||
<span :style="{
|
||||
padding: '6px 12px',
|
||||
borderRadius: '999px',
|
||||
background: storageType === 'local' ? 'rgba(40,167,69,0.12)' : 'rgba(102,126,234,0.12)',
|
||||
color: storageType === 'local' ? '#1c7c3d' : '#4b5fc9',
|
||||
fontWeight: 700,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '6px'
|
||||
}">
|
||||
<i :class="storageType === 'local' ? 'fas fa-hard-drive' : 'fas fa-server'"></i>
|
||||
{{ storageTypeText }}
|
||||
</span>
|
||||
</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 存储' : '本地存储' }}...
|
||||
</div>
|
||||
<div v-else style="color: #666; font-size: 13px;">本地存储适合快速读写,SFTP 适合独立服务器空间</div>
|
||||
</div>
|
||||
|
||||
<div v-if="storageType === 'local'" style="margin-bottom: 15px;">
|
||||
<span style="font-weight: 600; color: #333;">配额使用: </span>
|
||||
<span>{{ localUsedFormatted }} / {{ localQuotaFormatted }} ({{ quotaPercentage }}%)</span>
|
||||
<div style="margin-top: 8px; width: 100%; height: 18px; background: #e0e0e0; border-radius: 9px; overflow: hidden;">
|
||||
<div :style="{
|
||||
width: quotaPercentage + '%',
|
||||
height: '100%',
|
||||
background: quotaPercentage > 90 ? '#dc3545' : quotaPercentage > 75 ? '#ffc107' : '#28a745',
|
||||
transition: 'width 0.3s'
|
||||
}"></div>
|
||||
<div style="margin-top: 16px; background: white; border-radius: 12px; padding: 12px; border: 1px solid #e2e8f0;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; align-items: center;">
|
||||
<button
|
||||
class="btn"
|
||||
:class="storageType === 'local' ? 'btn-primary' : 'btn-secondary'"
|
||||
style="width: 100%; border-radius: 10px; padding: 12px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: all .3s;"
|
||||
:disabled="storageType === 'local' || storageSwitching"
|
||||
@click="switchStorage('local')">
|
||||
<i class="fas fa-hard-drive"></i>
|
||||
切换到本地
|
||||
</button>
|
||||
<div style="height: 4px; background: #e2e8f0; border-radius: 999px; position: relative; overflow: hidden;">
|
||||
<div :style="{
|
||||
position: 'absolute',
|
||||
left: storageType === 'local' ? '6%' : '52%',
|
||||
width: '42%',
|
||||
height: '100%',
|
||||
background: 'linear-gradient(90deg,#667eea,#764ba2)',
|
||||
borderRadius: '999px',
|
||||
transition: 'left .35s ease'
|
||||
}"></div>
|
||||
</div>
|
||||
<button
|
||||
class="btn"
|
||||
:class="storageType === 'sftp' ? 'btn-primary' : 'btn-secondary'"
|
||||
style="width: 100%; border-radius: 10px; padding: 12px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: all .3s;"
|
||||
:disabled="storageType === 'sftp' || storageSwitching"
|
||||
@click="switchStorage('sftp')">
|
||||
<i class="fas fa-server"></i>
|
||||
切换到 SFTP
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 15px; flex-wrap: wrap;">
|
||||
<button
|
||||
class="btn"
|
||||
:class="storageType === 'local' ? 'btn-primary' : 'btn-secondary'"
|
||||
@click="switchStorage('local')"
|
||||
:disabled="storageType === 'local'">
|
||||
<i class="fas fa-hard-drive"></i> 本地存储
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
:class="storageType === 'sftp' ? 'btn-primary' : 'btn-secondary'"
|
||||
@click="switchStorage('sftp')"
|
||||
:disabled="storageType === 'sftp'">
|
||||
<i class="fas fa-server"></i> SFTP存储
|
||||
</button>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin-top: 14px;">
|
||||
<div style="background: white; border: 1px solid #e2e8f0; border-radius: 12px; padding: 16px; box-shadow: 0 6px 20px rgba(0,0,0,0.04);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: 700; color: #0f172a; display: flex; gap: 8px; align-items: center;">
|
||||
<i class="fas fa-hard-drive"></i> 本地存储
|
||||
</div>
|
||||
<span v-if="storageType === 'local'" style="font-size: 12px; color: #28a745; background: rgba(40,167,69,0.12); padding: 4px 8px; border-radius: 999px;">当前</span>
|
||||
</div>
|
||||
<div style="color: #475569; font-size: 13px; margin-bottom: 10px;">更快的读写,适合日常上传下载。</div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<div style="font-size: 12px; color: #64748b; margin-bottom: 6px;">配额使用</div>
|
||||
<div style="font-weight: 600; color: #0f172a;">{{ localUsedFormatted }} / {{ localQuotaFormatted }}</div>
|
||||
<div style="margin-top: 6px; width: 100%; height: 10px; background: #e2e8f0; border-radius: 5px; overflow: hidden;">
|
||||
<div :style="{
|
||||
width: quotaPercentage + '%',
|
||||
height: '100%',
|
||||
background: quotaPercentage > 90 ? '#dc3545' : quotaPercentage > 75 ? '#ffc107' : '#28a745',
|
||||
transition: 'width 0.35s ease'
|
||||
}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" style="width: 100%; border-radius: 10px;" :disabled="storageType === 'local' || storageSwitching" @click="switchStorage('local')">
|
||||
<i class="fas fa-bolt"></i> 用本地存储
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style="background: white; border: 1px solid #e2e8f0; border-radius: 12px; padding: 16px; box-shadow: 0 6px 20px rgba(0,0,0,0.04);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: 700; color: #0f172a; display: flex; gap: 8px; align-items: center;">
|
||||
<i class="fas fa-server"></i> SFTP 存储
|
||||
</div>
|
||||
<span v-if="storageType === 'sftp'" style="font-size: 12px; color: #4b5fc9; background: rgba(102,126,234,0.15); padding: 4px 8px; border-radius: 999px;">当前</span>
|
||||
</div>
|
||||
<div style="color: #475569; font-size: 13px; margin-bottom: 10px;">使用你自己的服务器空间,独立存储更灵活。</div>
|
||||
<div v-if="user?.has_ftp_config" style="font-size: 13px; color: #0f172a; margin-bottom: 10px;">
|
||||
已配置: {{ user.ftp_host }}:{{ user.ftp_port }}
|
||||
</div>
|
||||
<div v-else style="font-size: 13px; color: #b45309; background: #fff7ed; border: 1px dashed #fcd34d; padding: 10px; border-radius: 8px; margin-bottom: 10px;">
|
||||
<i class="fas fa-exclamation-circle"></i> 先填写 SFTP 连接信息再切换
|
||||
</div>
|
||||
<button
|
||||
class="btn"
|
||||
:class="user?.has_ftp_config ? 'btn-primary' : 'btn-secondary'"
|
||||
style="width: 100%; border-radius: 10px;"
|
||||
:disabled="storageType === 'sftp' || storageSwitching"
|
||||
@click="switchStorage('sftp')">
|
||||
<i class="fas fa-random"></i>
|
||||
{{ user?.has_ftp_config ? '切到 SFTP 存储' : '去配置 SFTP' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 15px; padding: 10px; background: #fff3cd; border-radius: 6px; font-size: 13px; color: #856404;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>提示:</strong> 本地存储速度快但有配额限制;SFTP存储需先配置服务器信息
|
||||
<div style="margin-top: 12px; padding: 10px 12px; background: #f1f5f9; border-radius: 10px; font-size: 13px; color: #475569;">
|
||||
<i class="fas fa-info-circle" style="color: #4b5fc9;"></i>
|
||||
本地存储速度快但受配额限制;SFTP 需先配置连接,切换过程中可继续查看文件列表。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1641,39 +1716,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密码重置审核区域 -->
|
||||
<div class="card" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 20px;">密码重置审核</h3>
|
||||
<div v-if="passwordResetRequests.length === 0" class="alert alert-info">
|
||||
暂无待审核的密码重置请求
|
||||
</div>
|
||||
<table v-else style="width: 100%; border-collapse: collapse; table-layout: fixed;">
|
||||
<thead>
|
||||
<tr style="border-bottom: 2px solid #ddd;">
|
||||
<th style="padding: 10px; text-align: left;">用户名</th>
|
||||
<th style="padding: 10px; text-align: left;">邮箱</th>
|
||||
<th style="padding: 10px; text-align: left;">提交时间</th>
|
||||
<th style="padding: 10px; text-align: center;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="req in passwordResetRequests" :key="req.id" style="border-bottom: 1px solid #eee;">
|
||||
<td style="padding: 10px;">{{ req.username }}</td>
|
||||
<td style="padding: 10px;">{{ req.email }}</td>
|
||||
<td style="padding: 10px;">{{ formatDate(req.created_at) }}</td>
|
||||
<td style="padding: 10px; text-align: center;">
|
||||
<button class="btn" style="background: #28a745; color: white; margin: 2px;" @click="reviewPasswordReset(req.id, true)">
|
||||
<i class="fas fa-check"></i> 批准
|
||||
</button>
|
||||
<button class="btn" style="background: #dc3545; color: white; margin: 2px;" @click="reviewPasswordReset(req.id, false)">
|
||||
<i class="fas fa-times"></i> 拒绝
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 上传工具管理区域 -->
|
||||
<div class="card" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 20px;">
|
||||
|
||||
Reference in New Issue
Block a user