| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // src/store/user.ts
- import { defineStore } from 'pinia'
- import { ref, computed} from 'vue'
- import { generateDefaultAvatar } from '@/utils/defaultUtils'
- import { getUserProfileApi, updateUserProfileApi } from '@/api/user' // 【新增】导入API
- // 定义 user info 的接口,以便后续的修改
- interface IUserInfo {
- id: string | number;
- name: string;
- officialEmail: string | null;
- officialNumber: string | null;
- role: 'STUDENT' | 'TEACHER' | 'ADMIN' | null;
- userAvatar: string | null;
- createTime: string | null;
- englishName: string | null;
- gender: 'MAN' | 'WOMAN' | null;
- birthday: string | null;
- phone: string | null;
- contentEmail: string | null;
- pid: string | number;
- openid: string | null;
- unionid: string | null;
- isWechatBound: boolean;
- }
- const defaultUserInfo: IUserInfo = {
- id: '',
- name: '',
- officialEmail: null,
- officialNumber: null,
- role: 'STUDENT',
- userAvatar: null,
- createTime: null,
- englishName: null,
- gender: null,
- birthday: null,
- phone: null,
- contentEmail: null,
- pid: 0,
- openid: null,
- unionid: null,
- isWechatBound: false
- }
- export const useUserStore = defineStore('user', () => {
- const userInfo = ref<IUserInfo>({ ...defaultUserInfo })
- const isLoggedIn = ref<boolean>(false)
- const token = ref<string | null>(null);
-
- const displayAvatar = computed(() => {
- // return userInfo.value.userAvatar || generateDefaultAvatar(userInfo.value)
- return generateDefaultAvatar(userInfo.value);
- })
- const isUsingDefaultAvatar = computed(() => {
- return !userInfo.value.userAvatar
- })
-
- const setUserInfo = (info: Partial<any>, userToken?: string) => { // 将info的类型改为any,以便兼容后端返回的number
- // 将后端返回的数字角色和性别转换为字符串
- const roleMap = { 0: 'ADMIN', 1: 'STUDENT', 2: 'TEACHER' };
- const genderMap = { 0: 'MAN', 1: 'WOMAN' };
-
- if (typeof info.role === 'number') {
- info.role = roleMap[info.role];
- }
- if (typeof info.gender === 'number') {
- info.gender = genderMap[info.gender];
- }
-
- userInfo.value = { ...userInfo.value, ...info as Partial<IUserInfo> }
- isLoggedIn.value = true
- if (userToken) {
- token.value = userToken;
- }
- }
- // 用于更新用户信息的方法
- const updateUserProfile = async (updates: Partial<IUserInfo>) => {
- try {
- // 确保只发送有更新的字段
- const payload: any = {};
- Object.keys(updates).forEach(key => {
- payload[key] = updates[key];
- });
-
- if (Object.keys(payload).length > 0) {
- await updateUserProfileApi(payload);
- // API调用成功后,才更新本地状态
- setUserInfo(updates);
- uni.showToast({ title: '修改成功', icon: 'success', duration: 1500 });
- }
- } catch (error) {
- console.error("更新用户信息失败:", error);
- uni.showToast({ title: '修改失败,请稍后重试', icon: 'none' });
- throw error; // 向上抛出错误,让调用方知道失败了
- }
- };
-
- // 获取用户信息的 action
- const fetchUserProfile = async () => {
- const officialNumber = userInfo.value.officialNumber;
- if (!officialNumber) {
- console.error("未获取到学号,无法查询个人信息");
- uni.showToast({title: '获取个人信息失败', icon: 'none'});
- return;
- }
- try {
- const res = await getUserProfileApi(officialNumber);
- setUserInfo(res);
- } catch (error) {
- console.error("获取个人信息失败:", error);
- uni.showToast({title: '获取个人信息失败', icon: 'none'});
- }
- };
-
- // 更新用户信息
- const updateUserInfo = (info: Partial<IUserInfo>) => {
- userInfo.value = { ...userInfo.value, ...info }
- }
-
- const setCustomAvatar = (avatarUrl: string) => {
- userInfo.value.userAvatar = avatarUrl
- }
-
- const resetToDefaultAvatar = () => {
- userInfo.value.userAvatar = null;
- }
-
- const clearUserInfo = () => {
- console.log('【登出】执行 clearUserInfo...');
- userInfo.value = { ...defaultUserInfo };
- isLoggedIn.value = false;
- token.value = null;
-
- uni.removeStorageSync('user-store');
-
- uni.reLaunch({
- url: '/pages/login/index'
- });
- }
-
- const resetUserInfo = () => {
- userInfo.value = { ...defaultUserInfo }
- }
-
- const checkLoginStatus = () => {
- return !!token.value && isLoggedIn.value
- }
- const loadUserFromStorage = () => {
- try {
- const persistedState = uni.getStorageSync('user-store');
- if (persistedState) {
- const parsedState = JSON.parse(persistedState);
- if (parsedState.token && parsedState.isLoggedIn) {
- userInfo.value = parsedState.userInfo;
- isLoggedIn.value = parsedState.isLoggedIn;
- token.value = parsedState.token;
- console.log('【UserStore】状态从本地存储恢复成功。');
- } else {
- uni.removeStorageSync('user-store');
- }
- }
- } catch (e) {
- console.error('【UserStore】加载本地存储失败:', e);
- uni.removeStorageSync('user-store');
- }
- };
-
- return {
- userInfo,
- isLoggedIn,
- token,
- displayAvatar,
- isUsingDefaultAvatar,
- setUserInfo,
- fetchUserProfile,
- updateUserInfo, // 这个方法在profile页面中不再被直接使用,但保留
- updateUserProfile,
- setCustomAvatar,
- resetToDefaultAvatar,
- clearUserInfo,
- resetUserInfo,
- checkLoginStatus,
- loadUserFromStorage,
- }
- }, {
- persist: {
- key: 'user-store',
- storage: {
- getItem(key: string) { return uni.getStorageSync(key) },
- setItem(key: string, value: string) { uni.setStorageSync(key, value) }
- },
- paths: ['userInfo', 'isLoggedIn', 'token'],
- }
- })
|