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.
|
|
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
|
-
|
|
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
|
-
|
|
79
|
-
if (
|
|
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
|
-
|
|
93
|
-
if (
|
|
94
|
-
|
|
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
|
-
|
|
105
|
-
if (
|
|
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
|
-
|
|
113
|
-
if (
|
|
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,
|
|
129
|
+
clearDictCache(dictType, resolveOrgId(), orgId, all)
|
|
118
130
|
}
|
|
119
|
-
|
|
131
|
+
const userReady = ref(!dictTypes?.length)
|
|
120
132
|
const dictReady = ref(!dictTypes?.length)
|
|
121
133
|
if (dictTypes?.length) {
|
|
122
|
-
|
|
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,
|
package/src/stores/dictStore.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
+
}
|