aegon-gen 1.0.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.
Files changed (86) hide show
  1. package/package.json +12 -0
  2. package/src/App.vue +3 -0
  3. package/src/api/index.ts +19 -0
  4. package/src/api/modules/gen-ai/gen-entry/index.ts +30 -0
  5. package/src/api/modules/gen-ai/model-manager/index.ts +42 -0
  6. package/src/api/modules/gen-ai/model-manager/mockApi.ts +33 -0
  7. package/src/api/modules/index.ts +98 -0
  8. package/src/api/modules/user/index.ts +4 -0
  9. package/src/api/request.ts +102 -0
  10. package/src/assets/sample-access-icon.png +0 -0
  11. package/src/assets/sample-pie-chart.png +0 -0
  12. package/src/assets/vue.svg +1 -0
  13. package/src/components/CapsuleScrollbar.vue +93 -0
  14. package/src/components/Export/ExcelExport.vue +592 -0
  15. package/src/components/Export/ExcelExport2.vue +494 -0
  16. package/src/components/Export/ExcelExport3.vue +342 -0
  17. package/src/components/Export/ExcelExport4.vue +665 -0
  18. package/src/components/Export/excelExport.js +547 -0
  19. package/src/components/Export/excelExport.ts +551 -0
  20. package/src/components/GEN-AI/index.vue +142 -0
  21. package/src/components/GEN-AI/index1.vue +456 -0
  22. package/src/components/GEN-AI/index10.vue +5 -0
  23. package/src/components/GEN-AI/index2.vue +568 -0
  24. package/src/components/GEN-AI/index3.vue +623 -0
  25. package/src/components/GEN-AI/index4.vue +629 -0
  26. package/src/components/GEN-AI/index5.vue +578 -0
  27. package/src/components/GEN-AI/index6.vue +656 -0
  28. package/src/components/GEN-AI/index7.vue +717 -0
  29. package/src/components/GEN-AI/index8.vue +405 -0
  30. package/src/components/GEN-AI/index9.vue +1065 -0
  31. package/src/components/GEN-AI/types.ts +12 -0
  32. package/src/components/GEN-AI/utils.ts +42 -0
  33. package/src/components/HelloWorld.vue +41 -0
  34. package/src/components/PageCard.vue +7 -0
  35. package/src/components/PageHeader.vue +32 -0
  36. package/src/components/backup/index5 copy.vue +556 -0
  37. package/src/components/backup/index5.vue +620 -0
  38. package/src/components/backup/index9 copy.vue +1029 -0
  39. package/src/components/backup/index9-pro.vue +1065 -0
  40. package/src/components/backup/index9.vue +1057 -0
  41. package/src/components/el-date-picker.vue +64 -0
  42. package/src/directives/btnLoading.ts +427 -0
  43. package/src/directives/debounce copy.ts +670 -0
  44. package/src/directives/debounce.ts +98 -0
  45. package/src/directives/index.ts +25 -0
  46. package/src/layouts/MainLayout.vue +101 -0
  47. package/src/main.ts +85 -0
  48. package/src/router/index.ts +76 -0
  49. package/src/router/menus.ts +28 -0
  50. package/src/style.css +79 -0
  51. package/src/styles/_variables.scss +24 -0
  52. package/src/styles/app-button.css +26 -0
  53. package/src/styles/element-overrides.css +23 -0
  54. package/src/styles/global.css +44 -0
  55. package/src/styles/index.scss +1 -0
  56. package/src/styles/page-card.css +21 -0
  57. package/src/styles/variables.css +26 -0
  58. package/src/test/mock.ts +101 -0
  59. package/src/test/test1.vue +402 -0
  60. package/src/test/test2.vue +1689 -0
  61. package/src/types/gen-ai/gen-entry/index.ts +17 -0
  62. package/src/types/gen-ai/model-manager/index.ts +19 -0
  63. package/src/utils/docxExport.ts +1610 -0
  64. package/src/utils/gen-ai-navigation.ts +37 -0
  65. package/src/utils/gen-ai-scroll.ts +455 -0
  66. package/src/utils/openDataLoaderWordExport.ts +33 -0
  67. package/src/utils/pageScrollbar.ts +115 -0
  68. package/src/utils/randomTranscode.ts +87 -0
  69. package/src/utils/reportPdfExport.ts +44 -0
  70. package/src/views/AdminCenter/index.vue +817 -0
  71. package/src/views/Blank.vue +68 -0
  72. package/src/views/Home.vue +29 -0
  73. package/src/views/ReportCenter/index.vue +1380 -0
  74. package/src/views/TemplateCenter/Knowledge.ts +83 -0
  75. package/src/views/TemplateCenter/data.d.ts +10 -0
  76. package/src/views/TemplateCenter/index.vue +1205 -0
  77. package/src/views/TemplateCenter/service.ts +69 -0
  78. package/src/views/gen-ai/components/RecentReportsTable.vue +193 -0
  79. package/src/views/gen-ai/gen-entry/index.vue +309 -0
  80. package/src/views/gen-ai/gen-entry/mockData.ts +160 -0
  81. package/src/views/gen-ai/management-center/index.vue +53 -0
  82. package/src/views/gen-ai/model-manager/ChapterTitleScroll.vue +275 -0
  83. package/src/views/gen-ai/model-manager/index.vue +1205 -0
  84. package/src/views/gen-ai/model-manager/mockData.ts +122 -0
  85. package/src/views/gen-ai/report-center/index.vue +158 -0
  86. package/src/vite-env.d.ts +38 -0
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="block">
3
+ <span class="demonstration">默认</span>
4
+ <el-date-picker
5
+ v-model="value1"
6
+ type="daterange"
7
+ range-separator="至"
8
+ start-placeholder="开始日期"
9
+ end-placeholder="结束日期"
10
+ :disabled-date="disabledDate"
11
+ @change="handleDateChange"
12
+ >
13
+ </el-date-picker>
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import { ref } from "vue";
19
+ import { ElMessage } from "element-plus";
20
+
21
+ type DateRange = [Date | null, Date | null];
22
+
23
+ const value1 = ref<DateRange>([null, null]);
24
+
25
+ const getDateDiffInDays = (date1: Date, date2: Date): number => {
26
+ const timeDiff = Math.abs(date2.getTime() - date1.getTime());
27
+ return Math.ceil(timeDiff / (1000 * 3600 * 24));
28
+ };
29
+
30
+ const handleDateChange = (value: DateRange | null) => {
31
+ if (!value || !value[0] || !value[1]) {
32
+ return;
33
+ }
34
+
35
+ const [startDate, endDate] = value;
36
+
37
+ if (startDate > endDate) {
38
+ ElMessage.error("开始时间不能晚于结束时间");
39
+ value1.value = [null, null];
40
+ return;
41
+ }
42
+
43
+ const dayDiff = getDateDiffInDays(startDate, endDate);
44
+ if (dayDiff > 31) {
45
+ ElMessage.error("时间范围不能超过31天");
46
+ value1.value = [null, null];
47
+ }
48
+ };
49
+
50
+ const disabledDate = (_time: Date) => false;
51
+ </script>
52
+
53
+ <style scoped>
54
+ .block {
55
+ padding: 20px 0;
56
+ }
57
+
58
+ .demonstration {
59
+ display: block;
60
+ color: var(--el-text-color-secondary);
61
+ font-size: 14px;
62
+ margin-bottom: 10px;
63
+ }
64
+ </style>
@@ -0,0 +1,427 @@
1
+ import { nextTick, type Directive, type DirectiveBinding } from 'vue'
2
+
3
+ const BTN_LOADING_KEY = Symbol('vBtnLoading')
4
+ const REFRESH_GEN_KEY = Symbol('vBtnLoadingRefreshGen')
5
+
6
+ const LOADING_STYLE_ID = 'v-btn-loading-style'
7
+ const DEFAULT_MIN_LOCK_MS = 1000
8
+ const DEFAULT_AUTO_CLOSE_MS = 30_000
9
+ const HOST_ID_ATTR = 'data-v-btn-loading-id'
10
+
11
+ interface BtnLoadingSession {
12
+ id: string
13
+ host: HTMLButtonElement
14
+ startedAt: number
15
+ minLockMs: number
16
+ locked: boolean
17
+ closeRequested: boolean
18
+ closeRequestedAt?: number
19
+ releaseTimer?: number
20
+ autoCloseTimer?: number
21
+ guardTimer?: number
22
+ classObserver?: MutationObserver
23
+ }
24
+
25
+ interface BtnLoadingBindingMeta {
26
+ listener: (event: Event) => void
27
+ event: string
28
+ binding: DirectiveBinding
29
+ }
30
+
31
+ /** closeBtnLoading() 主动关闭;未调用时 DEFAULT_AUTO_CLOSE_MS 后自动关闭 */
32
+ const activeSessions = new Map<string, BtnLoadingSession>()
33
+ const hostToSessionId = new Map<HTMLButtonElement, string>()
34
+
35
+ function resolveButtonHost(el: HTMLElement): HTMLButtonElement {
36
+ if (el.tagName === 'BUTTON') return el as HTMLButtonElement
37
+ const nested = el.querySelector<HTMLButtonElement>('button.el-button')
38
+ return (nested ?? el) as HTMLButtonElement
39
+ }
40
+
41
+ function ensureHostId(host: HTMLButtonElement, id: string) {
42
+ host.setAttribute(HOST_ID_ATTR, id)
43
+ }
44
+
45
+ function getSessionById(id: string): BtnLoadingSession | undefined {
46
+ return activeSessions.get(id)
47
+ }
48
+
49
+ /** Vue 重渲染可能替换 button 节点,按 session id 重新绑定 DOM */
50
+ function rebindSessionHost(session: BtnLoadingSession): HTMLButtonElement | null {
51
+ if (session.host.isConnected) {
52
+ ensureHostId(session.host, session.id)
53
+ hostToSessionId.set(session.host, session.id)
54
+ return session.host
55
+ }
56
+
57
+ const byAttr = document.querySelector<HTMLButtonElement>(
58
+ `[${HOST_ID_ATTR}="${CSS.escape(session.id)}"]`,
59
+ )
60
+ if (byAttr) {
61
+ session.host = byAttr
62
+ hostToSessionId.set(byAttr, session.id)
63
+ return byAttr
64
+ }
65
+
66
+ return null
67
+ }
68
+
69
+ function getSessionByHost(host: HTMLButtonElement): BtnLoadingSession | undefined {
70
+ const id = hostToSessionId.get(host) ?? host.getAttribute(HOST_ID_ATTR) ?? undefined
71
+ if (!id) return undefined
72
+
73
+ const session = getSessionById(id)
74
+ if (!session) return undefined
75
+
76
+ session.host = host
77
+ hostToSessionId.set(host, id)
78
+ return session
79
+ }
80
+
81
+ function findSessionForHost(host: HTMLButtonElement): BtnLoadingSession | undefined {
82
+ const direct = getSessionByHost(host)
83
+ if (direct) return direct
84
+
85
+ const id = host.getAttribute(HOST_ID_ATTR)
86
+ if (id) {
87
+ const session = getSessionById(id)
88
+ if (session) {
89
+ session.host = host
90
+ hostToSessionId.set(host, id)
91
+ return session
92
+ }
93
+ }
94
+
95
+ for (const session of activeSessions.values()) {
96
+ const rebound = rebindSessionHost(session)
97
+ if (rebound === host) return session
98
+ }
99
+
100
+ return undefined
101
+ }
102
+
103
+ function resolveCloseTargets(target?: HTMLElement | string): HTMLButtonElement[] {
104
+ if (target === undefined) {
105
+ return [...activeSessions.values()]
106
+ .map((session) => rebindSessionHost(session))
107
+ .filter((host): host is HTMLButtonElement => host !== null)
108
+ }
109
+ if (typeof target === 'string') {
110
+ return Array.from(document.querySelectorAll<HTMLElement>(target)).map((node) =>
111
+ resolveButtonHost(node),
112
+ )
113
+ }
114
+ return [resolveButtonHost(target)]
115
+ }
116
+
117
+ function resolveMinLockMs(arg?: string): number {
118
+ if (arg && /^\d+$/.test(arg)) return Number(arg)
119
+ return DEFAULT_MIN_LOCK_MS
120
+ }
121
+
122
+ function ensureLoadingStyles() {
123
+ if (typeof document === 'undefined') return
124
+
125
+ const css = `
126
+ .el-button.v-btn-loading-host,
127
+ button.v-btn-loading-host {
128
+ position: relative !important;
129
+ box-sizing: border-box;
130
+ cursor: not-allowed !important;
131
+ }
132
+ .el-button.v-btn-loading-host {
133
+ display: inline-flex !important;
134
+ align-items: center !important;
135
+ justify-content: center !important;
136
+ }
137
+ .el-button.v-btn-loading-host::after,
138
+ button.v-btn-loading-host::after {
139
+ content: '';
140
+ display: inline-block;
141
+ width: 14px;
142
+ height: 14px;
143
+ margin-left: 6px;
144
+ flex: 0 0 auto;
145
+ border: 2px solid currentColor;
146
+ border-right-color: transparent;
147
+ border-radius: 50%;
148
+ animation: v-btn-loading-spin 0.75s linear infinite;
149
+ vertical-align: middle;
150
+ opacity: 1 !important;
151
+ }
152
+ @keyframes v-btn-loading-spin {
153
+ to { transform: rotate(360deg); }
154
+ }
155
+ `
156
+
157
+ const existing = document.getElementById(LOADING_STYLE_ID)
158
+ if (existing) {
159
+ existing.textContent = css
160
+ return
161
+ }
162
+
163
+ const style = document.createElement('style')
164
+ style.id = LOADING_STYLE_ID
165
+ style.textContent = css
166
+ document.head.appendChild(style)
167
+ }
168
+
169
+ function bumpRefreshGen(host: HTMLButtonElement): number {
170
+ const next = ((host as HTMLElement & { [REFRESH_GEN_KEY]?: number })[REFRESH_GEN_KEY] ?? 0) + 1
171
+ ;(host as HTMLElement & { [REFRESH_GEN_KEY]?: number })[REFRESH_GEN_KEY] = next
172
+ return next
173
+ }
174
+
175
+ function applyLoadingVisual(host: HTMLButtonElement, sessionId: string) {
176
+ ensureLoadingStyles()
177
+ ensureHostId(host, sessionId)
178
+ host.classList.add('v-btn-loading-host', 'is-disabled')
179
+ host.setAttribute('aria-busy', 'true')
180
+ host.setAttribute('aria-disabled', 'true')
181
+ host.dataset.btnLoading = '1'
182
+ }
183
+
184
+ function clearLoadingVisual(host: HTMLButtonElement) {
185
+ host.classList.remove('v-btn-loading-host', 'is-disabled')
186
+ host.removeAttribute('aria-busy')
187
+ host.removeAttribute('aria-disabled')
188
+ host.removeAttribute(HOST_ID_ATTR)
189
+ delete host.dataset.btnLoading
190
+ }
191
+
192
+ function ensureLoadingVisual(session: BtnLoadingSession) {
193
+ if (!activeSessions.has(session.id)) return
194
+
195
+ const host = rebindSessionHost(session)
196
+ if (!host) return
197
+
198
+ if (!host.classList.contains('v-btn-loading-host')) {
199
+ applyLoadingVisual(host, session.id)
200
+ } else {
201
+ ensureHostId(host, session.id)
202
+ }
203
+ }
204
+
205
+ function startClassGuard(session: BtnLoadingSession) {
206
+ stopClassGuard(session)
207
+
208
+ const guard = () => {
209
+ if (!activeSessions.has(session.id)) return
210
+ ensureLoadingVisual(session)
211
+ }
212
+
213
+ const host = rebindSessionHost(session)
214
+ if (host) {
215
+ session.classObserver = new MutationObserver(guard)
216
+ session.classObserver.observe(host, { attributes: true, attributeFilter: ['class'] })
217
+ }
218
+
219
+ session.guardTimer = window.setInterval(guard, 120)
220
+ }
221
+
222
+ function stopClassGuard(session: BtnLoadingSession) {
223
+ session.classObserver?.disconnect()
224
+ delete session.classObserver
225
+ if (session.guardTimer !== undefined) {
226
+ window.clearInterval(session.guardTimer)
227
+ delete session.guardTimer
228
+ }
229
+ }
230
+
231
+ function scheduleLoadingRefresh(session: BtnLoadingSession) {
232
+ const host = rebindSessionHost(session)
233
+ if (!host) return
234
+
235
+ const gen = (host as HTMLElement & { [REFRESH_GEN_KEY]?: number })[REFRESH_GEN_KEY] ?? 0
236
+ void nextTick(() => {
237
+ if (!activeSessions.has(session.id)) return
238
+ if ((host as HTMLElement & { [REFRESH_GEN_KEY]?: number })[REFRESH_GEN_KEY] !== gen) return
239
+ ensureLoadingVisual(session)
240
+ })
241
+ }
242
+
243
+ function clearReleaseTimer(session: BtnLoadingSession) {
244
+ if (session.releaseTimer !== undefined) {
245
+ window.clearTimeout(session.releaseTimer)
246
+ session.releaseTimer = undefined
247
+ }
248
+ }
249
+
250
+ function clearAutoCloseTimer(session: BtnLoadingSession) {
251
+ if (session.autoCloseTimer !== undefined) {
252
+ window.clearTimeout(session.autoCloseTimer)
253
+ session.autoCloseTimer = undefined
254
+ }
255
+ }
256
+
257
+ function releaseSession(session: BtnLoadingSession) {
258
+ if (!activeSessions.has(session.id)) return
259
+
260
+ clearReleaseTimer(session)
261
+ clearAutoCloseTimer(session)
262
+ stopClassGuard(session)
263
+
264
+ const host = rebindSessionHost(session)
265
+ if (host) {
266
+ clearLoadingVisual(host)
267
+ hostToSessionId.delete(host)
268
+ }
269
+
270
+ activeSessions.delete(session.id)
271
+ }
272
+
273
+ /** closeBtnLoading() 或超时触发;从点击起至少 minLockMs 后才真正关闭 */
274
+ function scheduleRelease(session: BtnLoadingSession) {
275
+ clearReleaseTimer(session)
276
+ const elapsed = Date.now() - session.startedAt
277
+ const remain = Math.max(0, session.minLockMs - elapsed)
278
+
279
+ session.releaseTimer = window.setTimeout(() => {
280
+ session.releaseTimer = undefined
281
+ session.locked = false
282
+ releaseSession(session)
283
+ }, remain)
284
+ }
285
+
286
+ /** 未调用 closeBtnLoading() 时,点击后 DEFAULT_AUTO_CLOSE_MS 自动关闭 */
287
+ function scheduleAutoClose(session: BtnLoadingSession) {
288
+ clearAutoCloseTimer(session)
289
+ session.autoCloseTimer = window.setTimeout(() => {
290
+ session.autoCloseTimer = undefined
291
+ if (!activeSessions.has(session.id)) return
292
+ requestClose(session)
293
+ }, DEFAULT_AUTO_CLOSE_MS)
294
+ }
295
+
296
+ function requestClose(session: BtnLoadingSession) {
297
+ if (session.closeRequested) return
298
+ session.closeRequested = true
299
+ session.closeRequestedAt = Date.now()
300
+ clearAutoCloseTimer(session)
301
+ scheduleRelease(session)
302
+ }
303
+
304
+ function activateLoading(host: HTMLButtonElement, minLockMs: number) {
305
+ const existing = findSessionForHost(host)
306
+ if (existing?.locked && !existing.closeRequested) return
307
+
308
+ const id = existing?.id ?? `bl-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`
309
+ const session: BtnLoadingSession = {
310
+ id,
311
+ host,
312
+ startedAt: Date.now(),
313
+ minLockMs,
314
+ locked: true,
315
+ closeRequested: false,
316
+ }
317
+
318
+ activeSessions.set(id, session)
319
+ hostToSessionId.set(host, id)
320
+ bumpRefreshGen(host)
321
+ applyLoadingVisual(host, id)
322
+ startClassGuard(session)
323
+ scheduleLoadingRefresh(session)
324
+ scheduleAutoClose(session)
325
+ }
326
+
327
+ /** 请求关闭;未调用时 30s 后自动关闭;调用后至少再保持 minLockMs(默认 1s,从点击起算) */
328
+ export function closeBtnLoading(target?: HTMLElement | string) {
329
+ if (target === undefined) {
330
+ ;[...activeSessions.values()].forEach((session) => requestClose(session))
331
+ return
332
+ }
333
+
334
+ resolveCloseTargets(target).forEach((host) => {
335
+ const session = findSessionForHost(host)
336
+ if (!session) return
337
+ requestClose(session)
338
+ })
339
+ }
340
+
341
+ /** 是否存在未关闭的 loading(便于调试/测试) */
342
+ export function hasActiveBtnLoading(target?: HTMLElement | string): boolean {
343
+ if (target === undefined) return activeSessions.size > 0
344
+
345
+ return resolveCloseTargets(target).some((host) => {
346
+ const session = findSessionForHost(host)
347
+ return !!session && !session.closeRequested
348
+ })
349
+ }
350
+
351
+ /**
352
+ * v-btnLoading — 按钮 loading(与 v-debounce 解耦)
353
+ * - v-btnLoading 默认最短 1s(从点击起算)
354
+ * - v-btnLoading:1500 自定义最短毫秒
355
+ * - 未调用 closeBtnLoading():30s 后自动关闭
356
+ * - closeBtnLoading() 后:若未满 minLockMs 则补满剩余时间再关闭
357
+ */
358
+ export const vBtnLoading: Directive<HTMLElement> = {
359
+ mounted(el: HTMLElement, binding: DirectiveBinding) {
360
+ const host = resolveButtonHost(el)
361
+ const event = binding.arg && !/^\d+$/.test(binding.arg) ? binding.arg : 'click'
362
+
363
+ const listener = (e: Event) => {
364
+ const meta = (el as HTMLElement & { [BTN_LOADING_KEY]?: BtnLoadingBindingMeta })[BTN_LOADING_KEY]
365
+ const currentBinding = meta?.binding ?? binding
366
+ const minLockMs = resolveMinLockMs(
367
+ currentBinding.arg && /^\d+$/.test(currentBinding.arg) ? currentBinding.arg : undefined,
368
+ )
369
+
370
+ const session = findSessionForHost(host)
371
+ if (session?.locked && !session.closeRequested) {
372
+ e.preventDefault()
373
+ e.stopImmediatePropagation()
374
+ return
375
+ }
376
+
377
+ activateLoading(host, minLockMs)
378
+ }
379
+
380
+ host.addEventListener(event, listener, true)
381
+ ;(el as HTMLElement & { [BTN_LOADING_KEY]?: BtnLoadingBindingMeta })[BTN_LOADING_KEY] = {
382
+ listener,
383
+ event,
384
+ binding,
385
+ }
386
+
387
+ const existing = findSessionForHost(host)
388
+ if (existing && !existing.closeRequested) {
389
+ existing.host = host
390
+ hostToSessionId.set(host, existing.id)
391
+ ensureLoadingVisual(existing)
392
+ startClassGuard(existing)
393
+ }
394
+ },
395
+ updated(el: HTMLElement, binding: DirectiveBinding) {
396
+ const host = resolveButtonHost(el)
397
+ const meta = (el as HTMLElement & { [BTN_LOADING_KEY]?: BtnLoadingBindingMeta })[BTN_LOADING_KEY]
398
+ if (meta) meta.binding = binding
399
+
400
+ const session = findSessionForHost(host)
401
+ if (!session || session.closeRequested) return
402
+
403
+ session.host = host
404
+ hostToSessionId.set(host, session.id)
405
+ ensureLoadingVisual(session)
406
+ scheduleLoadingRefresh(session)
407
+ },
408
+ unmounted(el: HTMLElement) {
409
+ const host = resolveButtonHost(el)
410
+ const meta = (el as HTMLElement & { [BTN_LOADING_KEY]?: BtnLoadingBindingMeta })[BTN_LOADING_KEY]
411
+ if (meta) {
412
+ host.removeEventListener(meta.event, meta.listener, true)
413
+ delete (el as HTMLElement & { [BTN_LOADING_KEY]?: BtnLoadingBindingMeta })[BTN_LOADING_KEY]
414
+ }
415
+
416
+ const session = findSessionForHost(host)
417
+ if (!session) return
418
+
419
+ if (session.closeRequested) {
420
+ releaseSession(session)
421
+ return
422
+ }
423
+
424
+ stopClassGuard(session)
425
+ hostToSessionId.delete(host)
426
+ },
427
+ }