adtec-core-package 3.2.9 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adtec-core-package",
3
- "version": "3.2.9",
3
+ "version": "3.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -102,6 +102,7 @@
102
102
  "smooth-signature": "1.0.15",
103
103
  "socket.io-client": "^2.3.1",
104
104
  "tdesign-vue-next": "1.18.2",
105
+ "ts-md5": "^1.3.1",
105
106
  "uuid": "^11.0.3",
106
107
  "vue": "^3.5.13",
107
108
  "vue-demi": "^0.14.10",
@@ -22,6 +22,7 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
22
22
  const getDict = async (dictTypes?: string[], orgId?: string): Promise<void> => {
23
23
  try {
24
24
  if (!dictTypes || !dictTypes.length) return
25
+ await userInfo.ensureUserHydrated()
25
26
  const tenantOrgId = resolveOrgId(orgId)
26
27
  const dictKeySet = new Set(Object.keys(dictMap.value))
27
28
  let uncachedDictTypes: string[] = []
@@ -127,14 +128,19 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
127
128
  const clearDict = (dictType?: string[], orgId?: string, all?: Boolean) => {
128
129
  clearDictCache(dictType, resolveOrgId(), orgId, all)
129
130
  }
131
+ const userReady = ref(!dictTypes?.length)
130
132
  const dictReady = ref(!dictTypes?.length)
131
133
  if (dictTypes?.length) {
132
- getDict(dictTypes, orgId).finally(() => {
134
+ void (async () => {
135
+ await userInfo.ensureUserHydrated()
136
+ userReady.value = true
137
+ await getDict(dictTypes, orgId)
133
138
  dictReady.value = true
134
- })
139
+ })()
135
140
  }
136
141
  return {
137
142
  getDict,
143
+ userReady,
138
144
  dictReady,
139
145
  getDictName,
140
146
  getDictData,
@@ -47,7 +47,7 @@ function getRootWindow(): Window {
47
47
  }
48
48
 
49
49
  function hydrateCacheFromSessionStorage(cache: SharedDictCache) {
50
- const raw = sessionStorage.getItem(DICT_STORAGE_KEY)
50
+ const raw = getRootWindow().sessionStorage.getItem(DICT_STORAGE_KEY)
51
51
  if (!raw) return
52
52
  try {
53
53
  const parsed = JSON.parse(Base64.parse(raw).toString(Utf8)) as {
@@ -70,14 +70,15 @@ function hydrateCacheFromSessionStorage(cache: SharedDictCache) {
70
70
  }
71
71
 
72
72
  function persistCacheToSessionStorage(cache: SharedDictCache) {
73
- if (typeof sessionStorage === 'undefined') return
73
+ if (typeof window === 'undefined') return
74
+ const storage = getRootWindow().sessionStorage
74
75
  try {
75
76
  const payload = JSON.stringify({
76
77
  dictMap: cache.dictMap,
77
78
  dictDataMap: cache.dictDataMap,
78
79
  dictDefaultValueMap: cache.dictDefaultValueMap,
79
80
  })
80
- sessionStorage.setItem(DICT_STORAGE_KEY, Base64.stringify(Utf8.parse(payload)))
81
+ storage.setItem(DICT_STORAGE_KEY, Base64.stringify(Utf8.parse(payload)))
81
82
  } catch {
82
83
  // ignore quota / privacy errors
83
84
  }
@@ -8,6 +8,12 @@ import { defineStore } from 'pinia'
8
8
  import type { IUserPermissionVo } from '../interface/IUserPermissionVo'
9
9
  import { readUserInfoFromSessionStorage } from '../utils/userSessionStorage'
10
10
 
11
+ let hydratePromise: Promise<IUserPermissionVo | null> | null = null
12
+
13
+ function resetHydratePromise() {
14
+ hydratePromise = null
15
+ }
16
+
11
17
  export const userInfoStore = defineStore({
12
18
  id: 'userInfoStore',
13
19
  state: () => ({
@@ -16,34 +22,52 @@ export const userInfoStore = defineStore({
16
22
  }),
17
23
  getters: {
18
24
  getUserInfo(): IUserPermissionVo {
19
- if (!this.user) {
20
- const hydrated = readUserInfoFromSessionStorage()
21
- if (hydrated) {
22
- //@ts-ignore
23
- this.user = hydrated
24
- }
25
- }
25
+ this.hydrateFromRootSession()
26
26
  return this.user as IUserPermissionVo
27
27
  },
28
28
  },
29
29
  actions: {
30
30
  /** 无界子应用从宿主 sessionStorage 恢复登录态(与 dictStore 同源策略) */
31
31
  hydrateFromRootSession(): IUserPermissionVo | null {
32
- if (this.user) {
32
+ if (this.user?.orgId) {
33
33
  return this.user
34
34
  }
35
35
  const hydrated = readUserInfoFromSessionStorage()
36
- if (hydrated) {
36
+ if (hydrated?.orgId) {
37
37
  //@ts-ignore
38
38
  this.user = hydrated
39
39
  }
40
40
  return this.user
41
41
  },
42
+ /** 等待宿主 sessionStorage 写入 userInfo(无界子应用首次进入菜单页) */
43
+ async ensureUserHydrated(maxWaitMs = 3000): Promise<IUserPermissionVo | null> {
44
+ if (this.user?.orgId) {
45
+ return this.user
46
+ }
47
+ if (!hydratePromise) {
48
+ hydratePromise = (async () => {
49
+ const deadline = Date.now() + maxWaitMs
50
+ while (Date.now() < deadline) {
51
+ const hydrated = this.hydrateFromRootSession()
52
+ if (hydrated?.orgId) {
53
+ return hydrated
54
+ }
55
+ await new Promise((resolve) => setTimeout(resolve, 50))
56
+ }
57
+ return this.user
58
+ })().finally(() => {
59
+ hydratePromise = null
60
+ })
61
+ }
62
+ return hydratePromise
63
+ },
42
64
  setUserInfo(userInfo: IUserPermissionVo) {
65
+ resetHydratePromise()
43
66
  //@ts-ignore
44
67
  this.user = userInfo
45
68
  },
46
69
  clear() {
70
+ resetHydratePromise()
47
71
  //@ts-ignore
48
72
  this.user = null
49
73
  },
@@ -14,8 +14,18 @@ export function getRootWindow(): Window {
14
14
  /** 从 pinia-plugin-store 持久化的 sessionStorage 恢复用户信息 */
15
15
  export function readUserInfoFromSessionStorage(storage?: Storage): IUserPermissionVo | null {
16
16
  if (typeof window === 'undefined') return null
17
- const store = storage ?? getRootWindow().sessionStorage
18
- const raw = store.getItem(USER_INFO_STORAGE_KEY)
17
+ let store: Storage
18
+ try {
19
+ store = storage ?? getRootWindow().sessionStorage
20
+ } catch {
21
+ return null
22
+ }
23
+ let raw: string | null
24
+ try {
25
+ raw = store.getItem(USER_INFO_STORAGE_KEY)
26
+ } catch {
27
+ return null
28
+ }
19
29
  if (!raw) return null
20
30
  try {
21
31
  const parsed = JSON.parse(Base64.parse(raw).toString(Utf8)) as {