feat: remove old password requirement, fix user info display, and add password change reminder on home page
This commit is contained in:
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
// 如果是普通用户修改成功,提示重新登录
|
|
||||||
if (msg.includes('重新登录')) {
|
|
||||||
profileDialogVisible.value = false
|
profileDialogVisible.value = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
userStore.logout()
|
userStore.logout()
|
||||||
router.replace('/login')
|
router.replace('/login')
|
||||||
}, 1500)
|
}, 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"
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user