fix: 修复多处错误并优化用户体验

修复 ACCESS_TOKEN_INVALID 状态码从 403 改为 401
修复密码表单字段命名不一致问题
优化删除操作取消时的提示关闭逻辑
修复用户信息更新后未同步到 store 的问题
添加修改密码后的自动跳转登录功能
修复非 GET 请求成功时缺少成功提示的问题
This commit is contained in:
zhangtao
2025-07-27 00:26:09 +08:00
parent e7ebbf5479
commit 23d1e7adce
18 changed files with 389 additions and 727 deletions
+4 -4
View File
@@ -19,7 +19,7 @@ export const UserAPI = {
},
updateCurrentUserInfo(body: InfoFormState) {
return request<ApiResponse>({
return request<ApiResponse<UserInfo>>({
url: `/system/user/current/info/update`,
method: "put",
data: body,
@@ -229,9 +229,9 @@ export interface InfoFormState {
}
export interface PasswordFormState {
oldPassword: string;
newPassword: string;
confirmPassword: string;
old_password: string;
new_password: string;
confirm_password: string;
}
export interface ResetPasswordForm {
+1 -1
View File
@@ -18,6 +18,6 @@ export const enum ResultEnum {
/**
* 访问令牌无效或过期
*/
ACCESS_TOKEN_INVALID = 403,
ACCESS_TOKEN_INVALID = 401,
}
+5
View File
@@ -32,6 +32,11 @@ export const useUserStore = defineStore("user", {
this.basicInfo = { ...this.basicInfo, ...response.data.data };
},
// 设置用户信息
setUserInfo(info: UserInfo) {
this.basicInfo = info;
},
setRoute(routers: any) {
this.routeList = routers;
this.hasGetRoute = true;
+9 -3
View File
@@ -47,11 +47,17 @@ httpRequest.interceptors.response.use((response: AxiosResponse<ApiResponse>) =>
const data = response.data;
// 请求成功
if (data.code != ResultEnum.SUCCESS) {
// 检查请求是否失败
if (data.code !== ResultEnum.SUCCESS) {
ElMessage.error(data.msg);
return Promise.reject(response);
}
}
// 如果请求不是 GET 请求,请求成功时显示成功提示
if (response.config.method?.toUpperCase() !== 'GET') {
ElMessage.success(data.msg);
}
return response;
}, async (error: AxiosError<ApiResponse>) => {
const data = error.response?.data;
+55 -18
View File
@@ -124,15 +124,15 @@
<el-form ref="ruleFormRef" :model="infoFormState" :rules="rules" :inline="true" label-suffix=":">
<el-form-item label="姓名" name="name">
<el-input v-model:value="infoFormState.name" placeholder="请输入姓名" prefix-icon="User" clearable />
<el-input v-model="infoFormState.name" placeholder="请输入姓名" prefix-icon="User" clearable />
</el-form-item>
<el-form-item label="手机号" name="mobile">
<el-input v-model:value="infoFormState.mobile" placeholder="请输入手机号码" prefix-icon="Phone" clearable />
<el-input v-model="infoFormState.mobile" placeholder="请输入手机号码" prefix-icon="Phone" clearable />
</el-form-item>
<el-form-item label="邮箱" name="email">
<el-input v-model:value="infoFormState.email" placeholder="请输入邮箱" prefix-icon="Message" clearable />
<el-input v-model="infoFormState.email" placeholder="请输入邮箱" prefix-icon="Message" clearable />
</el-form-item>
<el-form-item label="性别" name="gender">
@@ -159,24 +159,24 @@
</template>
<div>
<el-form ref="ruleFormRef" :model="passwordFormState" :rules="resetPasswordRules" label-suffix=":">
<el-form-item label="当前密码" name="oldPassword">
<el-input v-model.trim="passwordFormState.oldPassword" :placeholder="t('login.password')" type="password" show-password clearable>
<el-form-item label="当前密码" name="old_password">
<el-input v-model.trim="passwordFormState.old_password" :placeholder="t('login.password')" type="password" show-password clearable>
<template #prefix>
<Lock />
</template>
</el-input>
</el-form-item>
<el-form-item label="新密码" name="newPassword">
<el-input v-model.trim="passwordFormState.newPassword" type="password" :placeholder="t('login.newPassword')" show-password clearable>
<el-form-item label="新密码" name="new_password">
<el-input v-model.trim="passwordFormState.new_password" type="password" :placeholder="t('login.newPassword')" show-password clearable>
<template #prefix>
<Key />
</template>
</el-input>
</el-form-item>
<el-form-item label="确认新密码" name="confirmPassword">
<el-input v-model.trim="passwordFormState.confirmPassword" type="password" :placeholder="t('login.message.password.confirm')" show-password clearable>
<el-form-item label="确认新密码" name="confirm_password">
<el-input v-model.trim="passwordFormState.confirm_password" type="password" :placeholder="t('login.message.password.confirm')" show-password clearable>
<template #prefix>
<Check />
</template>
@@ -184,7 +184,7 @@
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="passwordChanging" icon="edit">更新密码</el-button>
<el-button type="primary" :loading="passwordChanging" icon="edit" @click="handlePasswordChange">更新密码</el-button>
</el-form-item>
</el-form>
</div>
@@ -200,8 +200,10 @@
import type { FormInstance } from 'element-plus'
import UserAPI, { type InfoFormState, type PasswordFormState } from '@/api/system/user';
import { useUserStore, useDictStore } from "@/store";
import { useUserStoreHook } from "@/store/modules/user.store";
import { Camera } from '@element-plus/icons-vue';
import { useI18n } from "vue-i18n";
import router from "@/router";
const { t } = useI18n();
const userStore = useUserStore();
@@ -236,9 +238,9 @@ const infoFormState = reactive<InfoFormState>({
// 修改密码表单
const passwordFormState = reactive<PasswordFormState>({
oldPassword: '',
newPassword: '',
confirmPassword: ''
old_password: '',
new_password: '',
confirm_password: ''
});
// 头像上传处理优化
@@ -348,20 +350,55 @@ const initPasswordForm = () => {
};
// 基本信息表单提交
const handleSave = async (values: any) => {
const handleSave = async () => {
try {
infoSubmitting.value = true;
values.avatar = infoFormState.avatar;
await UserAPI.updateCurrentUserInfo(values);
await userStore.getUserInfo;
infoFormState.avatar = infoFormState.avatar;
const response = await UserAPI.updateCurrentUserInfo(infoFormState);
await userStore.setUserInfo(response.data.data);
} catch (error) {
console.error(error);
} finally {
infoSubmitting.value = false;
}
};
// 修改密码
const handlePasswordChange = async () => {
try {
passwordChanging.value = true;
const response = await UserAPI.changeCurrentUserPassword(passwordFormState);
initPasswordForm();
await redirectToLogin(response.data.msg);
} catch (error) {
console.error(error);
} finally {
passwordChanging.value = false;
}
};
/**
* 重定向到登录页面
*/
async function redirectToLogin(message: string = "请重新登录"): Promise<void> {
try {
ElNotification({
title: "提示",
message,
type: "warning",
duration: 3000,
});
await useUserStoreHook().resetAllState();
// 跳转到登录页,保留当前路由用于登录后跳转
const currentPath = router.currentRoute.value.fullPath;
await router.push(`/login?redirect=${encodeURIComponent(currentPath)}`);
} catch (error: any) {
ElMessage.error(error.message);
}
}
onMounted(async () => {
await getOptions();
initInfoForm();
+1 -1
View File
@@ -383,7 +383,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -386,7 +386,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
@@ -427,7 +427,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -406,7 +406,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -341,7 +341,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -715,7 +715,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -432,7 +432,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -384,7 +384,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+1 -1
View File
@@ -411,7 +411,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}
+3 -3
View File
@@ -367,7 +367,7 @@ const formData = reactive<UserForm>({
gender: undefined,
email: undefined,
mobile: undefined,
is_superuser: undefined,
is_superuser: false, //
status: true,
description: undefined,
})
@@ -551,7 +551,7 @@ async function handleSubmit() {
handleCloseDialog();
handleResetQuery();
} catch (error: any) {
ElMessage.error(error.message);
console.log(error.message);
} finally {
loading.value = false;
}
@@ -650,7 +650,7 @@ async function handleDelete(ids: number[]) {
loading.value = false;
}
}).catch(() => {
ElMessage.info('已取消删除');
ElMessageBox.close();
});
}