adtec-core-package 3.0.4 → 3.0.7
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/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/package.json +21 -4
- package/prebuilt/umo-editor/umo-editor.css +1 -1
- package/prebuilt/umo-editor/umo-editor.js +13739 -15052
- package/prebuilt/umo-editor/umo-editor.js.map +1 -1
- package/src/components/RichTextEditor/RichTextEditor.vue +1 -1
- package/src/components/editor-main/src/components/index.vue +2 -1
- package/src/components/editor-main/src/components/menus/button.vue +30 -3
- package/src/components/editor-main/src/components/menus/toolbar/base/color.vue +12 -5
- package/src/components/editor-main/src/components/menus/toolbar/base/font-family.vue +6 -4
- package/src/components/editor-main/src/components/menus/toolbar/base/font-size.vue +42 -25
- package/src/components/editor-main/src/components/menus/toolbar/base/heading.vue +6 -8
- package/src/components/editor-main/src/composables/toolbarSelection.js +233 -0
- package/src/components/editor-main/src/locales/bo.json +2 -2
- package/src/components/editor-main/src/locales/en-US.json +2 -2
- package/src/components/editor-main/src/locales/it-IT.json +2 -2
- package/src/components/editor-main/src/locales/ru-RU.json +2 -2
- package/src/components/editor-main/src/locales/zh-CN.json +2 -2
- package/src/components/editor-main/src/utils/editor-scroll.js +39 -15
- package/src/components/vxeGrid/index.vue +11 -4
- package/src/hooks/useDictHooks.ts +10 -2
- package/src/stores/dictStore.ts +181 -5
|
@@ -1,35 +1,59 @@
|
|
|
1
|
+
/** TipTap focus 选项:不触发 ProseMirror scrollIntoView */
|
|
2
|
+
export const FOCUS_WITHOUT_SCROLL = { scrollIntoView: false }
|
|
3
|
+
|
|
4
|
+
function pushScrollPosition(positions, seen, el) {
|
|
5
|
+
if (!el || seen.has(el)) return
|
|
6
|
+
seen.add(el)
|
|
7
|
+
positions.push({
|
|
8
|
+
el,
|
|
9
|
+
top: el.scrollTop,
|
|
10
|
+
left: el.scrollLeft,
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
/**
|
|
2
|
-
* 保存/恢复编辑器及外层滚动位置,避免 setBlockType
|
|
15
|
+
* 保存/恢复编辑器及外层滚动位置,避免 toolbar focus / setBlockType 等触发 scrollIntoView 导致页面跳动。
|
|
3
16
|
*/
|
|
4
17
|
export function captureScrollPositions(container) {
|
|
5
18
|
const positions = []
|
|
19
|
+
const seen = new Set()
|
|
6
20
|
const pageContainer = document.querySelector(
|
|
7
21
|
`${container} .umo-zoomable-container`,
|
|
8
22
|
)
|
|
9
|
-
|
|
10
|
-
positions.push({
|
|
11
|
-
el: pageContainer,
|
|
12
|
-
top: pageContainer.scrollTop,
|
|
13
|
-
left: pageContainer.scrollLeft,
|
|
14
|
-
})
|
|
15
|
-
}
|
|
23
|
+
pushScrollPosition(positions, seen, pageContainer)
|
|
16
24
|
|
|
17
|
-
let node =
|
|
25
|
+
let node =
|
|
26
|
+
pageContainer?.parentElement ??
|
|
27
|
+
document.querySelector(container)?.parentElement ??
|
|
28
|
+
null
|
|
18
29
|
while (node && node !== document.documentElement) {
|
|
19
30
|
if (node.classList?.contains('el-scrollbar__wrap')) {
|
|
20
|
-
positions
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
pushScrollPosition(positions, seen, node)
|
|
32
|
+
} else {
|
|
33
|
+
const style = getComputedStyle(node)
|
|
34
|
+
const overflow = `${style.overflow}${style.overflowY}${style.overflowX}`
|
|
35
|
+
if (/auto|scroll/.test(overflow)) {
|
|
36
|
+
pushScrollPosition(positions, seen, node)
|
|
37
|
+
}
|
|
26
38
|
}
|
|
27
39
|
node = node.parentElement
|
|
28
40
|
}
|
|
29
41
|
|
|
42
|
+
pushScrollPosition(positions, seen, document.documentElement)
|
|
43
|
+
pushScrollPosition(positions, seen, document.body)
|
|
44
|
+
|
|
30
45
|
return positions
|
|
31
46
|
}
|
|
32
47
|
|
|
48
|
+
export function runPreservingScroll(container, fn) {
|
|
49
|
+
const scrollPositions = captureScrollPositions(container)
|
|
50
|
+
try {
|
|
51
|
+
return fn()
|
|
52
|
+
} finally {
|
|
53
|
+
restoreScrollPositions(scrollPositions)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
33
57
|
export function restoreScrollPositions(positions) {
|
|
34
58
|
if (!positions.length) return
|
|
35
59
|
const apply = () => {
|
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
//@ts-ignore
|
|
9
9
|
import { components, initVxeTableInPage } from 'adtec-core-package/src/config/VxeTableConfig'
|
|
10
|
-
// 导入默认的语言
|
|
11
10
|
import { defineComponent, getCurrentInstance, h } from 'vue'
|
|
11
|
+
|
|
12
12
|
const { VxeGrid } = components
|
|
13
13
|
defineComponent({
|
|
14
14
|
components: {
|
|
15
15
|
VxeGrid,
|
|
16
16
|
},
|
|
17
17
|
})
|
|
18
|
+
|
|
18
19
|
const { renderComponent = { enableElementPlus: true, enableExcel: false, enablePdf: false } } =
|
|
19
20
|
defineProps<{
|
|
20
21
|
renderComponent?: {
|
|
@@ -24,12 +25,18 @@ const { renderComponent = { enableElementPlus: true, enableExcel: false, enableP
|
|
|
24
25
|
}
|
|
25
26
|
}>()
|
|
26
27
|
|
|
27
|
-
initVxeTableInPage(
|
|
28
|
+
initVxeTableInPage(
|
|
29
|
+
renderComponent.enableExcel,
|
|
30
|
+
renderComponent.enablePdf,
|
|
31
|
+
renderComponent.enableElementPlus ?? true,
|
|
32
|
+
)
|
|
28
33
|
|
|
29
34
|
const vm = getCurrentInstance()
|
|
30
35
|
|
|
31
|
-
const changeRef = (exposed:
|
|
32
|
-
|
|
36
|
+
const changeRef = (exposed: unknown) => {
|
|
37
|
+
if (vm) {
|
|
38
|
+
vm.exposed = exposed
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
</script>
|
|
35
42
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElMessage } from 'element-plus'
|
|
2
|
+
import { ref } from 'vue'
|
|
2
3
|
import SysDictCacheApi from '../api/SysDictCacheApi'
|
|
3
4
|
import type { ISysDictDataCacheVo } from '../interface/ISysDictDataCacheVo'
|
|
4
5
|
import { type dictDataMapVoType, dictStore } from '../stores/dictStore'
|
|
@@ -46,6 +47,7 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
|
|
|
46
47
|
ElMessage.error(`处理键 ${Object.keys(data)[index]} 时出错:`, result.reason)
|
|
47
48
|
}
|
|
48
49
|
})
|
|
50
|
+
dictStores.publishToSharedCache()
|
|
49
51
|
} catch (error: any) {
|
|
50
52
|
frameworkUtils.messageError(error)
|
|
51
53
|
}
|
|
@@ -114,10 +116,16 @@ export default function useDictHooks(dictTypes?: string[], orgId?: string) {
|
|
|
114
116
|
const clearDict = (dictType?: string[], orgId?: string, all?: Boolean) => {
|
|
115
117
|
clearDictCache(dictType, userInfo.getUserInfo.orgId, orgId, all)
|
|
116
118
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
/** 构造函数传入的 dictTypes 是否已全部加载(缓存命中也会立即置 true) */
|
|
120
|
+
const dictReady = ref(!dictTypes?.length)
|
|
121
|
+
if (dictTypes?.length) {
|
|
122
|
+
getDict(dictTypes, orgId).finally(() => {
|
|
123
|
+
dictReady.value = true
|
|
124
|
+
})
|
|
125
|
+
}
|
|
119
126
|
return {
|
|
120
127
|
getDict,
|
|
128
|
+
dictReady,
|
|
121
129
|
getDictName,
|
|
122
130
|
getDictData,
|
|
123
131
|
getDictTypeData,
|
package/src/stores/dictStore.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { defineStore } from 'pinia'
|
|
2
|
-
import { ref } from 'vue'
|
|
2
|
+
import { ref, type Ref } from 'vue'
|
|
3
|
+
import Base64 from 'crypto-js/enc-base64'
|
|
4
|
+
import Utf8 from 'crypto-js/enc-utf8'
|
|
3
5
|
import type { ISysDictDataCacheVo } from '../interface/ISysDictDataCacheVo'
|
|
6
|
+
|
|
4
7
|
// 定义包含map的整体类型
|
|
5
8
|
export interface dictMapType {
|
|
6
9
|
[key: string]: ISysDictDataCacheVo[]
|
|
@@ -14,12 +17,168 @@ export interface dictDataMapType {
|
|
|
14
17
|
[key: string]: { [key: string]: ISysDictDataCacheVo }
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
const DICT_STORAGE_KEY = 'dictStore'
|
|
21
|
+
const DICT_CACHE_UPDATE_EVENT = 'adtec-dict-cache-update'
|
|
22
|
+
|
|
23
|
+
/** 跨应用共享的 plain 缓存(非 Vue ref,避免 wujie 子应用与宿主 ref 响应式隔离) */
|
|
24
|
+
export interface SharedDictCache {
|
|
25
|
+
dictMap: dictMapType
|
|
26
|
+
dictDataMap: dictDataMapType
|
|
27
|
+
dictDefaultValueMap: dictMapType
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare global {
|
|
31
|
+
interface Window {
|
|
32
|
+
__ADTEC_SHARED_DICT_CACHE__?: SharedDictCache
|
|
33
|
+
/** @deprecated 3.0.7 起改用 __ADTEC_SHARED_DICT_CACHE__ */
|
|
34
|
+
__ADTEC_SHARED_DICT__?: {
|
|
35
|
+
dictMap: Ref<dictMapType>
|
|
36
|
+
dictDataMap: Ref<dictDataMapType>
|
|
37
|
+
dictDefaultValueMap: Ref<dictMapType>
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** wujie 子应用走 parent,宿主/独立 dev 走自身 window */
|
|
43
|
+
function getRootWindow(): Window {
|
|
44
|
+
if (typeof window === 'undefined') return window
|
|
45
|
+
const w = window as Window & { __POWERED_BY_WUJIE__?: boolean }
|
|
46
|
+
return w.__POWERED_BY_WUJIE__ ? window.parent : window
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hydrateCacheFromSessionStorage(cache: SharedDictCache) {
|
|
50
|
+
const raw = sessionStorage.getItem(DICT_STORAGE_KEY)
|
|
51
|
+
if (!raw) return
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(Base64.parse(raw).toString(Utf8)) as {
|
|
54
|
+
dictMap?: dictMapType
|
|
55
|
+
dictDataMap?: dictDataMapType
|
|
56
|
+
dictDefaultValueMap?: dictMapType
|
|
57
|
+
}
|
|
58
|
+
if (parsed.dictMap) {
|
|
59
|
+
Object.assign(cache.dictMap, parsed.dictMap)
|
|
60
|
+
}
|
|
61
|
+
if (parsed.dictDataMap) {
|
|
62
|
+
mergeDictDataMap(cache.dictDataMap, parsed.dictDataMap)
|
|
63
|
+
}
|
|
64
|
+
if (parsed.dictDefaultValueMap) {
|
|
65
|
+
Object.assign(cache.dictDefaultValueMap, parsed.dictDefaultValueMap)
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
// ignore corrupt session data
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function persistCacheToSessionStorage(cache: SharedDictCache) {
|
|
73
|
+
if (typeof sessionStorage === 'undefined') return
|
|
74
|
+
try {
|
|
75
|
+
const payload = JSON.stringify({
|
|
76
|
+
dictMap: cache.dictMap,
|
|
77
|
+
dictDataMap: cache.dictDataMap,
|
|
78
|
+
dictDefaultValueMap: cache.dictDefaultValueMap,
|
|
79
|
+
})
|
|
80
|
+
sessionStorage.setItem(DICT_STORAGE_KEY, Base64.stringify(Utf8.parse(payload)))
|
|
81
|
+
} catch {
|
|
82
|
+
// ignore quota / privacy errors
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function mergeDictDataMap(target: dictDataMapType, source: dictDataMapType) {
|
|
87
|
+
Object.keys(source).forEach((key) => {
|
|
88
|
+
target[key] = { ...target[key], ...source[key] }
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function cloneDictDataMap(source: dictDataMapType): dictDataMapType {
|
|
93
|
+
const clone: dictDataMapType = {}
|
|
94
|
+
mergeDictDataMap(clone, source)
|
|
95
|
+
return clone
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** 宿主 window 单例 plain 缓存:alive 子应用与宿主共享数据,但不共享 Vue ref */
|
|
99
|
+
export function getSharedDictCache(): SharedDictCache {
|
|
100
|
+
const root = getRootWindow()
|
|
101
|
+
if (!root.__ADTEC_SHARED_DICT_CACHE__) {
|
|
102
|
+
root.__ADTEC_SHARED_DICT_CACHE__ = {
|
|
103
|
+
dictMap: {},
|
|
104
|
+
dictDataMap: {},
|
|
105
|
+
dictDefaultValueMap: {},
|
|
106
|
+
}
|
|
107
|
+
hydrateCacheFromSessionStorage(root.__ADTEC_SHARED_DICT_CACHE__)
|
|
108
|
+
}
|
|
109
|
+
return root.__ADTEC_SHARED_DICT_CACHE__
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function broadcastDictCacheUpdate() {
|
|
113
|
+
if (typeof window === 'undefined') return
|
|
114
|
+
const event = new CustomEvent(DICT_CACHE_UPDATE_EVENT)
|
|
115
|
+
window.dispatchEvent(event)
|
|
116
|
+
const root = getRootWindow()
|
|
117
|
+
if (root !== window) {
|
|
118
|
+
try {
|
|
119
|
+
root.dispatchEvent(new CustomEvent(DICT_CACHE_UPDATE_EVENT))
|
|
120
|
+
} catch {
|
|
121
|
+
// cross-origin parent
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** @deprecated 3.0.7 起请使用 getSharedDictCache */
|
|
127
|
+
export function getSharedDictRefs() {
|
|
128
|
+
return getSharedDictCache() as unknown as {
|
|
129
|
+
dictMap: Ref<dictMapType>
|
|
130
|
+
dictDataMap: Ref<dictDataMapType>
|
|
131
|
+
dictDefaultValueMap: Ref<dictMapType>
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** @deprecated 已由 getSharedDictCache 在初始化时 hydrate */
|
|
136
|
+
export function syncDictFromSessionStorage(_target?: unknown) {
|
|
137
|
+
hydrateCacheFromSessionStorage(getSharedDictCache())
|
|
138
|
+
}
|
|
139
|
+
|
|
17
140
|
export const dictStore = defineStore('dictStore', () => {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
141
|
+
const sharedCache = getSharedDictCache()
|
|
142
|
+
|
|
143
|
+
/** 当前应用 Pinia 内的 ref,保证与本应用 Vue 响应式连通 */
|
|
144
|
+
const dictMap = ref<dictMapType>({ ...sharedCache.dictMap })
|
|
145
|
+
const dictDataMap = ref<dictDataMapType>(cloneDictDataMap(sharedCache.dictDataMap))
|
|
146
|
+
const dictDefaultValueMap = ref<dictMapType>({ ...sharedCache.dictDefaultValueMap })
|
|
147
|
+
|
|
148
|
+
const syncFromSharedCache = () => {
|
|
149
|
+
dictMap.value = { ...dictMap.value, ...sharedCache.dictMap }
|
|
150
|
+
mergeDictDataMap(dictDataMap.value, sharedCache.dictDataMap)
|
|
151
|
+
dictDefaultValueMap.value = { ...dictDefaultValueMap.value, ...sharedCache.dictDefaultValueMap }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const publishToSharedCache = () => {
|
|
155
|
+
Object.assign(sharedCache.dictMap, dictMap.value)
|
|
156
|
+
mergeDictDataMap(sharedCache.dictDataMap, dictDataMap.value)
|
|
157
|
+
Object.assign(sharedCache.dictDefaultValueMap, dictDefaultValueMap.value)
|
|
158
|
+
persistCacheToSessionStorage(sharedCache)
|
|
159
|
+
broadcastDictCacheUpdate()
|
|
160
|
+
}
|
|
21
161
|
|
|
22
|
-
|
|
162
|
+
if (typeof window !== 'undefined') {
|
|
163
|
+
window.addEventListener(DICT_CACHE_UPDATE_EVENT, syncFromSharedCache)
|
|
164
|
+
const root = getRootWindow()
|
|
165
|
+
if (root !== window) {
|
|
166
|
+
try {
|
|
167
|
+
root.addEventListener(DICT_CACHE_UPDATE_EVENT, syncFromSharedCache)
|
|
168
|
+
} catch {
|
|
169
|
+
// cross-origin parent
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
syncFromSharedCache()
|
|
175
|
+
|
|
176
|
+
const clearDictCache = (
|
|
177
|
+
dictType?: string[],
|
|
178
|
+
userOrgId?: string,
|
|
179
|
+
orgId?: string,
|
|
180
|
+
all?: Boolean,
|
|
181
|
+
) => {
|
|
23
182
|
if (dictType && dictType.length > 0) {
|
|
24
183
|
dictType.forEach((item) => {
|
|
25
184
|
if (orgId) {
|
|
@@ -27,6 +186,9 @@ export const dictStore = defineStore('dictStore', () => {
|
|
|
27
186
|
delete dictMap.value[key]
|
|
28
187
|
delete dictDataMap.value[key]
|
|
29
188
|
delete dictDefaultValueMap.value[key]
|
|
189
|
+
delete sharedCache.dictMap[key]
|
|
190
|
+
delete sharedCache.dictDataMap[key]
|
|
191
|
+
delete sharedCache.dictDefaultValueMap[key]
|
|
30
192
|
} else {
|
|
31
193
|
delete dictMap.value[item]
|
|
32
194
|
delete dictDataMap.value[item]
|
|
@@ -34,18 +196,32 @@ export const dictStore = defineStore('dictStore', () => {
|
|
|
34
196
|
delete dictMap.value[`${userOrgId}:${item}`]
|
|
35
197
|
delete dictDataMap.value[`${userOrgId}:${item}`]
|
|
36
198
|
delete dictDefaultValueMap.value[`${userOrgId}:${item}`]
|
|
199
|
+
delete sharedCache.dictMap[item]
|
|
200
|
+
delete sharedCache.dictDataMap[item]
|
|
201
|
+
delete sharedCache.dictDefaultValueMap[item]
|
|
202
|
+
delete sharedCache.dictMap[`${userOrgId}:${item}`]
|
|
203
|
+
delete sharedCache.dictDataMap[`${userOrgId}:${item}`]
|
|
204
|
+
delete sharedCache.dictDefaultValueMap[`${userOrgId}:${item}`]
|
|
37
205
|
}
|
|
38
206
|
})
|
|
207
|
+
publishToSharedCache()
|
|
39
208
|
} else if (all) {
|
|
40
209
|
dictMap.value = {}
|
|
41
210
|
dictDataMap.value = {}
|
|
42
211
|
dictDefaultValueMap.value = {}
|
|
212
|
+
sharedCache.dictMap = {}
|
|
213
|
+
sharedCache.dictDataMap = {}
|
|
214
|
+
sharedCache.dictDefaultValueMap = {}
|
|
215
|
+
publishToSharedCache()
|
|
43
216
|
}
|
|
44
217
|
}
|
|
218
|
+
|
|
45
219
|
return {
|
|
46
220
|
dictMap,
|
|
47
221
|
dictDataMap,
|
|
48
222
|
dictDefaultValueMap,
|
|
49
223
|
clearDictCache,
|
|
224
|
+
syncFromSharedCache,
|
|
225
|
+
publishToSharedCache,
|
|
50
226
|
}
|
|
51
227
|
})
|