aegon-lv97 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 (78) hide show
  1. package/gen-ai/build-report/chartStreamRefs.ts +227 -0
  2. package/gen-ai/build-report/coherence-check/index.vue +559 -0
  3. package/gen-ai/build-report/components/ReportChapterWorkspace.vue +4571 -0
  4. package/gen-ai/build-report/components/ReportConfigPanel.vue +727 -0
  5. package/gen-ai/build-report/components/ReportGenerateSettingsPanel.vue +2361 -0
  6. package/gen-ai/build-report/components/ReportGeneratingPanel.vue +1765 -0
  7. package/gen-ai/build-report/components/ReportPromptPanel.vue +625 -0
  8. package/gen-ai/build-report/components/ReportSourceFileSummary.vue +665 -0
  9. package/gen-ai/build-report/components/ReportSourcesPanel.vue +1327 -0
  10. package/gen-ai/build-report/components/ReportTemplateDetail.vue +191 -0
  11. package/gen-ai/build-report/components/ReportTemplateEditorFormPanel.vue +667 -0
  12. package/gen-ai/build-report/components/ReportTemplatePicker.vue +302 -0
  13. package/gen-ai/build-report/components/ReportWorkflowSidebar.vue +148 -0
  14. package/gen-ai/build-report/components/paramsSetting.vue +886 -0
  15. package/gen-ai/build-report/components/reportEdit.vue +2283 -0
  16. package/gen-ai/build-report/index.vue +856 -0
  17. package/gen-ai/build-report/report-domain.ts +1133 -0
  18. package/gen-ai/build-report/report-template-data.ts +295 -0
  19. package/gen-ai/build-report/useReportWorkflow.ts +1386 -0
  20. package/gen-ai/common/assets/NotoSans-SC.woff2 +0 -0
  21. package/gen-ai/common/assets/NotoSans-TC.woff2 +0 -0
  22. package/gen-ai/common/assets/NotoSans.woff2 +0 -0
  23. package/gen-ai/common/assets/fonts.css +278 -0
  24. package/gen-ai/common/assets/pagination.css +163 -0
  25. package/gen-ai/common/directives/btnLoading.ts +455 -0
  26. package/gen-ai/common/directives/debounce.ts +98 -0
  27. package/gen-ai/common/directives/index.ts +30 -0
  28. package/gen-ai/common/en.md +417 -0
  29. package/gen-ai/common/index.ts +36 -0
  30. package/gen-ai/common/types/component-expose.ts +9 -0
  31. package/gen-ai/common/utils/api-res-status.ts +7 -0
  32. package/gen-ai/common/utils/navigation.ts +59 -0
  33. package/gen-ai/common/utils/remote-request.ts +45 -0
  34. package/gen-ai/common/utils/scroll.ts +577 -0
  35. package/gen-ai/components/AIExport/docx-export.ts +950 -0
  36. package/gen-ai/components/AIExport/docxExport.ts +2566 -0
  37. package/gen-ai/components/AIExport/index.ts +52 -0
  38. package/gen-ai/components/AIExport/parseMarkdownHtml.ts +653 -0
  39. package/gen-ai/components/CapsuleScrollbar.vue +149 -0
  40. package/gen-ai/components/ChapterTitleScroll.vue +468 -0
  41. package/gen-ai/components/EntryHeroNavCards.vue +379 -0
  42. package/gen-ai/components/GenAiPagination.vue +52 -0
  43. package/gen-ai/components/ModelCard.vue +1114 -0
  44. package/gen-ai/components/Preview/FilePreviewPage.vue +949 -0
  45. package/gen-ai/components/Preview/PreviewCapsuleScroll.vue +205 -0
  46. package/gen-ai/components/Preview/PreviewOutlineTree.vue +148 -0
  47. package/gen-ai/components/Preview/index.ts +11 -0
  48. package/gen-ai/components/Preview/preview.ts +724 -0
  49. package/gen-ai/components/PromptField.vue +505 -0
  50. package/gen-ai/components/RecentReportsTable.vue +974 -0
  51. package/gen-ai/components/ReportCollapsibleSection.vue +172 -0
  52. package/gen-ai/components/ReportHistoryList.vue +637 -0
  53. package/gen-ai/components/ReportSectionConfirmPopover.vue +251 -0
  54. package/gen-ai/components/editor/ChapterTiptapEditor.vue +3718 -0
  55. package/gen-ai/components/editor/StructureBlockView.vue +441 -0
  56. package/gen-ai/components/editor/TiptapToolbar.vue +1036 -0
  57. package/gen-ai/components/editor/TypewriterDocEditor.vue +422 -0
  58. package/gen-ai/components/editor/_StructureOrgNode.vue +326 -0
  59. package/gen-ai/components/editor/index.ts +28 -0
  60. package/gen-ai/components/editor/parseMarkdownHtml.ts +754 -0
  61. package/gen-ai/components/editor/reviewCitationTip.ts +163 -0
  62. package/gen-ai/gen-entry/api/index.ts +32 -0
  63. package/gen-ai/gen-entry/index.vue +287 -0
  64. package/gen-ai/gen-entry/types/index.ts +4 -0
  65. package/gen-ai/i.mark +2 -0
  66. package/gen-ai/management-center/index.vue +1815 -0
  67. package/gen-ai/management-center/mockData.ts +248 -0
  68. package/gen-ai/management-center/types/index.ts +37 -0
  69. package/gen-ai/model-manager/TemplateEditorFormPanel.vue +661 -0
  70. package/gen-ai/model-manager/api/index.ts +32 -0
  71. package/gen-ai/model-manager/api/mockApi.ts +33 -0
  72. package/gen-ai/model-manager/index.vue +1583 -0
  73. package/gen-ai/model-manager/mockData.ts +177 -0
  74. package/gen-ai/model-manager/template-detail-shared.ts +154 -0
  75. package/gen-ai/model-manager/template-editor.vue +345 -0
  76. package/gen-ai/model-manager/types/index.ts +40 -0
  77. package/gen-ai/model-manager/utils.ts +25 -0
  78. package/package.json +12 -0
@@ -0,0 +1,302 @@
1
+ <template>
2
+ <section class="report-template-picker">
3
+ <section class="template-center-hero">
4
+ <h2 class="template-center-hero__title">選擇模板</h2>
5
+ <p class="template-center-hero__desc gen-ai-page-hero-desc">點擊卡片進入詳情與章節預覽</p>
6
+ </section>
7
+
8
+ <section class="template-center-toolbar">
9
+ <div class="template-center-toolbar__controls">
10
+ <div class="template-center-toolbar__right">
11
+ <label class="template-center-field">
12
+ <span class="gen-ai-filter-field-label">單位</span>
13
+ <el-select
14
+ v-model="unitFilter"
15
+ placeholder=""
16
+ clearable
17
+ class="template-center-field__select"
18
+ >
19
+ <el-option v-for="item in unitOptions" :key="item" :label="item" :value="item" />
20
+ </el-select>
21
+ </label>
22
+
23
+ <label class="template-center-field">
24
+ <span class="gen-ai-filter-field-label">Search</span>
25
+ <el-input v-model="keyword" clearable class="template-center-field__input" />
26
+ </label>
27
+
28
+ <button
29
+ type="button"
30
+ class="template-center-toolbar-btn gen-ai-action-btn template-center-toolbar-btn--primary"
31
+ @click="handleRefresh"
32
+ >
33
+ Refresh
34
+ </button>
35
+ </div>
36
+ </div>
37
+ </section>
38
+
39
+ <div class="report-template-picker__card-grid">
40
+ <div
41
+ v-for="row in paginatedTemplates"
42
+ :key="row.id"
43
+ class="report-template-picker__card-hit"
44
+ @click="handleCardClick(row)"
45
+ >
46
+ <ModelCard :template="row" :show-actions="false" />
47
+ </div>
48
+ </div>
49
+
50
+ <GenAiPagination
51
+ v-model:current-page="currentPage"
52
+ v-model:page-size="pageSize"
53
+ :page-sizes="[4]"
54
+ :total="filteredTemplates.length"
55
+ />
56
+ </section>
57
+ </template>
58
+
59
+ <script lang="ts">
60
+ export {
61
+ REPORT_TEMPLATE_CARDS,
62
+ REPORT_TEMPLATE_ITEMS,
63
+ fetchReportTemplateList,
64
+ resolveReportTemplateById,
65
+ } from '../report-template-data'
66
+ export type { ReportTemplateCard, TemplateItem } from '../report-template-data'
67
+ </script>
68
+
69
+ <script setup lang="ts">
70
+ import { ElMessage } from 'element-plus'
71
+ import { computed, onMounted, ref, watch } from 'vue'
72
+ import {
73
+ REPORT_TEMPLATE_ITEMS,
74
+ fetchReportTemplateList,
75
+ templateItemToReportCard,
76
+ type ReportTemplateCard,
77
+ type TemplateItem,
78
+ } from '../report-template-data'
79
+ import { GenAiPagination, ModelCard } from '../../common'
80
+
81
+ const unitOptions = ['風險管理部', '授信審批部', '合規部', '公司金融部']
82
+
83
+ const unitFilter = ref('')
84
+ const keyword = ref('')
85
+ const currentPage = ref(1)
86
+ const pageSize = ref(4)
87
+ const templates = ref<TemplateItem[]>([...REPORT_TEMPLATE_ITEMS])
88
+
89
+ const emit = defineEmits<{
90
+ select: [template: ReportTemplateCard]
91
+ }>()
92
+
93
+ function isTemplateList(data: unknown) {
94
+ return Array.isArray(data) && data.length > 0 && typeof data[0]?.id === 'string'
95
+ }
96
+
97
+ async function loadTemplates(force = false) {
98
+ const data = await fetchReportTemplateList(
99
+ {
100
+ unit: unitFilter.value || undefined,
101
+ keyword: keyword.value.trim() || undefined,
102
+ },
103
+ { force }
104
+ )
105
+ if (isTemplateList(data)) {
106
+ templates.value = data as TemplateItem[]
107
+ }
108
+ }
109
+
110
+ function handleCardClick(row: TemplateItem) {
111
+ emit('select', templateItemToReportCard(row))
112
+ }
113
+
114
+ function handleRefresh() {
115
+ keyword.value = ''
116
+ unitFilter.value = ''
117
+ void loadTemplates(true)
118
+ ElMessage.success('已重新整理')
119
+ }
120
+
121
+ const filteredTemplates = computed(() => {
122
+ const kw = keyword.value.trim().toLowerCase()
123
+ return templates.value.filter((item) => {
124
+ const unitOk = !unitFilter.value || item.unit === unitFilter.value
125
+ const keywordOk =
126
+ !kw ||
127
+ item.name.toLowerCase().includes(kw) ||
128
+ item.description.toLowerCase().includes(kw) ||
129
+ item.author.toLowerCase().includes(kw) ||
130
+ (item.industry || '').toLowerCase().includes(kw)
131
+ return unitOk && keywordOk
132
+ })
133
+ })
134
+
135
+ const paginatedTemplates = computed(() => {
136
+ const start = (currentPage.value - 1) * pageSize.value
137
+ return filteredTemplates.value.slice(start, start + pageSize.value)
138
+ })
139
+
140
+ watch([keyword, unitFilter], () => {
141
+ currentPage.value = 1
142
+ })
143
+
144
+ watch(filteredTemplates, (list) => {
145
+ const maxPage = Math.max(1, Math.ceil(list.length / pageSize.value))
146
+ if (currentPage.value > maxPage) currentPage.value = maxPage
147
+ })
148
+
149
+ onMounted(() => {
150
+ void loadTemplates()
151
+ })
152
+ </script>
153
+
154
+ <style scoped>
155
+ .report-template-picker {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 0;
159
+ min-height: 0;
160
+ overflow: visible;
161
+ --gen-ai-fs-hero: clamp(26px, calc(32 * 100vw / 1920), 32px);
162
+ --gen-ai-fw-bold: 700;
163
+ --report-accent: #c53355;
164
+ font-size: 14px;
165
+ line-height: 1.6;
166
+ color: #2d3139;
167
+ }
168
+
169
+ .template-center-hero {
170
+ text-align: center;
171
+ margin-bottom: 28px;
172
+ }
173
+
174
+ .template-center-hero__title {
175
+ margin: 0 0 10px;
176
+ font-size: var(--gen-ai-fs-hero);
177
+ font-weight: var(--gen-ai-fw-bold);
178
+ color: #1a1a1a;
179
+ }
180
+
181
+ .template-center-hero__desc {
182
+ margin: 0;
183
+ }
184
+
185
+ .gen-ai-page-hero-desc {
186
+ font-size: 16px;
187
+ font-weight: 600;
188
+ line-height: 1.7;
189
+ color: #666;
190
+ }
191
+
192
+ .template-center-toolbar {
193
+ display: flex;
194
+ flex-direction: column;
195
+ gap: 12px;
196
+ margin-bottom: 20px;
197
+ }
198
+
199
+ .template-center-toolbar__controls {
200
+ display: flex;
201
+ justify-content: flex-end;
202
+ }
203
+
204
+ .template-center-toolbar__right {
205
+ display: flex;
206
+ flex-wrap: wrap;
207
+ align-items: center;
208
+ justify-content: flex-end;
209
+ gap: 12px;
210
+ }
211
+
212
+ .template-center-field {
213
+ display: inline-flex;
214
+ align-items: center;
215
+ gap: 8px;
216
+ }
217
+
218
+ .gen-ai-filter-field-label {
219
+ font-size: 14px;
220
+ font-weight: 500;
221
+ color: #606266;
222
+ white-space: nowrap;
223
+ }
224
+
225
+ .template-center-field__select {
226
+ width: 160px;
227
+ }
228
+
229
+ .template-center-field__input {
230
+ width: 200px;
231
+ }
232
+
233
+ .template-center-toolbar-btn {
234
+ display: inline-flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+ height: 32px;
238
+ padding: 0 16px;
239
+ border: 1px solid transparent;
240
+ border-radius: 4px;
241
+ font-size: 14px;
242
+ font-weight: 500;
243
+ cursor: pointer;
244
+ box-sizing: border-box;
245
+ }
246
+
247
+ .template-center-toolbar-btn--primary {
248
+ background: #c53355;
249
+ border-color: #c53355;
250
+ color: #fff;
251
+ }
252
+
253
+ .template-center-toolbar-btn--primary:hover:not(:disabled) {
254
+ background: #a82b48;
255
+ border-color: #a82b48;
256
+ }
257
+
258
+ .report-template-picker__card-grid {
259
+ display: grid;
260
+ grid-template-columns: repeat(4, minmax(0, 1fr));
261
+ gap: 20px;
262
+ align-items: stretch;
263
+ min-height: 0;
264
+ }
265
+
266
+ .report-template-picker__card-hit {
267
+ min-width: 0;
268
+ min-height: 520px;
269
+ cursor: pointer;
270
+ }
271
+
272
+ .report-template-picker__card-hit :deep(.template-center-card) {
273
+ height: 100%;
274
+ min-height: 0;
275
+ }
276
+
277
+ .report-template-picker :deep(.gen-ai-pagination) {
278
+ margin-top: 16px;
279
+ }
280
+
281
+ .report-template-picker :deep(.gen-ai-pagination .el-pagination__sizes) {
282
+ display: none;
283
+ }
284
+
285
+ @media (max-width: 1400px) {
286
+ .report-template-picker__card-grid {
287
+ grid-template-columns: repeat(3, minmax(0, 1fr));
288
+ }
289
+ }
290
+
291
+ @media (max-width: 1100px) {
292
+ .report-template-picker__card-grid {
293
+ grid-template-columns: repeat(2, minmax(0, 1fr));
294
+ }
295
+ }
296
+
297
+ @media (max-width: 720px) {
298
+ .report-template-picker__card-grid {
299
+ grid-template-columns: 1fr;
300
+ }
301
+ }
302
+ </style>
@@ -0,0 +1,148 @@
1
+ <template>
2
+ <aside class="report-workflow-sidebar" :class="{ 'is-collapsed': collapsed }">
3
+ <div v-show="!collapsed" class="report-workflow-sidebar__body">
4
+ <ReportConfigPanel />
5
+
6
+ <ReportSourceFileSummary v-if="showEditorPanel" />
7
+
8
+ <ReportCollapsibleSection
9
+ ref="sourcesSectionRef"
10
+ v-model:open="sourcesOpen"
11
+ title="資訊源"
12
+ card-hover
13
+ class="report-workflow-sidebar__sources-wrap"
14
+ :class="{ 'is-collapsed': !sourcesOpen }"
15
+ @before-collapse="closeSourcesOverlays"
16
+ >
17
+ <ReportSourcesPanel
18
+ ref="sourcesPanelRef"
19
+ sync-workflow
20
+ embedded
21
+ :section-boundary-el="sourcesSectionRoot"
22
+ :panel-open="sourcesOpen"
23
+ :sources-view-mode="sourcesViewMode"
24
+ :class="{ 'is-section-collapsed': !sourcesOpen }"
25
+ @submitted="collapseSources"
26
+ />
27
+ </ReportCollapsibleSection>
28
+ </div>
29
+ </aside>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { computed, ref } from 'vue'
34
+ import { ReportCollapsibleSection } from '../../common'
35
+ import { useReportWorkflow } from '../useReportWorkflow'
36
+ import ReportConfigPanel from './ReportConfigPanel.vue'
37
+ import ReportSourceFileSummary from './ReportSourceFileSummary.vue'
38
+ import ReportSourcesPanel from './ReportSourcesPanel.vue'
39
+
40
+ withDefaults(
41
+ defineProps<{
42
+ /** 由父級 Divider 控制,收起後不佔佈局 */
43
+ collapsed?: boolean
44
+ }>(),
45
+ {
46
+ collapsed: false,
47
+ }
48
+ )
49
+
50
+ const { promptRightPanel, modelStep } = useReportWorkflow()
51
+
52
+ const showEditorPanel = computed(() => promptRightPanel.value !== 'settings')
53
+ const sourcesViewMode = computed<'edit' | 'finalize'>(() =>
54
+ modelStep.value === 'prompt' && promptRightPanel.value === 'settings' ? 'finalize' : 'edit'
55
+ )
56
+
57
+ const sourcesOpen = ref(true)
58
+ const sourcesSectionRef = ref<InstanceType<typeof ReportCollapsibleSection> | null>(null)
59
+ const sourcesPanelRef = ref<InstanceType<typeof ReportSourcesPanel> | null>(null)
60
+ const sourcesSectionRoot = computed(() => sourcesSectionRef.value?.rootRef ?? null)
61
+
62
+ function closeSourcesOverlays(done: (hadOpenOverlays: boolean) => void) {
63
+ const hadOpen = sourcesPanelRef.value?.hasOpenOverlays() ?? false
64
+ if (hadOpen) {
65
+ sourcesPanelRef.value?.closeAllOverlays(true)
66
+ }
67
+ done(hadOpen)
68
+ }
69
+
70
+ function collapseSources() {
71
+ // sourcesOpen.value = false
72
+ }
73
+ </script>
74
+
75
+ <style scoped>
76
+ .report-workflow-sidebar {
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: 15px;
80
+ min-width: 0;
81
+ width: 100%;
82
+ height: 100%;
83
+ overflow: visible;
84
+ }
85
+
86
+ .report-workflow-sidebar.is-collapsed {
87
+ width: 0;
88
+ min-width: 0;
89
+ height: 0;
90
+ min-height: 0;
91
+ gap: 0;
92
+ overflow: hidden;
93
+ pointer-events: none;
94
+ }
95
+
96
+ .report-workflow-sidebar__body {
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: 15px;
100
+ min-width: 0;
101
+ min-height: 0;
102
+ flex: 1 1 auto;
103
+ /* 陰影左右不被父級裁切 */
104
+ overflow: visible;
105
+ }
106
+
107
+ .report-workflow-sidebar__sources-wrap {
108
+ display: flex;
109
+ flex-direction: column;
110
+ min-width: 0;
111
+ flex: 1 1 auto;
112
+ min-height: 0;
113
+ }
114
+
115
+ .report-workflow-sidebar__sources-wrap.is-collapsed {
116
+ flex: 0 0 auto;
117
+ min-height: auto;
118
+ }
119
+
120
+ .report-workflow-sidebar__sources-wrap :deep(.report-collapsible-section) {
121
+ flex: 1;
122
+ display: flex;
123
+ flex-direction: column;
124
+ min-height: 0;
125
+ }
126
+
127
+ .report-workflow-sidebar__sources-wrap.is-collapsed :deep(.report-collapsible-section) {
128
+ flex: 0 0 auto;
129
+ min-height: auto;
130
+ height: auto;
131
+ }
132
+
133
+ .report-workflow-sidebar__sources-wrap :deep(.report-collapsible-section__body) {
134
+ flex: 1;
135
+ display: flex;
136
+ flex-direction: column;
137
+ min-height: 0;
138
+ min-width: 0;
139
+ }
140
+
141
+ .report-workflow-sidebar__sources-wrap :deep(.report-collapsible-section__toggle) {
142
+ border-bottom: none;
143
+ }
144
+
145
+ .report-workflow-sidebar__sources-wrap.is-collapsed :deep(.report-collapsible-section__toggle) {
146
+ padding-bottom: 0;
147
+ }
148
+ </style>