Blame view

pinia/user.js 7.75 KB
c293da23   刘淇   新园林init
1
2
3
  import { defineStore } from 'pinia';
  import cache from '@/common/utils/cache';
  import globalConfig from '@/common/config/global';
9b30ab8c   刘淇   新增快速工单,原版
4
  import { login, getUserInfo, logout, moduleList, getSimpleDictDataList } from '@/api/user';
c293da23   刘淇   新园林init
5
6
  
  export const useUserStore = defineStore('user', {
9b30ab8c   刘淇   新增快速工单,原版
7
    // 修复1:删除重复的 state 定义,只保留根层级的 state
c293da23   刘淇   新园林init
8
    state: () => ({
9b30ab8c   刘淇   新增快速工单,原版
9
10
11
12
13
14
15
      token: cache.get(globalConfig.cache.tokenKey) || '', // 初始值从缓存取(兼容持久化)
      userInfo: cache.get(globalConfig.cache.userInfoKey) || {},
      userId: cache.get(globalConfig.cache.userIdKey) || '',
      moduleListInfo: cache.get(globalConfig.cache.moduleListKey) || '',
      expireTime: cache.get(globalConfig.cache.expireTimeKey) || 0,
      dictData: cache.get(globalConfig.cache.dictDataKey) || {},
      logoutLoading: false
c293da23   刘淇   新园林init
16
17
    }),
  
c293da23   刘淇   新园林init
18
19
20
21
22
23
24
25
26
27
28
    getters: {
      isLogin: (state) => {
        if (!state.token) return false;
        if (state.expireTime && state.expireTime < Date.now()) {
          return false;
        }
        return true;
      },
      permissions: (state) => state.userInfo.permissions || []
    },
  
c293da23   刘淇   新园林init
29
30
31
32
33
34
35
36
37
38
    actions: {
      async login(params) {
        try {
          const res = await login(params);
          const { accessToken, expiresTime, userId } = res;
  
          if (!accessToken) {
            throw new Error('登录失败,未获取到令牌');
          }
  
9b30ab8c   刘淇   新增快速工单,原版
39
          // 更新 Pinia state
c293da23   刘淇   新园林init
40
41
42
43
44
          this.token = accessToken;
          this.expireTime = expiresTime;
          this.userId = userId;
          this.userInfo = {};
  
9b30ab8c   刘淇   新增快速工单,原版
45
          // 等待 Pinia 持久化同步
c293da23   刘淇   新园林init
46
47
48
49
50
          await new Promise(resolve => setTimeout(resolve, 50));
  
          // 获取用户信息
          const userInfo = await this.getUserInfo();
          this.userInfo = userInfo;
c293da23   刘淇   新园林init
51
52
53
54
55
56
  
          // 获取模块列表
          let moduleListInfo = null;
          try {
            moduleListInfo = await this.getModuleList();
            this.moduleListInfo = moduleListInfo;
c293da23   刘淇   新园林init
57
58
59
60
61
          } catch (moduleErr) {
            console.warn('获取模块列表失败(不影响登录):', moduleErr);
            uni.showToast({ title: '获取模块列表失败,可正常登录', icon: 'none' });
          }
  
9b30ab8c   刘淇   新增快速工单,原版
62
63
64
65
66
67
68
69
70
71
72
          // 修复2:调用字典接口时,不直接抛错(避免阻断登录)
          try {
            const dictRes = await this.getAndSaveDictData();
            // 仅接口返回成功时才更新字典
            this.dictData = dictRes || {};
            console.log('字典数据获取成功:', this.dictData);
          } catch (dictErr) {
            console.warn('获取字典失败(不影响登录):', dictErr);
            uni.showToast({ title: '获取字典失败,可正常使用', icon: 'none' });
          }
  
c293da23   刘淇   新园林init
73
74
75
76
77
78
79
          return { ...res, userInfo, moduleListInfo };
        } catch (err) {
          console.error('登录流程失败:', err);
          throw err;
        }
      },
  
9b30ab8c   刘淇   新增快速工单,原版
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
      // 修复3:重构字典获取方法(加 Token 校验 + 强制携带 Token + 宽松错误处理)
      async getAndSaveDictData() {
        // 前置校验:无登录态直接返回,不请求接口
        if (!this.isLogin) {
          console.warn('未登录,跳过字典获取');
          return { code: -1, msg: '未登录' };
        }
  
        try {
          // 强制携带 Token(和 getModuleList 保持一致,避免拦截器同步延迟)
          const res = await getSimpleDictDataList(
            {}, // 接口入参(按需传,比如 dictType: ['level'])
            { header: { 'Authorization': `Bearer ${this.token}` } }
          );
  
          // 校验接口返回码(核心:避免非 0 码数据存入)
          if (res.code !== 0) {
            console.warn('字典接口返回失败:', res.msg);
            return res; // 返回错误信息,但不抛错
          }
          return res;
        } catch (err) {
          // 修复4:宽松错误处理,只打印日志,不抛错(避免阻断登录)
          console.error('字典接口请求异常:', err);
          return { code: -2, msg: '接口请求异常:' + (err.message || '网络错误') };
        }
      },
  
c293da23   刘淇   新园林init
108
109
      async getModuleList() {
        try {
c293da23   刘淇   新园林init
110
111
112
113
          if (!this.token) {
            throw new Error('未获取到登录令牌,无法获取模块列表');
          }
  
c293da23   刘淇   新园林init
114
          const res = await moduleList({}, {
9b30ab8c   刘淇   新增快速工单,原版
115
            header: { 'Authorization': `Bearer ${this.token}` }
c293da23   刘淇   新园林init
116
117
118
119
          });
          return res;
        } catch (err) {
          console.error('获取用户菜单失败:', err);
c293da23   刘淇   新园林init
120
121
122
123
124
125
126
127
128
129
          if (err?.data?.code === 401 || err?.message.includes('401')) {
            throw new Error('登录态已过期,请重新登录');
          } else {
            throw new Error('获取用户菜单失败,请重新登录');
          }
        }
      },
  
      async getUserInfo() {
        try {
c293da23   刘淇   新园林init
130
131
132
133
134
135
136
          const res = await getUserInfo();
          return res;
        } catch (err) {
          console.error('获取用户信息失败:', err);
          throw new Error('获取用户信息失败,请重新登录');
        }
      },
9b30ab8c   刘淇   新增快速工单,原版
137
  
c293da23   刘淇   新园林init
138
139
140
141
142
143
144
145
146
147
      logout() {
        const pages = getCurrentPages();
        if (pages.length === 0) return;
  
        const currentPageRoute = pages[pages.length - 1].route;
        const loginPath = globalConfig.router.loginPath
          .replace(/^\//, '')
          .split('?')[0];
  
        if (currentPageRoute === loginPath) {
c293da23   刘淇   新园林init
148
149
150
151
152
          this.token = '';
          this.userInfo = {};
          this.userId = '';
          this.moduleListInfo = '';
          this.expireTime = 0;
9b30ab8c   刘淇   新增快速工单,原版
153
          this.dictData = {};
c293da23   刘淇   新园林init
154
155
156
157
158
159
160
161
162
163
164
165
          return;
        }
  
        const logoutWithLock = async () => {
          if (this.logoutLoading) return;
          this.logoutLoading = true;
  
          try {
            await logout();
          } catch (err) {
            console.error('退出登录接口调用失败:', err);
          } finally {
c293da23   刘淇   新园林init
166
167
168
169
            this.token = '';
            this.userInfo = {};
            this.userId = '';
            this.moduleListInfo = '';
9b30ab8c   刘淇   新增快速工单,原版
170
            this.dictData = {};
c293da23   刘淇   新园林init
171
172
173
            this.expireTime = 0;
            this.logoutLoading = false;
  
c293da23   刘淇   新园林init
174
175
176
177
178
179
180
181
182
            uni.redirectTo({
              url: globalConfig.router.loginPath
            });
          }
        };
  
        logoutWithLock();
      },
  
c293da23   刘淇   新园林init
183
184
      checkLogin() {
        if (!this.isLogin) {
c293da23   刘淇   新园林init
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
          const pages = getCurrentPages();
          if (pages.length === 0) return false;
  
          const currentPageRoute = pages[pages.length - 1].route;
          const loginPath = globalConfig.router.loginPath
            .replace(/^\//, '')
            .split('?')[0];
  
          if (currentPageRoute !== loginPath) {
            uni.redirectTo({
              url: globalConfig.router.loginPath
            });
          }
          return false;
        }
        return true;
      }
    },
  
c293da23   刘淇   新园林init
204
205
    persist: {
      enabled: true,
9b30ab8c   刘淇   新增快速工单,原版
206
      key: 'user_store',
c293da23   刘淇   新园林init
207
208
209
210
211
      storage: {
        getItem: (key) => uni.getStorageSync(key),
        setItem: (key, value) => uni.setStorageSync(key, value),
        removeItem: (key) => uni.removeStorageSync(key)
      },
c293da23   刘淇   新园林init
212
213
      serializer: {
        serialize: (state) => {
c293da23   刘淇   新园林init
214
215
216
217
218
          uni.setStorageSync(globalConfig.cache.tokenKey, state.token);
          uni.setStorageSync(globalConfig.cache.userIdKey, state.userId);
          uni.setStorageSync(globalConfig.cache.expireTimeKey, state.expireTime);
          uni.setStorageSync(globalConfig.cache.userInfoKey, state.userInfo);
          uni.setStorageSync(globalConfig.cache.moduleListKey, state.moduleListInfo);
9b30ab8c   刘淇   新增快速工单,原版
219
220
          uni.setStorageSync(globalConfig.cache.dictDataKey, state.dictData);
          return state;
c293da23   刘淇   新园林init
221
222
        },
        deserialize: (value) => {
c293da23   刘淇   新园林init
223
224
225
226
227
228
          return {
            token: uni.getStorageSync(globalConfig.cache.tokenKey) || '',
            userId: uni.getStorageSync(globalConfig.cache.userIdKey) || '',
            expireTime: uni.getStorageSync(globalConfig.cache.expireTimeKey) || 0,
            userInfo: uni.getStorageSync(globalConfig.cache.userInfoKey) || {},
            moduleListInfo: uni.getStorageSync(globalConfig.cache.moduleListKey) || '',
9b30ab8c   刘淇   新增快速工单,原版
229
            dictData: uni.getStorageSync(globalConfig.cache.dictDataKey) || {},
c293da23   刘淇   新园林init
230
231
232
233
            logoutLoading: false
          };
        }
      },
9b30ab8c   刘淇   新增快速工单,原版
234
      paths: []
c293da23   刘淇   新园林init
235
236
    }
  });