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,101 @@
1
+ /** /api/v1/sse/aiStream Mock(EventStream 格式,与真实接口一致) */
2
+ export const REPORT_STREAM_API_PATH = '/api/v1/sse/aiStream'
3
+
4
+ export interface GenerateReportParams {
5
+ userId?: string
6
+ question?: string
7
+ chapters?: string[]
8
+ chapterVersions?: Record<string, string>
9
+ reportMode?: string
10
+ }
11
+
12
+ export const MOCK_REPORT_STREAM_TEXT = `# 行业分析报告(Mock)
13
+
14
+ ## 摘要與本年總結
15
+
16
+ 本报告为本地 Mock SSE 流式输出,用于演示「生成报告预览」区域的流式接收与打字机展示效果。接入后端后,正文将由 \`/api/v1/sse/aiStream\` 返回的真实模型输出替换。
17
+
18
+ 从本期经营表现看,行业整体维持温和复苏态势,头部企业集中度进一步提升,中小主体在融资与订单获取方面仍面临一定压力。信贷资产质量总体可控,但部分细分领域的信用风险需持续跟踪。
19
+
20
+ 展望下一阶段,建议在授信策略上兼顾增长与合规,关注政策边际变化对行业景气度的传导。本段为 Mock 占位文本,篇幅约为原版的数倍,便于验证长文滚动与分段输出体验。
21
+
22
+ ## 宏觀環境與政策背景
23
+
24
+ 宏观政策延续稳健基调,流动性环境相对友好,行业监管框架逐步完善。利率与汇率波动对进出口型企业的成本结构产生阶段性影响,需结合客户敞口进行动态评估。
25
+
26
+ 产业政策方面,绿色转型与数字化升级仍是重点方向,相关补贴与标准体系持续出台。金融机构在业务拓展中应关注客户是否符合最新监管分类及 ESG 披露要求。
27
+
28
+ 国际环境不确定性仍存,供应链重构与地缘政治因素可能扰动部分原材料价格。本节 Mock 内容仅作预览填充,实际报告将依据所选章节与版本参数生成对应分析段落。`
29
+
30
+ function buildChapterMockContent(label: string, index: number): string {
31
+ const n = index + 1
32
+ return [
33
+ `(Mock)第 ${n} 章「${label}」——本节为本地预览占位,模拟真实 SSE 推送时的章节标题与开篇段落结构。`,
34
+ `结合本期行业数据,相关核心指标呈现结构性分化:产能利用率、库存周转与价格传导在不同细分赛道间差异明显。政策端强调风险可控与高质量发展并重,授信审批需关注客户合规资质与现金流覆盖能力。`,
35
+ `从业务视角看,建议动态跟踪宏观周期、监管细则落地节奏及同业竞争格局变化,适时调整资产组合与行业限额。本段 Mock 文本用于演示打字机效果与长文滚动,接入后端后将由模型按所选版本生成正式正文。`,
36
+ ].join('\n\n') + '\n'
37
+ }
38
+
39
+ export function buildMockStreamText(params: GenerateReportParams): string {
40
+ const chapters = params.chapters?.length
41
+ ? params.chapters
42
+ .map((label, i) => `## ${label}\n\n${buildChapterMockContent(label, i)}`)
43
+ .join('\n')
44
+ : MOCK_REPORT_STREAM_TEXT
45
+
46
+ return `# 生成报告预览(Mock)\n\n**模式**:${params.reportMode === 'rewrite' ? '重寫整篇報告' : '拼裝並潤色'}\n\n**问题**:${params.question ?? ''}\n\n${chapters}`
47
+ }
48
+
49
+ export function encodeSseBlock(event: string, data: string): string {
50
+ const lines = data.split('\n').map((line) => `data: ${line}`)
51
+ return `event: ${event}\n${lines.join('\n')}\n\n`
52
+ }
53
+
54
+ /** 将报告正文拆成多段 event:text,模拟真实 SSE 推送 */
55
+ export function buildMockSsePayload(params: GenerateReportParams): string[] {
56
+ const text = buildMockStreamText(params)
57
+ const chunkSize = 24
58
+ const parts: string[] = []
59
+ for (let i = 0; i < text.length; i += chunkSize) {
60
+ parts.push(encodeSseBlock('text', text.slice(i, i + chunkSize)))
61
+ }
62
+ parts.push(encodeSseBlock('end', ''))
63
+ return parts
64
+ }
65
+
66
+ const MOCK_CHUNK_DELAY_MS = 80
67
+
68
+ /** Mock 完整 SSE Response(走与线上一致的 postStreamRequest → streamPostSse 链路) */
69
+ export function createMockReportSseResponse(
70
+ params: GenerateReportParams,
71
+ signal?: AbortSignal,
72
+ ): Response {
73
+ const payload = buildMockSsePayload(params)
74
+ const encoder = new TextEncoder()
75
+ let index = 0
76
+
77
+ const stream = new ReadableStream<Uint8Array>({
78
+ async pull(controller) {
79
+ if (signal?.aborted) {
80
+ controller.close()
81
+ return
82
+ }
83
+ if (index >= payload.length) {
84
+ controller.close()
85
+ return
86
+ }
87
+ controller.enqueue(encoder.encode(payload[index]!))
88
+ index += 1
89
+ await new Promise((resolve) => setTimeout(resolve, MOCK_CHUNK_DELAY_MS))
90
+ },
91
+ })
92
+
93
+ return new Response(stream, {
94
+ status: 200,
95
+ headers: {
96
+ 'Content-Type': 'text/event-stream; charset=utf-8',
97
+ 'Cache-Control': 'no-cache',
98
+ Connection: 'keep-alive',
99
+ },
100
+ })
101
+ }
@@ -0,0 +1,402 @@
1
+ <!--
2
+ industry-analysis 单文件版(含 PageHeader、openTemplateCenter、app-btn 样式、报告列表数据)
3
+ 路由示例:{ path: '/industry-analysis', component: () => import('@/test/test1.vue') }
4
+ 环境变量:
5
+ VITE_TEMPLATE_CENTER_URL — 新建报告跳转(默认 router TemplateCenter → test2.vue)
6
+ VITE_MODEL_MANAGER_URL — 模型管理跳转(默认同域 /model-manager)
7
+ -->
8
+ <template>
9
+ <div class="industry-page">
10
+ <header class="page-header">
11
+ <h1 class="page-header__title">IR-DEMO</h1>
12
+ </header>
13
+
14
+ <main ref="pageBodyRef" class="industry-page__body">
15
+ <section class="industry-hero">
16
+ <h2 class="industry-hero__title">AI产业分析報告</h2>
17
+ <p class="industry-hero__desc">
18
+ 基於你選擇的模型、行業與年份,並結合上傳或雲端引用的資料,自動生成結構化的風控分析報告。
19
+ </p>
20
+ <p class="industry-hero__desc">
21
+ 你可以從標準模版開始,逐章生成與調整內容,最終輸出可複用、可審閱的完整報告。
22
+ </p>
23
+
24
+ <div class="industry-hero__actions">
25
+ <button v-for="action in heroActions" :key="action.id" type="button" class="app-btn"
26
+ @click="handleHeroAction(action)">
27
+ {{ action.label }}
28
+ </button>
29
+ </div>
30
+ </section>
31
+
32
+ <section ref="reportsScrollRef" class="industry-reports industry-reports--scroll">
33
+ <h3 class="industry-reports__title">最近的報告</h3>
34
+ <el-table :data="recentReports" :fit="false" table-layout="auto" class="industry-reports__table"
35
+ :header-cell-style="{ color: '#1a1a1a' }">
36
+ <el-table-column prop="name" label="報告名稱" align="left" header-align="left">
37
+ <template #default="{ row }">
38
+ <a v-if="row.canOpen" href="#" class="industry-report-name industry-report-name--link"
39
+ @click.prevent="openReport(row)">{{ row.name }}</a>
40
+ <span v-else class="industry-report-name">{{ row.name }}</span>
41
+ </template>
42
+ </el-table-column>
43
+ <el-table-column prop="industry" label="行業" align="left" header-align="left" />
44
+ <el-table-column prop="year" label="年份" align="left" header-align="left" />
45
+ <el-table-column prop="status" label="狀態" align="left" header-align="left" />
46
+ <el-table-column prop="initiator" label="发起人" align="left" header-align="left" />
47
+ <el-table-column prop="editor" label="編輯" align="left" header-align="left" />
48
+ <el-table-column prop="permission" label="我的权限" align="left" header-align="left" />
49
+ <el-table-column prop="updatedAt" label="最近更新" align="left" header-align="left" />
50
+ </el-table>
51
+ <a href="#" class="industry-reports__more" @click.prevent>更多報告 &gt;&gt;</a>
52
+ </section>
53
+ </main>
54
+ </div>
55
+ </template>
56
+
57
+ <script setup lang="ts">
58
+ import { ref, onMounted, onUnmounted } from 'vue'
59
+ import { useRouter } from 'vue-router'
60
+ import { bindViewportBodyHeight } from '@/utils/gen-ai-scroll'
61
+ import { setupPageScroll } from '@/utils/pageScrollbar'
62
+
63
+ const router = useRouter()
64
+ const pageBodyRef = ref<HTMLElement | null>(null)
65
+ const reportsScrollRef = ref<HTMLElement | null>(null)
66
+
67
+ let cleanupBodyHeight: (() => void) | undefined
68
+ let cleanupPageScroll: (() => void) | undefined
69
+
70
+ onMounted(() => {
71
+ if (pageBodyRef.value) {
72
+ cleanupBodyHeight = bindViewportBodyHeight(pageBodyRef.value, {
73
+ subtractSelector: '.page-header',
74
+ subtractRoot: pageBodyRef.value.parentElement ?? undefined,
75
+ })
76
+ }
77
+ if (reportsScrollRef.value) {
78
+ cleanupPageScroll = setupPageScroll({
79
+ containers: [reportsScrollRef.value],
80
+ size: 20,
81
+ lockDocumentScroll: true,
82
+ })
83
+ }
84
+ })
85
+
86
+ onUnmounted(() => {
87
+ cleanupBodyHeight?.()
88
+ cleanupPageScroll?.()
89
+ })
90
+
91
+ const heroActions = [
92
+ { id: 'new-report', label: '新建報告' },
93
+ { id: 'report-sim', label: '報告模擬' },
94
+ { id: 'template-sim', label: '模板模擬' },
95
+ { id: 'admin-sim', label: '管理模擬' },
96
+ ] as const
97
+
98
+ interface RecentReport {
99
+ id: string
100
+ name: string
101
+ industry: string
102
+ year: string
103
+ status: string
104
+ initiator: string
105
+ editor: string
106
+ permission: string
107
+ updatedAt: string
108
+ canOpen: boolean
109
+ }
110
+
111
+ const recentReports: RecentReport[] = [
112
+ {
113
+ id: '1',
114
+ name: '深圳房地產風控年報 - 2024',
115
+ industry: '房地產',
116
+ year: '2025',
117
+ status: '草稿',
118
+ initiator: '陳大文 (单位 xxxx)',
119
+ editor: '陳1文 (单位 xxxx) , 陳2文 (单位 xxxx) , 陳3文 (单位 xxxx) ...',
120
+ permission: '可編輯',
121
+ updatedAt: '3天前',
122
+ canOpen: true,
123
+ },
124
+ {
125
+ id: '2',
126
+ name: '深圳房地產風控年報 - 2024',
127
+ industry: '房地產',
128
+ year: '2024',
129
+ status: '已生成',
130
+ initiator: '陳中文 (单位 yyyy)',
131
+ editor: '陳4文 (单位 yyyy) , 陳5文 (单位 yyyy) ...',
132
+ permission: '无权限',
133
+ updatedAt: '3天前',
134
+ canOpen: false,
135
+ },
136
+ {
137
+ id: '3',
138
+ name: '深圳房地產風控年報 - 2024',
139
+ industry: '房地產',
140
+ year: '2023',
141
+ status: '已導出',
142
+ initiator: '陳小文 (单位 zzzz)',
143
+ editor: '陳6文 (单位 zzzz)',
144
+ permission: '可編輯',
145
+ updatedAt: '3天前',
146
+ canOpen: true,
147
+ },
148
+ ]
149
+
150
+ /** 打开 Template Center / test2.vue(优先 VITE_TEMPLATE_CENTER_URL,否则同域 /template-center) */
151
+ function openTemplateCenter() {
152
+ const configured = import.meta.env.VITE_TEMPLATE_CENTER_URL?.trim()
153
+ const url = configured || router.resolve({ name: 'TemplateCenter' }).href
154
+ window.open(url, '_blank')
155
+ }
156
+
157
+ /** 打开模型管理(优先 VITE_MODEL_MANAGER_URL,否则同域 /model-manager) */
158
+ function openReport(report: RecentReport) {
159
+ const configured = import.meta.env.VITE_MODEL_MANAGER_URL?.trim()
160
+ const url = configured
161
+ ? `${configured}${configured.includes('?') ? '&' : '?'}id=${encodeURIComponent(report.id)}`
162
+ : router.resolve({ name: 'model-manager', query: { id: report.id } }).href
163
+ window.open(url, '_blank')
164
+ }
165
+
166
+ function handleHeroAction(action: (typeof heroActions)[number]) {
167
+ if (action.id === 'new-report') {
168
+ openTemplateCenter()
169
+ }
170
+ }
171
+ </script>
172
+
173
+ <style scoped>
174
+ /* —— PageHeader(原 components/PageHeader.vue)—— */
175
+ .page-header {
176
+ flex-shrink: 0;
177
+ height: 62px;
178
+ display: flex;
179
+ align-items: center;
180
+ padding: 0 24px;
181
+ background: #fff;
182
+ border-bottom: 1px solid #e8eaec;
183
+ box-shadow: none;
184
+ }
185
+
186
+ .page-header__title {
187
+ margin: 0;
188
+ font-size: 16px;
189
+ font-weight: 600;
190
+ color: #2d3139;
191
+ line-height: 1;
192
+ }
193
+
194
+ /* —— app-btn(原 styles/variables.css + app-button.css)—— */
195
+ .industry-page {
196
+ --app-btn-color: #fff;
197
+ --app-btn-color-hover: #c53355;
198
+ --app-btn-bg: #c53355;
199
+ --app-btn-bg-hover: #fff;
200
+ --app-btn-border: #c53355;
201
+ --app-btn-border-hover: #c53355;
202
+ --app-btn-radius: 5px;
203
+ --app-btn-font-size: 15px;
204
+ --app-btn-font-weight: 600;
205
+ --app-btn-padding-y: 8px;
206
+ --app-btn-padding-x: 15px;
207
+ --app-btn-min-width: 120px;
208
+
209
+ display: flex;
210
+ flex-direction: column;
211
+ height: 100vh;
212
+ overflow: hidden;
213
+ background: #fff;
214
+ }
215
+
216
+ .app-btn {
217
+ min-width: var(--app-btn-min-width);
218
+ padding: var(--app-btn-padding-y) var(--app-btn-padding-x);
219
+ border: 1px solid var(--app-btn-border);
220
+ border-radius: var(--app-btn-radius);
221
+ background: var(--app-btn-bg);
222
+ color: var(--app-btn-color);
223
+ font-size: var(--app-btn-font-size);
224
+ font-weight: var(--app-btn-font-weight);
225
+ line-height: 1.4;
226
+ font-family: inherit;
227
+ cursor: pointer;
228
+ transition: all 0.2s ease;
229
+ }
230
+
231
+ .app-btn:hover {
232
+ background: var(--app-btn-bg-hover);
233
+ border-color: var(--app-btn-border-hover);
234
+ color: var(--app-btn-color-hover);
235
+ }
236
+
237
+ .industry-page__body {
238
+ flex: 1;
239
+ min-height: 0;
240
+ overflow: hidden;
241
+ display: flex;
242
+ flex-direction: column;
243
+ width: 100%;
244
+ padding: 48px 24px 40px;
245
+ box-sizing: border-box;
246
+ }
247
+
248
+ .industry-hero {
249
+ flex-shrink: 0;
250
+ text-align: center;
251
+ margin-bottom: 48px;
252
+ }
253
+
254
+ .industry-hero__title {
255
+ margin: 0 0 20px;
256
+ font-size: 28px;
257
+ font-weight: 700;
258
+ color: #1a1a1a;
259
+ }
260
+
261
+ .industry-hero__desc {
262
+ margin: 0 0 8px;
263
+ font-size: 14px;
264
+ line-height: 1.7;
265
+ color: #666;
266
+ }
267
+
268
+ .industry-hero__actions {
269
+ display: flex;
270
+ flex-wrap: wrap;
271
+ align-items: center;
272
+ justify-content: center;
273
+ gap: 16px;
274
+ margin-top: 28px;
275
+ }
276
+
277
+ .industry-reports {
278
+ width: fit-content;
279
+ max-width: 100%;
280
+ margin: 0 auto;
281
+ padding: 0;
282
+ }
283
+
284
+ .industry-reports--scroll {
285
+ flex: 1;
286
+ min-height: 0;
287
+ overflow-y: auto;
288
+ overflow-x: auto;
289
+ }
290
+
291
+ .industry-reports__title {
292
+ margin: 0;
293
+ padding: 0;
294
+ font-size: 16px;
295
+ font-weight: 600;
296
+ color: #909399;
297
+ }
298
+
299
+ .industry-reports__table {
300
+ width: max-content;
301
+ margin: 0;
302
+ padding: 0;
303
+ --el-table-border: none;
304
+ --el-table-border-color: transparent;
305
+ }
306
+
307
+ .industry-reports__table :deep(.el-table) {
308
+ --el-table-header-text-color: #1a1a1a;
309
+ }
310
+
311
+ .industry-reports__table :deep(.el-table__inner-wrapper),
312
+ .industry-reports__table :deep(.el-table__header-wrapper),
313
+ .industry-reports__table :deep(.el-table__body-wrapper) {
314
+ margin-left: 0;
315
+ padding-left: 0;
316
+ }
317
+
318
+ .industry-reports__table :deep(table) {
319
+ width: auto;
320
+ table-layout: auto;
321
+ }
322
+
323
+ .industry-reports__table :deep(thead th.el-table__cell > .cell) {
324
+ color: #1a1a1a;
325
+ }
326
+
327
+ .industry-reports__table :deep(thead th.el-table__cell:first-child > .cell) {
328
+ margin-left: -12px;
329
+ }
330
+
331
+ .industry-reports__table :deep(.el-table__header .cell),
332
+ .industry-reports__table :deep(.el-table__body .cell) {
333
+ white-space: nowrap;
334
+ text-align: left;
335
+ }
336
+
337
+ .industry-reports__table :deep(.el-table__inner-wrapper::before),
338
+ .industry-reports__table :deep(.el-table__inner-wrapper::after) {
339
+ display: none;
340
+ }
341
+
342
+ .industry-reports__table :deep(.el-table__body tr) {
343
+ background: #fff;
344
+ }
345
+
346
+ .industry-reports__table :deep(.el-table__body tr:hover > td.el-table__cell) {
347
+ background: #f5f7fa;
348
+ }
349
+
350
+ .industry-reports__table :deep(.el-table__header th.el-table__cell) {
351
+ font-weight: 600;
352
+ border-bottom: none;
353
+ }
354
+
355
+ .industry-reports__table :deep(.el-table__header th.el-table__cell:first-child),
356
+ .industry-reports__table :deep(.el-table__body td.el-table__cell:first-child) {
357
+ padding-left: 0;
358
+ }
359
+
360
+ .industry-reports__table :deep(.el-table__header th.el-table__cell:first-child .cell),
361
+ .industry-reports__table :deep(.el-table__body td.el-table__cell:first-child .cell) {
362
+ padding: 0;
363
+ }
364
+
365
+ .industry-reports__table :deep(.el-table__body td.el-table__cell) {
366
+ border-bottom: none;
367
+ }
368
+
369
+ .industry-reports__table :deep(.el-table__body td.el-table__cell:not(:first-child) .cell) {
370
+ color: #2d3139;
371
+ }
372
+
373
+ .industry-report-name {
374
+ color: #909399;
375
+ }
376
+
377
+ .industry-report-name--link {
378
+ color: #409eff;
379
+ text-decoration: none;
380
+ cursor: pointer;
381
+ }
382
+
383
+ .industry-report-name--link:hover {
384
+ color: #66b1ff;
385
+ text-decoration: none;
386
+ }
387
+
388
+ .industry-reports__more {
389
+ display: inline-block;
390
+ margin: 12px 0 0;
391
+ padding: 0;
392
+ font-size: 14px;
393
+ color: #409eff;
394
+ text-decoration: none;
395
+ cursor: pointer;
396
+ }
397
+
398
+ .industry-reports__more:hover {
399
+ color: #66b1ff;
400
+ text-decoration: none;
401
+ }
402
+ </style>