✨ 添加用户修改密码功能
- 左边栏添加修改密码按钮 - 添加修改密码弹窗 - 添加 /api/user/password API 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
26
app.py
26
app.py
@@ -2247,6 +2247,32 @@ def get_current_user_vip():
|
|||||||
return jsonify(vip_info)
|
return jsonify(vip_info)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/user/password', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def change_user_password():
|
||||||
|
"""用户修改自己的密码"""
|
||||||
|
data = request.get_json()
|
||||||
|
current_password = data.get('current_password')
|
||||||
|
new_password = data.get('new_password')
|
||||||
|
|
||||||
|
if not current_password or not new_password:
|
||||||
|
return jsonify({"error": "请填写完整信息"}), 400
|
||||||
|
|
||||||
|
if len(new_password) < 6:
|
||||||
|
return jsonify({"error": "新密码至少6位"}), 400
|
||||||
|
|
||||||
|
# 验证当前密码
|
||||||
|
user = database.get_user_by_id(current_user.id)
|
||||||
|
if not user or not check_password_hash(user['password_hash'], current_password):
|
||||||
|
return jsonify({"error": "当前密码错误"}), 400
|
||||||
|
|
||||||
|
# 更新密码(使用管理员重置密码的函数,因为已经验证过当前密码了)
|
||||||
|
if database.admin_reset_user_password(current_user.id, new_password):
|
||||||
|
return jsonify({"success": True})
|
||||||
|
else:
|
||||||
|
return jsonify({"error": "密码更新失败"}), 500
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/run_stats', methods=['GET'])
|
@app.route('/api/run_stats', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def get_run_stats():
|
def get_run_stats():
|
||||||
|
|||||||
@@ -285,6 +285,7 @@
|
|||||||
<div class="nav-item active" data-tab="accounts"><span class="nav-icon">👤</span><span class="nav-label">账号管理</span></div>
|
<div class="nav-item active" data-tab="accounts"><span class="nav-icon">👤</span><span class="nav-label">账号管理</span></div>
|
||||||
<div class="nav-item" data-tab="schedule"><span class="nav-icon">⏰</span><span class="nav-label">定时任务</span></div>
|
<div class="nav-item" data-tab="schedule"><span class="nav-icon">⏰</span><span class="nav-label">定时任务</span></div>
|
||||||
<div class="nav-item" data-tab="screenshots"><span class="nav-icon">📸</span><span class="nav-label">截图管理</span></div>
|
<div class="nav-item" data-tab="screenshots"><span class="nav-icon">📸</span><span class="nav-label">截图管理</span></div>
|
||||||
|
<div class="nav-item" onclick="openModal('changePasswordModal')" style="margin-top: auto;"><span class="nav-icon">⚙️</span><span class="nav-label">修改密码</span></div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
@@ -499,6 +500,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 修改密码弹窗 -->
|
||||||
|
<div class="modal-overlay" id="changePasswordModal">
|
||||||
|
<div class="modal" style="max-width: 400px;">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">修改密码</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">当前密码</label>
|
||||||
|
<input type="password" class="form-input" id="currentPassword" placeholder="请输入当前密码">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">新密码</label>
|
||||||
|
<input type="password" class="form-input" id="newPassword" placeholder="请输入新密码(至少6位)">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">确认新密码</label>
|
||||||
|
<input type="password" class="form-input" id="confirmPassword" placeholder="请再次输入新密码">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-text" onclick="closeModal('changePasswordModal')">取消</button>
|
||||||
|
<button class="btn btn-primary" onclick="changePassword()">确认修改</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 反馈弹窗 -->
|
<!-- 反馈弹窗 -->
|
||||||
<div class="modal-overlay" id="feedbackModal">
|
<div class="modal-overlay" id="feedbackModal">
|
||||||
<div class="modal" style="max-width: 560px;">
|
<div class="modal" style="max-width: 560px;">
|
||||||
@@ -1750,7 +1778,34 @@
|
|||||||
.catch(() => { window.location.href = '/login'; });
|
.catch(() => { window.location.href = '/login'; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changePassword() {
|
||||||
|
const currentPwd = document.getElementById('currentPassword').value;
|
||||||
|
const newPwd = document.getElementById('newPassword').value;
|
||||||
|
const confirmPwd = document.getElementById('confirmPassword').value;
|
||||||
|
|
||||||
|
if (!currentPwd) { showToast('请输入当前密码', 'error'); return; }
|
||||||
|
if (!newPwd || newPwd.length < 6) { showToast('新密码至少6位', 'error'); return; }
|
||||||
|
if (newPwd !== confirmPwd) { showToast('两次密码不一致', 'error'); return; }
|
||||||
|
|
||||||
|
fetch('/api/user/password', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ current_password: currentPwd, new_password: newPwd })
|
||||||
|
})
|
||||||
|
.then(r => r.json().then(data => ({ ok: r.ok, data })))
|
||||||
|
.then(({ ok, data }) => {
|
||||||
|
if (ok) {
|
||||||
|
showToast('密码修改成功', 'success');
|
||||||
|
closeModal('changePasswordModal');
|
||||||
|
document.getElementById('currentPassword').value = '';
|
||||||
|
document.getElementById('newPassword').value = '';
|
||||||
|
document.getElementById('confirmPassword').value = '';
|
||||||
|
} else {
|
||||||
|
showToast(data.error || '修改失败', 'error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => showToast('网络错误', 'error'));
|
||||||
|
}
|
||||||
|
|
||||||
// 点击overlay关闭弹窗
|
// 点击overlay关闭弹窗
|
||||||
document.querySelectorAll('.modal-overlay').forEach(function(overlay) {
|
document.querySelectorAll('.modal-overlay').forEach(function(overlay) {
|
||||||
|
|||||||
Reference in New Issue
Block a user