adtec-core-package 3.2.8 → 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.8",
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",
@@ -12,25 +12,29 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
12
12
  const dictStores = dictStore()
13
13
  const { clearDictCache } = dictStores
14
14
  const { dictMap, dictDefaultValueMap, dictDataMap } = storeToRefs(dictStores)
15
+
16
+ const resolveOrgId = (explicitOrgId?: string): string | undefined => {
17
+ if (explicitOrgId) return explicitOrgId
18
+ userInfo.hydrateFromRootSession()
19
+ return userInfo.user?.orgId
20
+ }
21
+
15
22
  const getDict = async (dictTypes?: string[], orgId?: string): Promise<void> => {
16
23
  try {
17
24
  if (!dictTypes || !dictTypes.length) return
18
- //判断是否存在缓存数据,如果存在则不请求接口
25
+ await userInfo.ensureUserHydrated()
26
+ const tenantOrgId = resolveOrgId(orgId)
19
27
  const dictKeySet = new Set(Object.keys(dictMap.value))
20
- let uncachedDictTypes = []
21
- if (orgId) {
22
- uncachedDictTypes = dictTypes.filter((dictType) => !dictKeySet.has(`${orgId}:${dictType}`))
28
+ let uncachedDictTypes: string[] = []
29
+ if (orgId || tenantOrgId) {
30
+ const oid = orgId ?? tenantOrgId!
31
+ uncachedDictTypes = dictTypes.filter((dictType) => !dictKeySet.has(`${oid}:${dictType}`))
23
32
  } else {
24
- uncachedDictTypes = dictTypes.filter(
25
- (dictType) =>
26
- !dictKeySet.has(`${userInfo.getUserInfo.orgId}:${dictType}`) &&
27
- !dictKeySet.has(dictType)
28
- )
33
+ uncachedDictTypes = dictTypes.filter((dictType) => !dictKeySet.has(dictType))
29
34
  }
30
35
  if (!uncachedDictTypes.length) return
31
- const data = await SysDictCacheApi.batchGetSysDictDataCacheVo(uncachedDictTypes, orgId)
36
+ const data = await SysDictCacheApi.batchGetSysDictDataCacheVo(uncachedDictTypes, orgId ?? tenantOrgId)
32
37
  dictMap.value = { ...dictMap.value, ...data }
33
- // 获取默认值
34
38
  const promises = Object.keys(data).map(async (item: string) => {
35
39
  const dataMap: dictDataMapVoType = {}
36
40
  const defaultList: ISysDictDataCacheVo[] = []
@@ -72,11 +76,13 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
72
76
  }
73
77
 
74
78
  const getDictName = (value?: string, dictType?: string, orgId?: string): string | undefined => {
75
- //此处需要支持多租户
76
79
  let key = orgId ? `${orgId}:${dictType}` : dictType
77
80
  if (dictDataMap.value[key!]) return dictDataMap.value[key!][value!]?.label || value
78
- key = `${userInfo.getUserInfo.orgId}:${dictType}`
79
- if (dictDataMap.value[key!]) return dictDataMap.value[key!][value!]?.label || value
81
+ const tenantOrgId = resolveOrgId()
82
+ if (tenantOrgId) {
83
+ key = `${tenantOrgId}:${dictType}`
84
+ if (dictDataMap.value[key!]) return dictDataMap.value[key!][value!]?.label || value
85
+ }
80
86
  return value
81
87
  }
82
88
 
@@ -85,46 +91,56 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
85
91
  dictType: string,
86
92
  orgId?: string,
87
93
  ): ISysDictDataCacheVo | {} => {
88
- //此处需要支持多租户
89
94
  let key = orgId ? `${orgId}:${dictType}` : dictType
90
95
  if (dictDataMap.value[key!] && dictDataMap.value[key!][value!])
91
96
  return dictDataMap.value[key!][value!]
92
- key = `${userInfo.getUserInfo.orgId}:${dictType}`
93
- if (dictDataMap.value[key!] && dictDataMap.value[key!][value!])
94
- return dictDataMap.value[key!][value!]
97
+ const tenantOrgId = resolveOrgId()
98
+ if (tenantOrgId) {
99
+ key = `${tenantOrgId}:${dictType}`
100
+ if (dictDataMap.value[key!] && dictDataMap.value[key!][value!])
101
+ return dictDataMap.value[key!][value!]
102
+ }
95
103
  return {}
96
104
  }
97
105
  const getDictDefaultValue = (
98
106
  dictType: string,
99
107
  orgId?: string
100
108
  ): ISysDictDataCacheVo[] => {
101
- //此处需要支持多租户
102
109
  let key = orgId ? `${orgId}:${dictType}` : dictType
103
110
  if (dictDefaultValueMap.value[key!]) return dictDefaultValueMap.value[key!]
104
- key = `${userInfo.getUserInfo.orgId}:${dictType}`
105
- if (dictDefaultValueMap.value[key!]) return dictDefaultValueMap.value[key!]
111
+ const tenantOrgId = resolveOrgId()
112
+ if (tenantOrgId) {
113
+ key = `${tenantOrgId}:${dictType}`
114
+ if (dictDefaultValueMap.value[key!]) return dictDefaultValueMap.value[key!]
115
+ }
106
116
  return []
107
117
  }
108
118
  const getDictTypeData = (dictType: string, orgId?: string): ISysDictDataCacheVo[] => {
109
- //此处需要支持多租户
110
119
  let key = orgId ? `${orgId}:${dictType}` : dictType
111
120
  if (dictMap.value[key!]) return dictMap.value[key!]
112
- key = `${userInfo.getUserInfo.orgId}:${dictType}`
113
- if (dictMap.value[key!]) return dictMap.value[key!]
121
+ const tenantOrgId = resolveOrgId()
122
+ if (tenantOrgId) {
123
+ key = `${tenantOrgId}:${dictType}`
124
+ if (dictMap.value[key!]) return dictMap.value[key!]
125
+ }
114
126
  return []
115
127
  }
116
128
  const clearDict = (dictType?: string[], orgId?: string, all?: Boolean) => {
117
- clearDictCache(dictType, userInfo.getUserInfo.orgId, orgId, all)
129
+ clearDictCache(dictType, resolveOrgId(), orgId, all)
118
130
  }
119
- /** 构造函数传入的 dictTypes 是否已全部加载(缓存命中也会立即置 true) */
131
+ const userReady = ref(!dictTypes?.length)
120
132
  const dictReady = ref(!dictTypes?.length)
121
133
  if (dictTypes?.length) {
122
- getDict(dictTypes, orgId).finally(() => {
134
+ void (async () => {
135
+ await userInfo.ensureUserHydrated()
136
+ userReady.value = true
137
+ await getDict(dictTypes, orgId)
123
138
  dictReady.value = true
124
- })
139
+ })()
125
140
  }
126
141
  return {
127
142
  getDict,
143
+ userReady,
128
144
  dictReady,
129
145
  getDictName,
130
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
  }
@@ -6,26 +6,70 @@
6
6
  */
7
7
  import { defineStore } from 'pinia'
8
8
  import type { IUserPermissionVo } from '../interface/IUserPermissionVo'
9
+ import { readUserInfoFromSessionStorage } from '../utils/userSessionStorage'
10
+
11
+ let hydratePromise: Promise<IUserPermissionVo | null> | null = null
12
+
13
+ function resetHydratePromise() {
14
+ hydratePromise = null
15
+ }
9
16
 
10
17
  export const userInfoStore = defineStore({
11
18
  id: 'userInfoStore',
12
19
  state: () => ({
13
20
  //@ts-ignore
14
- user: null as IUserPermissionVo
21
+ user: null as IUserPermissionVo | null,
15
22
  }),
16
23
  getters: {
17
24
  getUserInfo(): IUserPermissionVo {
25
+ this.hydrateFromRootSession()
18
26
  return this.user as IUserPermissionVo
19
- }
27
+ },
20
28
  },
21
29
  actions: {
30
+ /** 无界子应用从宿主 sessionStorage 恢复登录态(与 dictStore 同源策略) */
31
+ hydrateFromRootSession(): IUserPermissionVo | null {
32
+ if (this.user?.orgId) {
33
+ return this.user
34
+ }
35
+ const hydrated = readUserInfoFromSessionStorage()
36
+ if (hydrated?.orgId) {
37
+ //@ts-ignore
38
+ this.user = hydrated
39
+ }
40
+ return this.user
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
+ },
22
64
  setUserInfo(userInfo: IUserPermissionVo) {
65
+ resetHydratePromise()
23
66
  //@ts-ignore
24
67
  this.user = userInfo
25
68
  },
26
69
  clear() {
70
+ resetHydratePromise()
27
71
  //@ts-ignore
28
72
  this.user = null
29
- }
30
- }
73
+ },
74
+ },
31
75
  })
@@ -0,0 +1,38 @@
1
+ import Base64 from 'crypto-js/enc-base64'
2
+ import Utf8 from 'crypto-js/enc-utf8'
3
+ import type { IUserPermissionVo } from '../interface/IUserPermissionVo'
4
+
5
+ const USER_INFO_STORAGE_KEY = 'userInfoStore'
6
+
7
+ /** wujie 子应用读宿主 sessionStorage,独立运行读自身 */
8
+ export function getRootWindow(): Window {
9
+ if (typeof window === 'undefined') return window
10
+ const w = window as Window & { __POWERED_BY_WUJIE__?: boolean }
11
+ return w.__POWERED_BY_WUJIE__ ? window.parent : window
12
+ }
13
+
14
+ /** 从 pinia-plugin-store 持久化的 sessionStorage 恢复用户信息 */
15
+ export function readUserInfoFromSessionStorage(storage?: Storage): IUserPermissionVo | null {
16
+ if (typeof window === 'undefined') return null
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
+ }
29
+ if (!raw) return null
30
+ try {
31
+ const parsed = JSON.parse(Base64.parse(raw).toString(Utf8)) as {
32
+ user?: IUserPermissionVo | null
33
+ }
34
+ return parsed?.user ?? null
35
+ } catch {
36
+ return null
37
+ }
38
+ }