feat: remove old password requirement, fix user info display, and add password change reminder on home page

This commit is contained in:
DXC
2026-03-23 11:52:30 +08:00
parent ec5331ffb3
commit 719fe108ba
4 changed files with 52 additions and 51 deletions

View File

@ -255,8 +255,9 @@ def get_my_permissions():
@jwt_required() @jwt_required()
def change_my_password(): def change_my_password():
""" """
新增】自我修改密码接口 改造】自我修改密码接口
- 无需管理员权限,只需验证 JWT Token 和旧密码是否正确 - 无需管理员权限,无需旧密码
- 只要 JWT Token 有效(已证明当前登录身份),即可直接修改新密码
- 字段脱敏:不暴露系统角色 - 字段脱敏:不暴露系统角色
""" """
try: try:
@ -269,12 +270,11 @@ def change_my_password():
if not data: if not data:
return jsonify({'msg': '无效的请求数据'}), 400 return jsonify({'msg': '无效的请求数据'}), 400
old_password = data.get('old_password')
new_password = data.get('new_password') new_password = data.get('new_password')
confirm_password = data.get('confirm_password') confirm_password = data.get('confirm_password')
if not old_password or not new_password or not confirm_password: if not new_password or not confirm_password:
return jsonify({'msg': '旧密码、新密码确认新密码均不能为空'}), 400 return jsonify({'msg': '新密码确认新密码均不能为空'}), 400
if new_password != confirm_password: if new_password != confirm_password:
return jsonify({'msg': '新密码与确认密码不一致'}), 400 return jsonify({'msg': '新密码与确认密码不一致'}), 400
@ -282,22 +282,15 @@ def change_my_password():
if len(new_password) < 6: if len(new_password) < 6:
return jsonify({'msg': '新密码长度不能少于6位'}), 400 return jsonify({'msg': '新密码长度不能少于6位'}), 400
# 超级管理员user_id=0使用硬编码密码 # 超级管理员user_id=0使用硬编码密码,不存入数据库
if user_id == 0: if user_id == 0:
if old_password != AuthService.SUPER_ADMIN_PASS: return jsonify({'msg': '超级管理员密码由系统管理员管理,当前会话无法修改'}), 200
return jsonify({'msg': '旧密码错误'}), 401
# 超级管理员密码不存入数据库直接返回成功IRIS 使用固定密码)
# 注:如果需要支持 IRIS 修改密码,可在此添加特殊逻辑
return jsonify({'msg': '超级管理员密码由系统管理员管理,当前会话无需修改'}), 200
# 普通用户:从数据库验证旧密码 # 普通用户:JWT 已证明身份,直接更新新密码
user = SysUser.query.get(user_id) user = SysUser.query.get(user_id)
if not user: if not user:
return jsonify({'msg': '用户不存在'}), 404 return jsonify({'msg': '用户不存在'}), 404
if not user.check_password(old_password):
return jsonify({'msg': '旧密码错误'}), 401
user.set_password(new_password) user.set_password(new_password)
db.session.commit() db.session.commit()

View File

@ -44,7 +44,6 @@ const profileForm = ref<ProfileData>({
}) })
const passwordForm = ref({ const passwordForm = ref({
old_password: '',
new_password: '', new_password: '',
confirm_password: '' confirm_password: ''
}) })
@ -55,13 +54,19 @@ const passwordFormRef = ref()
const openProfileDialog = async () => { const openProfileDialog = async () => {
profileDialogVisible.value = true profileDialogVisible.value = true
profileLoading.value = true profileLoading.value = true
passwordForm.value = { old_password: '', new_password: '', confirm_password: '' } passwordForm.value = { new_password: '', confirm_password: '' }
try { try {
// 【修复】axios 拦截器已解包 response.data
// res 本身已是 { msg, data: { id, username, display_name, department } }
// 故直接取 res.data 即可,多跳一层 res.data.data 会取到 undefined
const res: any = await getMyProfile() const res: any = await getMyProfile()
const data = res.data || res const payload = res.data || res
if (data && data.data) { if (payload && payload.data) {
profileForm.value = data.data profileForm.value = payload.data
} else if (payload && payload.username) {
// 兜底:响应已经是平铺结构
profileForm.value = payload
} }
} catch (e: any) { } catch (e: any) {
ElMessage.error(e?.message || '获取个人资料失败') ElMessage.error(e?.message || '获取个人资料失败')
@ -70,12 +75,12 @@ const openProfileDialog = async () => {
} }
} }
// 提交修改密码 // 提交修改密码无需旧密码JWT 已证明身份)
const submitPasswordChange = async () => { const submitPasswordChange = async () => {
const { old_password, new_password, confirm_password } = passwordForm.value const { new_password, confirm_password } = passwordForm.value
if (!old_password || !new_password || !confirm_password) { if (!new_password || !confirm_password) {
ElMessage.warning('请填写所有密码字段') ElMessage.warning('请填写新密码和确认密码')
return return
} }
@ -92,24 +97,16 @@ const submitPasswordChange = async () => {
passwordLoading.value = true passwordLoading.value = true
try { try {
const res: any = await changeMyPassword({ const res: any = await changeMyPassword({
old_password,
new_password, new_password,
confirm_password confirm_password
}) })
const msg = res?.data?.msg || res?.msg || '修改成功' const msg = res?.msg || '修改成功'
ElMessage.success(msg) ElMessage.success(msg)
profileDialogVisible.value = false
// 如果是普通用户修改成功,提示重新登录 setTimeout(() => {
if (msg.includes('重新登录')) { userStore.logout()
profileDialogVisible.value = false router.replace('/login')
setTimeout(() => { }, 1500)
userStore.logout()
router.replace('/login')
}, 1500)
} else {
// 超级管理员等特殊提示,直接清空表单
passwordForm.value = { old_password: '', new_password: '', confirm_password: '' }
}
} catch (e: any) { } catch (e: any) {
const errMsg = e?.response?.data?.msg || e?.message || '修改失败' const errMsg = e?.response?.data?.msg || e?.message || '修改失败'
ElMessage.error(errMsg) ElMessage.error(errMsg)
@ -217,23 +214,13 @@ const handleLogout = () => {
<el-icon><Lock /></el-icon> 修改密码 <el-icon><Lock /></el-icon> 修改密码
</el-divider> </el-divider>
<!-- 修改密码表单 --> <!-- 修改密码表单无需旧密码JWT 已验证身份 -->
<el-form <el-form
ref="passwordFormRef" ref="passwordFormRef"
:model="passwordForm" :model="passwordForm"
label-width="110px" label-width="110px"
class="password-form" class="password-form"
> >
<el-form-item label="旧密码" prop="old_password">
<el-input
v-model="passwordForm.old_password"
type="password"
placeholder="请输入当前密码"
show-password
clearable
/>
</el-form-item>
<el-form-item label="新密码" prop="new_password"> <el-form-item label="新密码" prop="new_password">
<el-input <el-input
v-model="passwordForm.new_password" v-model="passwordForm.new_password"

View File

@ -59,8 +59,8 @@ export function getMyProfile() {
}) })
} }
// 【新增】自我修改密码(验证旧密码,无需管理员权限 // 【新增】自我修改密码(无需旧密码,JWT 已证明身份
export function changeMyPassword(data: { old_password: string; new_password: string; confirm_password: string }) { export function changeMyPassword(data: { new_password: string; confirm_password: string }) {
return request({ return request({
url: '/v1/auth/me/password', url: '/v1/auth/me/password',
method: 'put', method: 'put',

View File

@ -36,6 +36,11 @@
借库申请 借库申请
</el-button> </el-button>
</div> </div>
<!-- 修改密码温馨提示 -->
<div class="password-tip">
💡 提示为了您的账号安全请点击右上角<strong>个人头像</strong>修改默认登录密码
</div>
</div> </div>
</el-card> </el-card>
@ -415,6 +420,22 @@ const handleNav = (path: string) => {
flex-wrap: wrap; /* 防止屏幕过窄时按钮挤压 */ flex-wrap: wrap; /* 防止屏幕过窄时按钮挤压 */
} }
/* 修改密码温馨提示 */
.password-tip {
text-align: center;
font-size: 13px;
color: #909399;
margin-top: 20px;
padding: 10px 16px;
background-color: #f4f4f5;
border-radius: 6px;
line-height: 1.6;
}
.password-tip strong {
color: #409eff;
}
/* 给按钮加一点悬浮效果 */ /* 给按钮加一点悬浮效果 */
.el-button { .el-button {
transition: all 0.3s; transition: all 0.3s;