@epxing/core 5.3.0-beta.2 → 5.3.0-beta.4
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/API.md +715 -714
- package/README.md +3 -1
- package/dist/.cache/route-chart-release/frontend/frame/public/js/ecStat.min.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts-wordcloud.min.js +6 -0
- package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts.min.js +49 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
- package/dist/_virtual/jsencrypt.min.js +1 -1
- package/dist/assets/role_select-DTqRlFNz.webp +0 -0
- package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/jsencrypt@3.5.4/_vendor/jsencrypt/bin/jsencrypt.min.js +1 -1
- package/dist/src/RootApp.js +54 -0
- package/dist/src/api/createHttp.js +6 -0
- package/dist/src/app-ui-settings.js +49 -0
- package/dist/src/axios.js +10 -15
- package/dist/src/chart-runtime-assets.js +19 -0
- package/dist/src/chart-runtime-sources.js +8 -0
- package/dist/src/create-app.js +3 -6
- package/dist/src/index.js +2 -0
- package/dist/src/loadComponent.js +2 -2
- package/dist/src/menu-route.js +11 -0
- package/dist/src/mixins/component.js +3 -0
- package/dist/src/navigation-context.js +47 -0
- package/dist/src/navigation.js +43 -12
- package/dist/src/package-install.js +3 -2
- package/dist/src/plugins/element-plus.js +8 -8
- package/dist/src/public-api.js +4 -2
- package/dist/src/route-components.js +9 -0
- package/dist/src/router/config.js +7 -8
- package/dist/src/runtime-services.js +1 -1
- package/dist/src/runtime-utils/meta.js +3 -0
- package/dist/src/runtime-utils/pdf.viewer.js +31 -15
- package/dist/src/runtime-utils/util.js +28 -5
- package/dist/src/shared-packages.js +1 -3
- package/dist/src/store/modules/list.js +25 -3
- package/dist/src/store/modules/meta.js +49 -7
- package/dist/src/style-presets.js +4 -4
- package/dist/src/ui-settings.js +90 -18
- package/dist/src/views/App.js +48 -0
- package/dist/src/views/AppRoleSelect.js +233 -0
- package/dist/src/views/Error.js +210 -0
- package/dist/src/views/Module.js +173 -0
- package/dist/style.css +251 -0
- package/package.json +4 -4
- package/src/RootApp.vue +75 -0
- package/src/api/createHttp.js +7 -0
- package/src/api/index.js +47 -47
- package/src/app-ui-settings.js +31 -0
- package/src/axios.js +311 -318
- package/src/chart-runtime-assets.js +13 -0
- package/src/chart-runtime-sources.js +5 -0
- package/src/create-app.js +3 -7
- package/src/index.js +28 -28
- package/src/install.js +157 -157
- package/src/loadComponent.js +187 -187
- package/src/loadLibrary.js +99 -99
- package/src/menu-route.js +12 -1
- package/src/mixins/component.js +1464 -1461
- package/src/navigation-context.js +49 -0
- package/src/navigation.js +208 -176
- package/src/package-install.js +2 -1
- package/src/plugins/element-plus.js +302 -302
- package/src/plugins/frame.js +178 -178
- package/src/public-api.js +1 -0
- package/src/route-components.js +7 -0
- package/src/router/config.js +861 -864
- package/src/router/public.js +1 -1
- package/src/runtime-services.js +1 -1
- package/src/runtime-utils/fieldFactory.js +179 -179
- package/src/runtime-utils/meta.js +399 -378
- package/src/runtime-utils/pdf.viewer.js +672 -644
- package/src/runtime-utils/util.js +1359 -1330
- package/src/shared-packages.js +1 -3
- package/src/store/modules/config.js +351 -351
- package/src/store/modules/list.js +30 -3
- package/src/store/modules/locale.js +236 -236
- package/src/store/modules/meta.js +314 -265
- package/src/style-presets.js +4 -4
- package/src/ui-settings.js +84 -23
- package/src/views/App.vue +53 -0
- package/src/views/AppRoleSelect.vue +334 -0
- package/src/views/Error.vue +63 -0
- package/src/views/Module.vue +210 -0
- package/src/xss.js +26 -26
- package/types/app.d.ts +10 -10
- package/types/axios.d.ts +1 -1
- package/types/component-mixin.d.ts +1 -1
- package/types/field-factory.d.ts +1 -1
- package/types/global-mixin.d.ts +1 -1
- package/types/http.d.ts +1 -1
- package/types/index.d.ts +3 -0
- package/types/meta.d.ts +1 -1
- package/types/navigation.d.ts +21 -21
- package/types/pdf-viewer.d.ts +1 -1
- package/types/runtime.d.ts +13 -13
- package/types/store.d.ts +1 -1
- package/types/util.d.ts +2 -2
- /package/dist/{build → .cache/route-chart-release/frontend/frame/build}/stubs/empty-components.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-icons.names.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-plus.lazy.js +0 -0
- /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/en.js +0 -0
- /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/zh-cn.js +0 -0
|
@@ -1,265 +1,314 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 获取页面配置
|
|
3
|
-
*/
|
|
4
|
-
import { markRaw } from 'vue'
|
|
5
|
-
import http from '@epxing/core/src/api'
|
|
6
|
-
import Meta from '@epxing/core/src/runtime-utils/meta'
|
|
7
|
-
import { ADD_META } from '@epxing/core/src/store/actions'
|
|
8
|
-
import { prune, touch, touchKeys } from '@epxing/core/src/store/lru'
|
|
9
|
-
const ADD_SIMPLE_META = 'ADD_SIMPLE_META'
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
data
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 获取页面配置
|
|
3
|
+
*/
|
|
4
|
+
import { markRaw, reactive, toRaw } from 'vue'
|
|
5
|
+
import http from '@epxing/core/src/api'
|
|
6
|
+
import Meta from '@epxing/core/src/runtime-utils/meta'
|
|
7
|
+
import { ADD_META } from '@epxing/core/src/store/actions'
|
|
8
|
+
import { prune, touch, touchKeys } from '@epxing/core/src/store/lru'
|
|
9
|
+
const ADD_SIMPLE_META = 'ADD_SIMPLE_META'
|
|
10
|
+
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
11
|
+
// 缓存逐 key 更新,getter 从当前 store 的 state 读取,兼容独立 store 和状态替换。
|
|
12
|
+
const metas = reactive({})
|
|
13
|
+
// 别名 → 存储 key:同一对象可按 id / code / code@system@client 三种写法读取
|
|
14
|
+
const metaAliases = new WeakMap()
|
|
15
|
+
const aliasesOf = (state) => {
|
|
16
|
+
const cache = toRaw(state.metas)
|
|
17
|
+
if (!metaAliases.has(cache)) metaAliases.set(cache, {})
|
|
18
|
+
return metaAliases.get(cache)
|
|
19
|
+
}
|
|
20
|
+
// 每个 key 一个响应式信号,读取方只订阅自己的 key;元数据到达时只通知它
|
|
21
|
+
const metaSignals = new Map()
|
|
22
|
+
const signalOf = (key) => {
|
|
23
|
+
let signal = metaSignals.get(key)
|
|
24
|
+
if (!signal) {
|
|
25
|
+
signal = reactive({ version: 0 })
|
|
26
|
+
metaSignals.set(key, signal)
|
|
27
|
+
}
|
|
28
|
+
return signal
|
|
29
|
+
}
|
|
30
|
+
const notifyMeta = (key) => {
|
|
31
|
+
const signal = metaSignals.get(key)
|
|
32
|
+
if (signal) signal.version++
|
|
33
|
+
}
|
|
34
|
+
const ADD_META_RELATION_FIELDS = 'ADD_META_RELATION_FIELDS'
|
|
35
|
+
const ADD_META_VIEW_FIELDS = 'ADD_META_VIEW_FIELDS'
|
|
36
|
+
// 缓存容量:soft 是常态上限,hard 是极端场景兜底;正在使用的对象不会被淘汰,详见 @epxing/core/src/store/lru
|
|
37
|
+
// 单个对象元数据实测约 110KB 堆(已在 @epxing/utils/src/meta 里冻结只读容器;不冻结时是 2.9MB),
|
|
38
|
+
// 所以 metas 常态 50 个约 5MB、最坏 200 个约 22MB
|
|
39
|
+
const LIMITS = {
|
|
40
|
+
metas: { soft: 50, hard: 200 },
|
|
41
|
+
metaRelationFields: { soft: 50, hard: 120 },
|
|
42
|
+
metaViewFields: { soft: 50, hard: 200 }
|
|
43
|
+
}
|
|
44
|
+
// 按条件在 metas 里查找,命中的同时记录一次使用
|
|
45
|
+
const findMeta = (metas, matcher) => {
|
|
46
|
+
for (const key in metas) {
|
|
47
|
+
const item = metas[key]
|
|
48
|
+
if (item && matcher(item)) {
|
|
49
|
+
touch('metas', key)
|
|
50
|
+
return item
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
const formatFields = (arr, flag = '') => {
|
|
56
|
+
arr.forEach(item => {
|
|
57
|
+
if (!item.field) item.field = flag ? flag.toUpperCase() + '|' + item.code : item.code
|
|
58
|
+
if (!item.codeKey) item.codeKey = item.relatedEntity
|
|
59
|
+
if (item.relationMeta) {
|
|
60
|
+
const { children, linkFlag, relationMetaList, id, text } = item.relationMeta
|
|
61
|
+
item.children = children.map(child => ({ ...child, meta: id, metaLabel: text }))
|
|
62
|
+
item.linkFlag = flag ? flag + '|' + linkFlag : linkFlag
|
|
63
|
+
if (relationMetaList) {
|
|
64
|
+
relationMetaList.forEach(meta => {
|
|
65
|
+
meta.isSub = true
|
|
66
|
+
meta.type = 'meta'
|
|
67
|
+
meta.linkFlag = item.linkFlag + '|' + meta.linkFlag
|
|
68
|
+
meta.field = meta.linkFlag
|
|
69
|
+
meta.children = meta.children.map(child => ({ ...child, meta: meta.id, metaLabel: meta.text, relationSort: meta.relationType }))
|
|
70
|
+
})
|
|
71
|
+
item.children.push(...relationMetaList)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (item.children) formatFields(item.children, item.linkFlag)
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default {
|
|
79
|
+
state: {
|
|
80
|
+
metas,
|
|
81
|
+
simpleMetas: {},
|
|
82
|
+
metaStatus: {},
|
|
83
|
+
simpleMetaStatus: {},
|
|
84
|
+
metaRelationFields: {},
|
|
85
|
+
metaRelationFieldStatus: {},
|
|
86
|
+
metaViewFields: {},
|
|
87
|
+
metaViewFieldStatus: {}
|
|
88
|
+
|
|
89
|
+
},
|
|
90
|
+
mutations: {
|
|
91
|
+
// 逐 key 写入并只通知该 key(及其别名)的信号,不整体替换 metas
|
|
92
|
+
[ADD_META] (state, data) {
|
|
93
|
+
touchKeys('metas', Object.keys(data))
|
|
94
|
+
const metaAlias = aliasesOf(state)
|
|
95
|
+
for (const key in data) {
|
|
96
|
+
const meta = data[key]
|
|
97
|
+
state.metas[key] = meta
|
|
98
|
+
const aliases = [meta.id, meta.code, `${meta.code}@${meta.systemCode}@${meta.clientCode}`]
|
|
99
|
+
aliases.forEach(alias => {
|
|
100
|
+
if (alias && alias !== key) metaAlias[alias] = key
|
|
101
|
+
})
|
|
102
|
+
notifyMeta(key)
|
|
103
|
+
aliases.forEach(notifyMeta)
|
|
104
|
+
}
|
|
105
|
+
// 容量淘汰:先在副本上算出保留集合,再原地删除被淘汰的 key(保护期内正在用的不会被淘汰)
|
|
106
|
+
const keep = prune('metas', { ...state.metas }, LIMITS.metas)
|
|
107
|
+
for (const key in state.metas) {
|
|
108
|
+
if (!hasOwn(keep, key)) delete state.metas[key]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
[ADD_SIMPLE_META] (state, data) {
|
|
112
|
+
state.simpleMetas = { ...state.simpleMetas, ...data }
|
|
113
|
+
},
|
|
114
|
+
[ADD_META_RELATION_FIELDS] (state, data) {
|
|
115
|
+
touchKeys('metaRelationFields', Object.keys(data))
|
|
116
|
+
state.metaRelationFields = prune('metaRelationFields', { ...state.metaRelationFields, ...data }, LIMITS.metaRelationFields)
|
|
117
|
+
},
|
|
118
|
+
[ADD_META_VIEW_FIELDS] (state, data) {
|
|
119
|
+
touchKeys('metaViewFields', Object.keys(data))
|
|
120
|
+
state.metaViewFields = prune('metaViewFields', { ...state.metaViewFields, ...data }, LIMITS.metaViewFields)
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
getters: {
|
|
124
|
+
getMetaById: (state) => (id) => {
|
|
125
|
+
// eslint-disable-next-line no-unused-expressions
|
|
126
|
+
signalOf(id).version
|
|
127
|
+
const meta = state.metas[id]
|
|
128
|
+
if (meta) touch('metas', id)
|
|
129
|
+
return meta
|
|
130
|
+
},
|
|
131
|
+
getMeta: (state) => (id) => {
|
|
132
|
+
if (!id) return undefined
|
|
133
|
+
// 只订阅这一个 key 的信号,其它元数据的到达不会触发本组件重渲染
|
|
134
|
+
// eslint-disable-next-line no-unused-expressions
|
|
135
|
+
signalOf(id).version
|
|
136
|
+
const key = hasOwn(state.metas, id) ? id : aliasesOf(state)[id]
|
|
137
|
+
const meta = key ? state.metas[key] : undefined
|
|
138
|
+
if (meta) touch('metas', key)
|
|
139
|
+
return meta
|
|
140
|
+
},
|
|
141
|
+
getSimpleMeta: (state) => (id) => {
|
|
142
|
+
return state.simpleMetas[id] || findMeta(state.metas, item => (item.id === id || item.code === id))
|
|
143
|
+
},
|
|
144
|
+
getMetaRelationFields: (state) => (id) => {
|
|
145
|
+
const fields = state.metaRelationFields[id]
|
|
146
|
+
if (fields) touch('metaRelationFields', id)
|
|
147
|
+
return fields
|
|
148
|
+
},
|
|
149
|
+
getMetaViewFields: (state) => (metaId, viewId) => {
|
|
150
|
+
const key = metaId + (viewId || '')
|
|
151
|
+
const fields = state.metaViewFields[key]
|
|
152
|
+
if (fields) touch('metaViewFields', key)
|
|
153
|
+
return fields
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
actions: {
|
|
157
|
+
[ADD_META] ({ state, commit }, payload = {}) {
|
|
158
|
+
const { [payload.metaId]: metaPromise } = state.metaStatus
|
|
159
|
+
if (metaPromise) return metaPromise
|
|
160
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
161
|
+
const promise = new Promise((resolve, reject) => {
|
|
162
|
+
if (!payload.metaId) {
|
|
163
|
+
// 这条路径**不写在飞标记**(见函数末尾的 if 守卫):原来会以 undefined 为键把这个已 reject
|
|
164
|
+
// 的 promise 存进 metaStatus,之后每次不带 metaId 的调用都命中开头的缓存判断、拿到它。
|
|
165
|
+
reject(new Error('ADD_META 缺少 metaId'))
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
http.getMeta({
|
|
169
|
+
metaId: payload.metaId.includes('@system@') ? payload.metaId.split('@')[0] : payload.metaId
|
|
170
|
+
})
|
|
171
|
+
.then(data => {
|
|
172
|
+
if (!data) {
|
|
173
|
+
// ⚠️ 这是「后端 200 但 data 为空」,**不会**走下面的 .catch —— 在 .then 里调 reject
|
|
174
|
+
// 只让外层 promise 变成 rejected,同一条链的 catch 不会被触发。
|
|
175
|
+
// 漏删在飞标记的后果不是多发一次请求,而是**本次会话再也加载不出这个对象**:
|
|
176
|
+
// action 开头的 `if (metaPromise) return metaPromise` 会一直返回这个已 reject 的
|
|
177
|
+
// promise,表现为静默失败,且**没有任何重试能恢复**,直到用户整页刷新。
|
|
178
|
+
delete state.metaStatus[payload.metaId]
|
|
179
|
+
reject(new Error(`ADD_META 后端返回空数据:metaId=${payload.metaId}`))
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
// markRaw:对象元数据(attributes/relations 大且只读、加载后不变)不做响应式,省深层 Proxy
|
|
183
|
+
// 的内存与每次字段访问的 get/set 开销;元数据从不被响应式修改(见本模块只读+LRU 删除),安全。
|
|
184
|
+
const meta = markRaw(new Meta(data))
|
|
185
|
+
commit(ADD_META, { [payload.metaId]: meta })
|
|
186
|
+
delete state.metaStatus[payload.metaId]
|
|
187
|
+
resolve(meta)
|
|
188
|
+
})
|
|
189
|
+
.catch(err => {
|
|
190
|
+
delete state.metaStatus[payload.metaId]
|
|
191
|
+
reject(err)
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
if (payload.metaId) state.metaStatus = { ...state.metaStatus, [payload.metaId]: promise }
|
|
195
|
+
return promise
|
|
196
|
+
},
|
|
197
|
+
[ADD_SIMPLE_META] ({ state, commit }, payload = {}) {
|
|
198
|
+
const { [payload.metaId]: metaPromise } = state.simpleMetaStatus
|
|
199
|
+
if (metaPromise) return metaPromise
|
|
200
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
201
|
+
const promise = new Promise((resolve, reject) => {
|
|
202
|
+
if (!payload.metaId) {
|
|
203
|
+
// 同 ADD_META:不写在飞标记,否则 undefined 键会把已 reject 的 promise 永久缓存下来。
|
|
204
|
+
reject(new Error('ADD_SIMPLE_META 缺少 metaId'))
|
|
205
|
+
return
|
|
206
|
+
}
|
|
207
|
+
http.getSimpleMeta({
|
|
208
|
+
metaId: payload.metaId
|
|
209
|
+
})
|
|
210
|
+
.then(data => {
|
|
211
|
+
if (!data) {
|
|
212
|
+
// 与 ADD_META 同一个坑:这条分支不走 .catch,漏删在飞标记会让该 metaId 本次会话永久失败。
|
|
213
|
+
delete state.simpleMetaStatus[payload.metaId]
|
|
214
|
+
reject(new Error(`ADD_SIMPLE_META 后端返回空数据:metaId=${payload.metaId}`))
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
commit(ADD_SIMPLE_META, { [payload.metaId]: markRaw(data) }) // 只读元数据,去响应式
|
|
218
|
+
delete state.simpleMetaStatus[payload.metaId]
|
|
219
|
+
// 原来这里 resolve 之后**没有 return**,成功路径也会继续走到下面的 reject(new Error())。
|
|
220
|
+
// promise 已 settle 所以状态上看不出来,但每次成功都白构造一个 Error,
|
|
221
|
+
// 更要紧的是这行让「成功」和「空数据」两条路径纠缠在一起,掩盖了上面那个漏删。
|
|
222
|
+
resolve(data)
|
|
223
|
+
})
|
|
224
|
+
.catch(err => {
|
|
225
|
+
delete state.simpleMetaStatus[payload.metaId]
|
|
226
|
+
reject(err)
|
|
227
|
+
})
|
|
228
|
+
})
|
|
229
|
+
if (payload.metaId) state.simpleMetaStatus = { ...state.simpleMetaStatus, [payload.metaId]: promise }
|
|
230
|
+
return promise
|
|
231
|
+
},
|
|
232
|
+
[ADD_META_RELATION_FIELDS] ({ state, commit }, payload = {}) {
|
|
233
|
+
const { [payload.id]: metaPromise } = state.metaRelationFieldStatus
|
|
234
|
+
if (metaPromise) return metaPromise
|
|
235
|
+
const promise = http.get({
|
|
236
|
+
action: 'metaRelationTree',
|
|
237
|
+
entityId: 'FM_ENTITY',
|
|
238
|
+
metaId: payload.id,
|
|
239
|
+
allSub: true
|
|
240
|
+
})
|
|
241
|
+
.then(data => {
|
|
242
|
+
// data 为空时原来既不删在飞标记也不 reject ⇒ 永久缓存一个 resolve 成 undefined 的 promise,
|
|
243
|
+
// 后续所有调用都直接拿到 undefined。这里只补清理、保持「resolve undefined」的既有语义
|
|
244
|
+
// (改成 reject 会波及 88 处 dispatch 的错误处理,不在本次修复范围内)。
|
|
245
|
+
if (!data) {
|
|
246
|
+
delete state.metaRelationFieldStatus[payload.id]
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
data.children = data.children.map(item => ({ ...item, meta: data.id }))
|
|
250
|
+
if (data.relationMetaList) {
|
|
251
|
+
data.relationMetaList.forEach(meta => {
|
|
252
|
+
meta.isSub = true
|
|
253
|
+
meta.type = 'meta'
|
|
254
|
+
meta.isMeta = true
|
|
255
|
+
meta.field = meta.linkFlag
|
|
256
|
+
meta.children = meta.children.map(child => ({ ...child, relationSort: meta.relationType, meta: meta.id, field: meta.linkFlag.toUpperCase() + '|' + child.code }))
|
|
257
|
+
})
|
|
258
|
+
data.children.push(...data.relationMetaList)
|
|
259
|
+
}
|
|
260
|
+
data.isMain = true
|
|
261
|
+
data.isUnFold = true
|
|
262
|
+
const fields = [data]
|
|
263
|
+
formatFields(fields)
|
|
264
|
+
commit(ADD_META_RELATION_FIELDS, { [payload.id]: markRaw(fields) }) // 只读关联字段树,去响应式
|
|
265
|
+
delete state.metaRelationFieldStatus[payload.id]
|
|
266
|
+
return fields
|
|
267
|
+
})
|
|
268
|
+
.catch(() => {
|
|
269
|
+
delete state.metaRelationFieldStatus[payload.id]
|
|
270
|
+
})
|
|
271
|
+
state.metaRelationFieldStatus = { ...state.metaRelationFieldStatus, [payload.id]: promise }
|
|
272
|
+
return promise
|
|
273
|
+
},
|
|
274
|
+
[ADD_META_VIEW_FIELDS] ({ state, commit }, payload = {}) {
|
|
275
|
+
const key = payload.metaId + (payload.viewId || '')
|
|
276
|
+
const { [key]: metaPromise } = state.metaViewFieldStatus
|
|
277
|
+
if (metaPromise) return metaPromise
|
|
278
|
+
const promise = http.get({
|
|
279
|
+
action: 'getEntityMetaView',
|
|
280
|
+
entityId: 'FM_ENTITY_VIEW',
|
|
281
|
+
metaId: payload.metaId,
|
|
282
|
+
metaViewId: payload.viewId,
|
|
283
|
+
allSub: true
|
|
284
|
+
})
|
|
285
|
+
.then(data => {
|
|
286
|
+
// 同 ADD_META_RELATION_FIELDS:补上空数据时的在飞标记清理,语义保持不变。
|
|
287
|
+
if (!data) {
|
|
288
|
+
delete state.metaViewFieldStatus[key]
|
|
289
|
+
return
|
|
290
|
+
}
|
|
291
|
+
data[0].isMain = true
|
|
292
|
+
const formatData = (arr) => {
|
|
293
|
+
return arr.filter(item => !!item).map(item => {
|
|
294
|
+
item.field = item.type === 'meta' ? item.linkFlag || item.code : item.linkCode || item.code
|
|
295
|
+
item.relationSort = item.relationType
|
|
296
|
+
if (!item.codeKey) item.codeKey = item.relatedEntity
|
|
297
|
+
if (item.type === 'meta' && item.relationType === '1') item.isSub = true
|
|
298
|
+
if (item.children) item.children = formatData(item.children)
|
|
299
|
+
return item
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
const newData = formatData(data)
|
|
303
|
+
commit(ADD_META_VIEW_FIELDS, { [key]: markRaw(newData) }) // 只读视图字段,去响应式
|
|
304
|
+
delete state.metaViewFieldStatus[key]
|
|
305
|
+
return newData
|
|
306
|
+
})
|
|
307
|
+
.catch(() => {
|
|
308
|
+
delete state.metaViewFieldStatus[key]
|
|
309
|
+
})
|
|
310
|
+
state.metaViewFieldStatus = { ...state.metaViewFieldStatus, [key]: promise }
|
|
311
|
+
return promise
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
package/src/style-presets.js
CHANGED
|
@@ -62,14 +62,14 @@ export const STYLE_AXES = [
|
|
|
62
62
|
]
|
|
63
63
|
|
|
64
64
|
// 应用一套预设:把四个轴值写进 uiSettings(触发 applyTheme + 差量落盘)
|
|
65
|
-
export function applyStylePreset (presetKey) {
|
|
65
|
+
export function applyStylePreset (presetKey, settings = uiSettings) {
|
|
66
66
|
const preset = STYLE_PRESETS.find(p => p.key === presetKey)
|
|
67
67
|
if (!preset) return
|
|
68
|
-
Object.keys(AXIS_ATTRS).forEach(k => {
|
|
68
|
+
Object.keys(AXIS_ATTRS).forEach(k => { settings[k] = preset[k] })
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// 当前轴值组合命中哪套预设(设置面板高亮用);都不命中返回 ''(= 用户自定义了组合)
|
|
72
|
-
export function matchStylePreset () {
|
|
72
|
+
export function matchStylePreset (settings = uiSettings) {
|
|
73
73
|
// 先把四个轴全读进 cur 再比,而不是在 every() 回调里现读:every()/find() 都会短路,现读的话
|
|
74
74
|
// 「第一个不匹配的轴」之后的轴根本不会被读到,也就不会被 Vue 登记为响应式依赖——依赖集完不完整
|
|
75
75
|
// 变成了「预设表长什么样」的函数。
|
|
@@ -80,7 +80,7 @@ export function matchStylePreset () {
|
|
|
80
80
|
// 这里改成先全读,是把「依赖完整」从一条依赖预设表形状的隐性推理,变成无条件成立的事实——
|
|
81
81
|
// 于是调用方(AppSettings 的 currentPreset)可以直接 return,不必再挂一个「依赖预读」数组兜底。
|
|
82
82
|
const cur = {}
|
|
83
|
-
for (const k of Object.keys(AXIS_ATTRS)) cur[k] =
|
|
83
|
+
for (const k of Object.keys(AXIS_ATTRS)) cur[k] = settings[k]
|
|
84
84
|
const hit = STYLE_PRESETS.find(p => Object.keys(AXIS_ATTRS).every(k => cur[k] === p[k]))
|
|
85
85
|
return hit ? hit.key : ''
|
|
86
86
|
}
|