2 Commits

Author SHA1 Message Date
ZhuRui b3458fd4b8 fix: 优化用户信息展示 2026-08-05 16:02:01 +08:00
ZhuRui e79404aba9 fix: 优化登录逻辑 2026-08-05 15:40:57 +08:00
7 changed files with 79 additions and 10 deletions
+8 -1
View File
@@ -1,5 +1,12 @@
import { post } from '@/utils/request'; import { post } from '@/utils/request';
import type { LoginResult } from './types';
export type { LoginResult } from './types';
export const login = (params: { phone: string; password: string }) => { export const login = (params: { phone: string; password: string }) => {
return post(`/op/login`, params); return post(`/op/login`, params) as Promise<{
code: number;
msg: string;
data: LoginResult;
}>;
}; };
+8
View File
@@ -0,0 +1,8 @@
export interface LoginResult {
token: string;
phone?: string;
nickName?: string;
realName?: string;
userName?: string;
name?: string;
}
+18 -3
View File
@@ -3,6 +3,7 @@ import type { MenuNode, PermissionCode } from '@/types';
import { FALLBACK_MENU_NODES } from '@/config/fallbackRoutes'; import { FALLBACK_MENU_NODES } from '@/config/fallbackRoutes';
import { getAuthDataPromise, setAuthDataPromise, clearAuthDataCache } from '@/api/authCache'; import { getAuthDataPromise, setAuthDataPromise, clearAuthDataCache } from '@/api/authCache';
import { forceReLogin } from '@/hooks/useAuth'; import { forceReLogin } from '@/hooks/useAuth';
import { useUserStore } from '@/stores/userStore';
export { clearAuthDataCache } from '@/api/authCache'; export { clearAuthDataCache } from '@/api/authCache';
@@ -12,6 +13,8 @@ export { clearAuthDataCache } from '@/api/authCache';
export interface AuthData { export interface AuthData {
roleList: string[]; roleList: string[];
permsList: string[]; permsList: string[];
nickname: string;
phone: string;
} }
const AUTH_FETCH_FAIL_MSG = '账户权限获取失败,请重新登录'; const AUTH_FETCH_FAIL_MSG = '账户权限获取失败,请重新登录';
@@ -21,14 +24,26 @@ function normalizeAuthData(res: any): AuthData {
throw new Error(res.msg || AUTH_FETCH_FAIL_MSG); throw new Error(res.msg || AUTH_FETCH_FAIL_MSG);
} }
const roleList = res?.data?.roleList || []; const data = res?.data || {};
const permsList = res?.data?.permsList || []; const roleList = data.roleList || [];
const permsList = data.permsList || [];
if (permsList.length === 0) { if (permsList.length === 0) {
throw new Error(AUTH_FETCH_FAIL_MSG); throw new Error(AUTH_FETCH_FAIL_MSG);
} }
return { roleList, permsList }; const nickname = data.nickName || '';
const phone = typeof data.phone === 'string' ? data.phone : '';
if (nickname || phone) {
const { setUser } = useUserStore();
setUser({
...(nickname ? { nickname } : {}),
...(phone ? { phone } : {}),
});
}
return { roleList, permsList, nickname, phone };
} }
function handleAuthFetchFailure() { function handleAuthFetchFailure() {
+1 -1
View File
@@ -62,7 +62,7 @@
align-items: center; align-items: center;
} }
.userPhone { .displayName {
font-size: 14px; font-size: 14px;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
} }
+6 -2
View File
@@ -78,7 +78,8 @@ export default defineComponent({
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const { menuItems } = useMenuStore(); const { menuItems } = useMenuStore();
const { phone } = useUserStore(); const { phone, nickname } = useUserStore();
const displayName = computed(() => nickname.value || phone.value);
const { const {
tabs, tabs,
cachedViews, cachedViews,
@@ -138,6 +139,9 @@ export default defineComponent({
if (res.code == 200) { if (res.code == 200) {
message.success('密码修改成功'); message.success('密码修改成功');
setChangePwdVisible(false); setChangePwdVisible(false);
window.setTimeout(() => {
auth.logout();
}, 1500);
} else { } else {
message.error(res.msg || '修改失败'); message.error(res.msg || '修改失败');
} }
@@ -229,7 +233,7 @@ export default defineComponent({
{/* 右侧: 账号信息 + 退出 */} {/* 右侧: 账号信息 + 退出 */}
<div class={styles.headerRight}> <div class={styles.headerRight}>
<span class={styles.userPhone}>{phone.value}</span> <span class={styles.displayName}>{displayName.value}</span>
<Dropdown trigger={['hover']} placement="bottomLeft"> <Dropdown trigger={['hover']} placement="bottomLeft">
{{ {{
default: () => <img src={logoutSvg} class={styles.logoutIcon} />, default: () => <img src={logoutSvg} class={styles.logoutIcon} />,
+10 -1
View File
@@ -55,7 +55,16 @@ export default defineComponent({
try { try {
const res = await loginApi({ phone: form.phone, password: form.password }); const res = await loginApi({ phone: form.phone, password: form.password });
setUser({ phone: form.phone, nickname: res.data.nickname, token: res.data.token }); if (res.code != 200) {
message.error(res.msg || '登录失败');
return;
}
setUser({
phone: res.data.phone || form.phone,
nickname: res.data.nickName || '',
token: res.data.token,
});
if (rememberMe.value) { if (rememberMe.value) {
localStorage.setItem( localStorage.setItem(
+28 -2
View File
@@ -9,9 +9,32 @@ interface UserState {
token: string; token: string;
} }
const USER_PROFILE_KEY = 'cpms_user_profile';
function loadUserProfile(): Pick<UserState, 'phone' | 'nickname'> {
try {
const raw = window.localStorage.getItem(USER_PROFILE_KEY);
if (!raw) return { phone: '', nickname: '' };
const data = JSON.parse(raw);
return {
phone: typeof data.phone === 'string' ? data.phone : '',
nickname: typeof data.nickname === 'string' ? data.nickname : '',
};
} catch {
window.localStorage.removeItem(USER_PROFILE_KEY);
return { phone: '', nickname: '' };
}
}
function persistUserProfile(profile: Pick<UserState, 'phone' | 'nickname'>) {
window.localStorage.setItem(USER_PROFILE_KEY, JSON.stringify(profile));
}
const savedProfile = loadUserProfile();
const state = reactive<UserState>({ const state = reactive<UserState>({
phone: '', phone: savedProfile.phone,
nickname: '', nickname: savedProfile.nickname,
token: '', token: '',
}); });
@@ -20,12 +43,15 @@ export function useUserStore() {
if (user.phone !== undefined) state.phone = user.phone; if (user.phone !== undefined) state.phone = user.phone;
if (user.nickname !== undefined) state.nickname = user.nickname; if (user.nickname !== undefined) state.nickname = user.nickname;
if (user.token !== undefined) state.token = user.token; if (user.token !== undefined) state.token = user.token;
persistUserProfile({ phone: state.phone, nickname: state.nickname });
}; };
const clearUser = () => { const clearUser = () => {
state.phone = ''; state.phone = '';
state.nickname = ''; state.nickname = '';
state.token = ''; state.token = '';
window.localStorage.removeItem(USER_PROFILE_KEY);
}; };
return { return {