132 lines
3.7 KiB
TypeScript
132 lines
3.7 KiB
TypeScript
import { defineStore } from 'pinia';
|
||
import { ref, computed } from 'vue';
|
||
import { setCache, getCache, removeCache } from '@/utils/cache';
|
||
import {
|
||
psdLogin as psdLoginApi,
|
||
parentSmsLogin as parentSmsLoginApi,
|
||
getUserInfo as getUserInfoApi,
|
||
logout as logoutApi,
|
||
type AccountLoginParams,
|
||
type ParentSmsLoginParams,
|
||
} from '@/api/login';
|
||
|
||
export interface UserInfo {
|
||
id?: string;
|
||
account?: string;
|
||
nickName?: string;
|
||
avatarUrl?: string;
|
||
learnGradeId?: string;
|
||
schoolName?: string;
|
||
className?: string;
|
||
classId?: string;
|
||
diamond?: number;
|
||
experience?: number;
|
||
schoolClass?: any[];
|
||
[key: string]: any;
|
||
}
|
||
|
||
/**
|
||
* 学生用户 store(兼容老接口)
|
||
*/
|
||
export const useUserStore = defineStore('user', () => {
|
||
const userInfo = ref<UserInfo>(getCache('userInfo') || {});
|
||
const token = ref<string>(getCache('token') || '');
|
||
|
||
const isLogin = computed(() => !!token.value);
|
||
const gradeId = computed(() => userInfo.value.learnGradeId || '');
|
||
|
||
/** 清空登录态与缓存 */
|
||
const clear = async () => {
|
||
token.value = '';
|
||
userInfo.value = {};
|
||
removeCache('token');
|
||
removeCache('userInfo');
|
||
removeCache('teacherInfo');
|
||
removeCache('role');
|
||
};
|
||
|
||
/** 拉取并解析用户信息 */
|
||
const fetchUserInfo = async () => {
|
||
try {
|
||
const res = await getUserInfoApi();
|
||
const info: UserInfo = res.data || {};
|
||
|
||
// schoolClass 字段后端有时是 JSON 字符串
|
||
if (typeof info.schoolClass === 'string') {
|
||
try {
|
||
info.schoolClass = JSON.parse(info.schoolClass);
|
||
} catch {
|
||
info.schoolClass = [];
|
||
}
|
||
}
|
||
|
||
// 提取学校班级到顶层方便展示
|
||
if (Array.isArray(info.schoolClass) && info.schoolClass.length) {
|
||
const school = info.schoolClass[0];
|
||
info.schoolName = school?.schoolName || '';
|
||
const cls = school?.classList?.[0];
|
||
if (cls) {
|
||
info.className = cls.className;
|
||
info.classId = cls.classId;
|
||
}
|
||
}
|
||
|
||
userInfo.value = info;
|
||
setCache('userInfo', info);
|
||
return info;
|
||
} catch (err) {
|
||
console.error('[user] fetchUserInfo error', err);
|
||
throw err;
|
||
}
|
||
};
|
||
|
||
/** 账号密码登录 */
|
||
const accountLogin = async (data: AccountLoginParams) => {
|
||
await clear();
|
||
setCache('role', data.clientType === 'MANAGE' ? 'teacher' : 'student');
|
||
const res = await psdLoginApi(data);
|
||
token.value = res.data;
|
||
setCache('token', res.data);
|
||
await fetchUserInfo();
|
||
};
|
||
|
||
/** 家长端 - 手机号验证码登录 */
|
||
const parentLogin = async (data: ParentSmsLoginParams) => {
|
||
await clear();
|
||
const res = await parentSmsLoginApi(data);
|
||
token.value = res.data;
|
||
setCache('token', res.data);
|
||
setCache('role', 'parent');
|
||
};
|
||
|
||
/** 退出登录 */
|
||
const logout = async () => {
|
||
try {
|
||
await logoutApi();
|
||
} catch (e) {
|
||
console.warn('[user] logout api error', e);
|
||
}
|
||
await clear();
|
||
uni.reLaunch({ url: '/pages/index/index' });
|
||
};
|
||
|
||
/** 部分更新本地用户信息 */
|
||
const updateUserInfo = (info: Partial<UserInfo>) => {
|
||
userInfo.value = { ...userInfo.value, ...info };
|
||
setCache('userInfo', userInfo.value);
|
||
};
|
||
|
||
return {
|
||
userInfo,
|
||
token,
|
||
isLogin,
|
||
gradeId,
|
||
accountLogin,
|
||
parentLogin,
|
||
fetchUserInfo,
|
||
logout,
|
||
clear,
|
||
updateUserInfo,
|
||
};
|
||
});
|