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,163 @@
1
+ /**
2
+ * //0918 tip / REF 兼容层(归类)
3
+ *
4
+ * 旧底(开发前,不可破坏):
5
+ * [^n] / [+n] / HTML title / Element Plus tip
6
+ * → span.report-tiptap-citation → 鼠标移入打开 report-chapter-review-popover
7
+ *
8
+ * 新叠(0918):
9
+ * chartAsStream REF / [ref:uuid] → 同一 citation DOM(data-chunk-id 等)
10
+ * + 14px / >18 行灰胶囊 / 文件名新 tab 预览(UI 在 ChapterTiptapEditor)
11
+ *
12
+ * 兼容约定:
13
+ * - 库未命中 [ref:uuid] → 删除占位(不显示原文 / 不造死圆点);REF 入库后重解析再出 tip
14
+ * - [+n] 无 tip 也可开 popup(只显示序号)
15
+ * - 禁止另起 tip DOM
16
+ */
17
+ //0918
18
+ import {
19
+ getChartStreamRef,
20
+ listChartStreamRefs,
21
+ type ChartStreamRefItem,
22
+ } from '../../build-report/chartStreamRefs'
23
+
24
+ export const REF_MARKER_RE =
25
+ /\[ref:\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\s*\]/gi
26
+
27
+ /** //0918-1:正文残留的任意 [ref:…](含空格/非 UUID)一律清空,打字机不显示 */
28
+ export const REF_ANY_MARKER_RE = /\[ref:[^\]]*\]/gi
29
+ //0918-1
30
+
31
+ export type CitationTipExtra = {
32
+ sourceName?: string
33
+ filePath?: string
34
+ filePreviewUrl?: string
35
+ chunkId?: string
36
+ }
37
+
38
+ export type ResolvedRefCitation = {
39
+ id: string
40
+ tip: string
41
+ extra: CitationTipExtra
42
+ ref: ChartStreamRefItem
43
+ }
44
+
45
+ /** [ref:{chunkId}] → 在 SSERefList 中按 chunkId 匹配;未命中过滤 */
46
+ export function resolveRefMarker(chunkId: string): ResolvedRefCitation | null {
47
+ const id = String(chunkId ?? '').trim().toLowerCase()
48
+ const pool = listChartStreamRefs()
49
+ console.log('[REF tip] 匹配 SSERefList', {
50
+ chunkId: id,
51
+ SSERefListLen: pool.length,
52
+ chunkIds: pool.map((r) => r.chunkId),
53
+ })
54
+ if (!id) return null
55
+ const ref = getChartStreamRef(id)
56
+ if (!ref) {
57
+ console.log('[REF tip] 未命中 → 过滤', { chunkId: id })
58
+ return null
59
+ }
60
+ console.log('[REF tip] 命中', {
61
+ chunkId: ref.chunkId,
62
+ index: ref.index,
63
+ sourceName: ref.sourceName,
64
+ })
65
+ return {
66
+ id: String(ref.index),
67
+ tip: ref.sourceText || '',
68
+ extra: {
69
+ sourceName: ref.sourceName || undefined,
70
+ filePath: ref.filePath || undefined,
71
+ filePreviewUrl: ref.filePreviewUrl || undefined,
72
+ chunkId: ref.chunkId,
73
+ },
74
+ ref,
75
+ }
76
+ }
77
+
78
+ export type CitationDatasetFields = {
79
+ citationId: number
80
+ tip: string
81
+ href: string
82
+ linkLabel: string
83
+ sourceName: string
84
+ filePath: string
85
+ filePreviewUrl: string
86
+ chunkId: string
87
+ }
88
+
89
+ /** 从 citation DOM 读字段;缺省时用 chartStreamRefs 回填(不覆盖已有 tip) */
90
+ export function readCitationDataset(el: HTMLElement): CitationDatasetFields {
91
+ let tip = String(el.dataset.tip || el.getAttribute('title') || '').trim()
92
+ const href = String(el.dataset.href || '').trim()
93
+ const linkLabel = String(el.dataset.linkLabel || '').trim()
94
+ let sourceName = String(el.dataset.sourceName || '').trim()
95
+ let filePath = String(el.dataset.filePath || '').trim()
96
+ let filePreviewUrl = String(el.dataset.filePreviewUrl || '').trim()
97
+ const chunkId = String(el.dataset.chunkId || '').trim()
98
+ const citationId = Number(el.dataset.citation)
99
+
100
+ if (chunkId) {
101
+ const ref = getChartStreamRef(chunkId)
102
+ if (ref) {
103
+ if (!tip && ref.sourceText) tip = String(ref.sourceText).trim()
104
+ if (!sourceName && ref.sourceName) sourceName = ref.sourceName
105
+ if (!filePath && ref.filePath) filePath = ref.filePath
106
+ if (!filePreviewUrl && ref.filePreviewUrl) filePreviewUrl = ref.filePreviewUrl
107
+ }
108
+ }
109
+
110
+ return {
111
+ citationId,
112
+ tip,
113
+ href,
114
+ linkLabel,
115
+ sourceName,
116
+ filePath,
117
+ filePreviewUrl,
118
+ chunkId,
119
+ }
120
+ }
121
+
122
+ export function resolveCitationTipText(fields: CitationDatasetFields): string {
123
+ const fromDom = String(fields.tip || '').trim()
124
+ if (fromDom) return fromDom
125
+ if (!fields.chunkId) return ''
126
+ const ref = getChartStreamRef(fields.chunkId)
127
+ return String(ref?.sourceText || '').trim()
128
+ }
129
+
130
+ /**
131
+ * 可否打开 tip popup
132
+ * - 旧:有 tip / href / sourceName / filePath
133
+ * - 旧 [+n]:仅有合法序号也可开(正文可空)
134
+ * - 新:chunkId 且库中已有 REF
135
+ */
136
+ export function canOpenCitationTip(fields: CitationDatasetFields): boolean {
137
+ if (fields.tip || fields.href || fields.sourceName || fields.filePath || fields.filePreviewUrl) {
138
+ return true
139
+ }
140
+ // [+n] / 仅序号圆点:开发前也可点出 popup(哪怕尚无批注文案)
141
+ if (Number.isFinite(fields.citationId) && fields.citationId > 0) return true
142
+ if (!fields.chunkId) return false
143
+ const ref = getChartStreamRef(fields.chunkId)
144
+ return !!(ref && (ref.sourceText || ref.sourceName || ref.filePath || ref.filePreviewUrl))
145
+ }
146
+
147
+ export function citationIndexFromRefOrDom(
148
+ fields: CitationDatasetFields,
149
+ fallbackId: number
150
+ ): number {
151
+ // 优先 REF.index(popup 序号);再用 DOM data-citation;禁止落到 0 当「有序号」
152
+ if (fields.chunkId) {
153
+ const ref = getChartStreamRef(fields.chunkId)
154
+ const idx = Number(ref?.index)
155
+ if (Number.isFinite(idx) && idx > 0) return Math.floor(idx)
156
+ }
157
+ if (Number.isFinite(fields.citationId) && fields.citationId > 0) {
158
+ return Math.floor(fields.citationId)
159
+ }
160
+ if (Number.isFinite(fallbackId) && fallbackId > 0) return Math.floor(fallbackId)
161
+ return 0
162
+ }
163
+ //0918
@@ -0,0 +1,32 @@
1
+ import type { genAiReportDataParams } from '../types'
2
+ import { RECENT_REPORTS, type RecentReport } from '../../components/RecentReportsTable.vue'
3
+ import { postGenAiRequest } from '../../common/utils/remote-request'
4
+
5
+ function isRecentReportList(data: unknown) {
6
+ return Array.isArray(data) && data.length > 0 && typeof data[0]?.id === 'string'
7
+ }
8
+
9
+ function fallbackRecentReports() {
10
+ return [...RECENT_REPORTS]
11
+ }
12
+
13
+ const genEntryApi = {
14
+ /** gen-entry: report list;網絡失敗或超時時回退 mock,不阻塞頁面 */
15
+ async fetchGenAiReportListData(data: genAiReportDataParams) {
16
+ try {
17
+ const response = await postGenAiRequest('/reportLatest', data)
18
+ if (isRecentReportList(response)) {
19
+ return response as RecentReport[]
20
+ }
21
+ } catch (error) {
22
+ console.error('獲取 fetchGenAiReportListData 失敗', error)
23
+ }
24
+ return fallbackRecentReports()
25
+ },
26
+
27
+ async fetchtest(data: unknown) {
28
+ return postGenAiRequest('/hello', data)
29
+ },
30
+ }
31
+
32
+ export default genEntryApi
@@ -0,0 +1,287 @@
1
+ <template>
2
+ <div class="industry-page">
3
+ <main ref="pageBodyRef" class="industry-page__body">
4
+ <section class="industry-hero">
5
+ <h2 class="industry-hero__title">AI產業分析報告</h2>
6
+ <p class="industry-hero__desc">
7
+ 基於你選擇的模型、行業與年份,並結合上傳或雲端引用的資料,自動生成結構化的風控分析報告。
8
+ </p>
9
+
10
+ <div class="industry-hero__actions">
11
+ <EntryHeroNavCards @select="handleHeroAction" />
12
+ </div>
13
+ </section>
14
+
15
+ <section class="industry-reports">
16
+ <h3 class="industry-reports__title">
17
+ <el-icon class="industry-reports__title-icon">
18
+ <Document />
19
+ </el-icon>
20
+ 最近的報告
21
+ </h3>
22
+ <RecentReportsTable ref="tableRef" :reports="displayedReports" @open="openReport" />
23
+ <a
24
+ v-if="showMoreLink"
25
+ href="#"
26
+ class="industry-reports__more"
27
+ @click.prevent="handleMoreReports"
28
+ >
29
+ 更多報告 &gt;&gt;
30
+ </a>
31
+ </section>
32
+ </main>
33
+ </div>
34
+ </template>
35
+
36
+ <script setup lang="ts">
37
+ import '../common/assets/fonts.css'
38
+ import { Document } from '@element-plus/icons-vue'
39
+ import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
40
+ import { useRouter } from 'vue-router'
41
+ import {
42
+ bindViewportBodyHeight,
43
+ lockDocumentScroll,
44
+ RECENT_REPORTS,
45
+ navigateToReportCenter,
46
+ openManagementCenter,
47
+ openModelManager,
48
+ openReportCenter,
49
+ openReportCreate,
50
+ RecentReportsTable,
51
+ type RecentReport,
52
+ type RecentReportsTableExpose,
53
+ } from '../common'
54
+ import EntryHeroNavCards, { type EntryHeroNavId } from '../components/EntryHeroNavCards.vue'
55
+ import genEntryApi from './api'
56
+
57
+ const DEFAULT_VISIBLE_ROWS = 10
58
+
59
+ const router = useRouter()
60
+ const recentReports = ref([...RECENT_REPORTS])
61
+
62
+ function isRecentReportList(data: unknown) {
63
+ return Array.isArray(data) && data.length > 0 && typeof data[0]?.id === 'string'
64
+ }
65
+
66
+ async function loadRecentReports() {
67
+ const data = await genEntryApi.fetchGenAiReportListData({})
68
+ if (isRecentReportList(data)) {
69
+ recentReports.value = data as RecentReport[]
70
+ }
71
+ }
72
+
73
+ const pageBodyRef = ref(null as HTMLElement | null)
74
+ const tableRef = ref<RecentReportsTableExpose | null>(null)
75
+
76
+ const displayedReports = computed(() => recentReports.value.slice(0, DEFAULT_VISIBLE_ROWS))
77
+
78
+ const showMoreLink = computed(() => recentReports.value.length > DEFAULT_VISIBLE_ROWS)
79
+
80
+ let cleanupBodyHeight: (() => void) | undefined
81
+ let cleanupLock: (() => void) | undefined
82
+ let resizeObserver: ResizeObserver | undefined
83
+ let measureRafId = 0
84
+
85
+ async function relayoutTable() {
86
+ await nextTick()
87
+ await new Promise((resolve) => {
88
+ cancelAnimationFrame(measureRafId)
89
+ measureRafId = requestAnimationFrame(() => {
90
+ measureRafId = requestAnimationFrame(() => resolve(undefined))
91
+ })
92
+ })
93
+ tableRef.value?.doLayout()
94
+ }
95
+
96
+ function scheduleRelayoutTable() {
97
+ cancelAnimationFrame(measureRafId)
98
+ measureRafId = requestAnimationFrame(() => {
99
+ void relayoutTable()
100
+ })
101
+ }
102
+
103
+ function handleMoreReports() {
104
+ navigateToReportCenter(router)
105
+ }
106
+
107
+ onMounted(() => {
108
+ void loadRecentReports()
109
+ if (pageBodyRef.value) {
110
+ cleanupBodyHeight = bindViewportBodyHeight(pageBodyRef.value)
111
+ resizeObserver = new ResizeObserver(() => scheduleRelayoutTable())
112
+ resizeObserver.observe(pageBodyRef.value)
113
+ }
114
+ cleanupLock = lockDocumentScroll()
115
+ window.addEventListener('resize', scheduleRelayoutTable)
116
+ scheduleRelayoutTable()
117
+ })
118
+
119
+ onUnmounted(() => {
120
+ cancelAnimationFrame(measureRafId)
121
+ resizeObserver?.disconnect()
122
+ window.removeEventListener('resize', scheduleRelayoutTable)
123
+ cleanupBodyHeight?.()
124
+ cleanupLock?.()
125
+ })
126
+
127
+ watch(displayedReports, () => {
128
+ scheduleRelayoutTable()
129
+ })
130
+
131
+ function handleHeroAction(id: EntryHeroNavId) {
132
+ if (id === 'new-report') {
133
+ openReportCreate(router)
134
+ }
135
+ if (id === 'report-sim') {
136
+ openReportCenter(router)
137
+ }
138
+ if (id === 'template-sim') {
139
+ openModelManager(router)
140
+ }
141
+ if (id === 'admin-sim') {
142
+ openManagementCenter(router)
143
+ }
144
+ }
145
+
146
+ function openReport(report: RecentReport) {
147
+ openModelManager(router, { id: report.id })
148
+ }
149
+ </script>
150
+
151
+ <style scoped>
152
+ .industry-page {
153
+ --gen-ai-design-w: 1920;
154
+ --gen-ai-fs-xs: clamp(11px, calc(12 * 100vw / 1920), 12px);
155
+ --gen-ai-fs-sm: clamp(12px, calc(13 * 100vw / 1920), 13px);
156
+ --gen-ai-fs-base: clamp(13px, calc(14 * 100vw / 1920), 14px);
157
+ --gen-ai-fs-md: clamp(14px, calc(16 * 100vw / 1920), 16px);
158
+ --gen-ai-fs-lg: clamp(16px, calc(18 * 100vw / 1920), 18px);
159
+ --gen-ai-fs-hero: clamp(26px, calc(32 * 100vw / 1920), 32px);
160
+ --gen-ai-lh-tight: 1.4;
161
+ --gen-ai-lh-normal: 1.6;
162
+ --gen-ai-lh-relaxed: 1.7;
163
+ --gen-ai-fw-semibold: 600;
164
+ --gen-ai-fw-bold: 700;
165
+ font-family: var(--gen-ai-font-family, 'Noto Sans', 'Noto Sans TC', sans-serif);
166
+ font-size: var(--gen-ai-fs-base);
167
+ line-height: var(--gen-ai-lh-normal);
168
+ color: #2d3139;
169
+ font-synthesis: none;
170
+ text-rendering: optimizeLegibility;
171
+ -webkit-font-smoothing: antialiased;
172
+ -moz-osx-font-smoothing: grayscale;
173
+ display: flex;
174
+ flex-direction: column;
175
+ height: 100vh;
176
+ overflow: hidden;
177
+ background: #fff;
178
+ }
179
+
180
+ .industry-page :deep(.el-table),
181
+ .industry-page :deep(.el-input),
182
+ .industry-page :deep(.el-select),
183
+ .industry-page :deep(.el-pagination) {
184
+ font-size: inherit;
185
+ }
186
+
187
+ .industry-page :deep(.el-button) {
188
+ font-size: 18px;
189
+ font-family: var(--gen-ai-font-family, 'Noto Sans', 'Noto Sans TC', sans-serif);
190
+ }
191
+
192
+ .industry-page__body {
193
+ flex: 1;
194
+ min-height: 0;
195
+ overflow: hidden;
196
+ display: flex;
197
+ flex-direction: column;
198
+ width: 100%;
199
+ padding: 48px 24px 40px;
200
+ box-sizing: border-box;
201
+ }
202
+
203
+ .industry-hero {
204
+ flex-shrink: 0;
205
+ text-align: center;
206
+ margin-bottom: 48px;
207
+ }
208
+
209
+ .industry-hero__title {
210
+ margin: 0 0 20px;
211
+ font-size: var(--gen-ai-fs-hero);
212
+ font-weight: var(--gen-ai-fw-bold);
213
+ color: #1a1a1a;
214
+ }
215
+
216
+ .industry-hero__desc {
217
+ margin: 0 0 8px;
218
+ font-size: 16px;
219
+ font-weight: 600;
220
+ line-height: var(--gen-ai-lh-relaxed);
221
+ color: #666;
222
+ }
223
+
224
+ .industry-hero__actions {
225
+ display: flex;
226
+ flex-wrap: wrap;
227
+ align-items: center;
228
+ justify-content: center;
229
+ gap: 16px;
230
+ margin-top: 28px;
231
+ }
232
+
233
+ .industry-reports {
234
+ width: 80%;
235
+ max-width: 80%;
236
+ margin: 0 auto;
237
+ padding: 0;
238
+ box-sizing: border-box;
239
+ flex: 1 1 auto;
240
+ min-height: 0;
241
+ display: flex;
242
+ flex-direction: column;
243
+ overflow: hidden;
244
+ }
245
+
246
+ .industry-reports :deep(.recent-reports-table) {
247
+ flex: 0 1 auto;
248
+ min-height: 0;
249
+ width: 100%;
250
+ }
251
+
252
+ .industry-reports__title {
253
+ display: inline-flex;
254
+ align-items: center;
255
+ gap: 8px;
256
+ margin: 0 0 16px;
257
+ padding: 0;
258
+ font-size: 18px;
259
+ font-weight: var(--gen-ai-fw-semibold);
260
+ color: #1a1a1a;
261
+ text-align: left;
262
+ width: 100%;
263
+ flex-shrink: 0;
264
+ }
265
+
266
+ .industry-reports__title-icon {
267
+ font-size: var(--gen-ai-fs-lg);
268
+ color: #606266;
269
+ }
270
+
271
+ .industry-reports__more {
272
+ display: inline-block;
273
+ margin: 12px 0 0;
274
+ padding: 0;
275
+ font-size: var(--gen-ai-fs-base);
276
+ color: #409eff;
277
+ text-decoration: none;
278
+ cursor: pointer;
279
+ text-align: left;
280
+ flex-shrink: 0;
281
+ }
282
+
283
+ .industry-reports__more:hover {
284
+ color: #66b1ff;
285
+ text-decoration: none;
286
+ }
287
+ </style>
@@ -0,0 +1,4 @@
1
+ /** gen-entry 報告列表請求參數;usmRight 不傳表示全部 */
2
+ export interface genAiReportDataParams {
3
+ usmRight?: string
4
+ }
package/gen-ai/i.mark ADDED
@@ -0,0 +1,2 @@
1
+ pnpm add jszip@^3.10.1 file-saver@^2.0.5 html2canvas@^1.4.1 marked@^9
2
+ pnpm add -D @types/file-saver