appsnbcbweicheng 1.2.25 → 1.2.27

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.
@@ -1,1067 +0,0 @@
1
- <template>
2
- <div class="event-interpretation">
3
- <!-- 筛选区域 -->
4
- <el-card class="filter-card" shadow="never">
5
- <el-form
6
- :inline="true"
7
- :model="searchForm"
8
- class="search-form"
9
- label-width="120px"
10
- size="small"
11
- >
12
- <el-form-item label="事件标题">
13
- <el-input
14
- v-model="searchForm.eventTitle"
15
- placeholder="请输入事件标题"
16
- clearable
17
- :maxlength="128"
18
- show-word-limit
19
- />
20
- </el-form-item>
21
- <el-form-item label="事件内容">
22
- <el-input
23
- v-model="searchForm.eventContent"
24
- placeholder="请输入事件内容"
25
- clearable
26
- :maxlength="128"
27
- show-word-limit
28
- />
29
- </el-form-item>
30
- <el-form-item label="资产类别">
31
- <el-select
32
- v-model="searchForm.assetCategory"
33
- multiple
34
- filterable
35
- placeholder="请选择资产类别"
36
- clearable
37
- >
38
- <el-option
39
- v-for="item in assetCategoryOptions"
40
- :key="item.value"
41
- :label="item.label"
42
- :value="item.value"
43
- />
44
- </el-select>
45
- <el-button type="primary" size="small" @click="openAssetConfigDialog">
46
- 编辑资产类别
47
- </el-button>
48
- </el-form-item>
49
-
50
- <el-form-item v-show="filterExpanded" label="事件情绪">
51
- <el-select v-model="searchForm.eventSentiment" placeholder="请选择" clearable>
52
- <el-option
53
- v-for="item in eventSentimentOptions"
54
- :key="item.value"
55
- :label="item.label"
56
- :value="item.value"
57
- />
58
- </el-select>
59
- </el-form-item>
60
- <el-form-item v-show="filterExpanded" label="板块相关性">
61
- <el-select v-model="searchForm.impact" placeholder="请选择" clearable>
62
- <el-option
63
- v-for="item in impactOptions"
64
- :key="item.value"
65
- :label="item.label"
66
- :value="item.value"
67
- />
68
- </el-select>
69
- </el-form-item>
70
- <el-form-item v-show="filterExpanded" label="综合影响力">
71
- <el-select v-model="searchForm.influence" placeholder="请选择" clearable>
72
- <el-option
73
- v-for="item in influenceOptions"
74
- :key="item.value"
75
- :label="item.label"
76
- :value="item.value"
77
- />
78
- </el-select>
79
- </el-form-item>
80
- <el-form-item v-show="filterExpanded" label="资讯发布时间">
81
- <el-date-picker
82
- v-model="searchForm.infoPublishTimeRange"
83
- type="daterange"
84
- range-separator="至"
85
- start-placeholder="开始日期"
86
- end-placeholder="结束日期"
87
- value-format="yyyy-MM-dd"
88
- clearable
89
- />
90
- </el-form-item>
91
- <el-form-item v-show="filterExpanded" label="解读发布时间">
92
- <el-date-picker
93
- v-model="searchForm.explainTimeRange"
94
- type="daterange"
95
- range-separator="至"
96
- start-placeholder="开始日期"
97
- end-placeholder="结束日期"
98
- value-format="yyyy-MM-dd"
99
- clearable
100
- />
101
- </el-form-item>
102
- <el-form-item class="form-actions">
103
- <el-button type="primary" @click="handleSearch">查询</el-button>
104
- <el-button @click="handleReset">重置</el-button>
105
- <el-button type="text" @click="toggleFilterExpanded">{{
106
- filterExpanded ? '收回' : '展开'
107
- }}</el-button>
108
- </el-form-item>
109
- </el-form>
110
- </el-card>
111
-
112
- <!-- 展示区域 -->
113
- <el-card class="display-card" shadow="never">
114
- <!-- 描述部分 -->
115
- <div class="description-section">
116
- <div class="description-left">
117
- <span class="fund-summary">{{ pageSummary }}</span>
118
- </div>
119
- <div class="description-right">
120
- <span class="text">
121
- <el-link type="primary" :underline="false" @click="handleFilterToday">{{
122
- formatDateCn(dailyStatsDate)
123
- }}</el-link>
124
- 新增{{ dailyStatsAddedCount }}条数据,{{ dailyStatsUnprocessedCount }}条未操作。
125
- </span>
126
- <el-button type="primary" size="small" @click="openCreateDialog">新增</el-button>
127
- <el-button type="primary" size="small" @click="openStatisticsDialog">数据总量</el-button>
128
- </div>
129
- </div>
130
-
131
- <!-- 表格 -->
132
- <el-table
133
- :data="tableData"
134
- border
135
- stripe
136
- class="result-table"
137
- size="small"
138
- :default-sort="{ prop: 'explainTime', order: 'descending' }"
139
- @sort-change="handleSortChange"
140
- >
141
- <!-- 冻结列:A/B/C(序号、事件标题、事件内容) -->
142
- <el-table-column type="index" label="序号" width="60" fixed="left" />
143
- <el-table-column prop="eventTitle" label="事件标题" min-width="220" fixed="left" />
144
- <el-table-column prop="eventContent" label="事件内容" min-width="260" fixed="left">
145
- <template slot-scope="{ row }">
146
- <div class="expandable-content">
147
- <div
148
- :class="{
149
- 'content-collapse': !row.expandEventContent,
150
- 'content-expanded': row.expandEventContent,
151
- }"
152
- >
153
- {{ row.eventContent }}
154
- </div>
155
- <el-button
156
- v-if="shouldShowExpand(row.eventContent)"
157
- type="text"
158
- size="mini"
159
- @click="toggleExpand(row, 'eventContent')"
160
- >
161
- {{ row.expandEventContent ? '收起' : '展开' }}
162
- </el-button>
163
- </div>
164
- </template>
165
- </el-table-column>
166
- <el-table-column prop="eventSummary" label="事件摘要" min-width="220">
167
- <template slot-scope="{ row }">
168
- <div class="expandable-content">
169
- <div
170
- :class="{
171
- 'content-collapse': !row.expandEventSummary,
172
- 'content-expanded': row.expandEventSummary,
173
- }"
174
- >
175
- {{ row.eventSummary }}
176
- </div>
177
- <el-button
178
- v-if="shouldShowExpand(row.eventSummary)"
179
- type="text"
180
- size="mini"
181
- @click="toggleExpand(row, 'eventSummary')"
182
- >
183
- {{ row.expandEventSummary ? '收起' : '展开' }}
184
- </el-button>
185
- </div>
186
- </template>
187
- </el-table-column>
188
- <el-table-column prop="assetCategory" label="资产类别" min-width="120" />
189
- <el-table-column prop="assetName" label="资产名称" min-width="150" />
190
- <el-table-column prop="eventSentiment" label="事件情绪" min-width="100" />
191
- <el-table-column prop="rEventInterpretation" label="事件完整解读" min-width="220" />
192
- <el-table-column prop="interpretation" label="事件100字解读" min-width="200" />
193
- <el-table-column prop="impact" label="板块相关性" min-width="110" />
194
- <el-table-column prop="influence" label="综合影响力" min-width="110" />
195
- <el-table-column prop="importanceScore" label="重要性分数" min-width="100" />
196
- <el-table-column
197
- prop="infoPublishTime"
198
- label="资讯发布时间"
199
- width="120"
200
- sortable="custom"
201
- />
202
- <el-table-column prop="explainTime" label="解读发布时间" width="120" sortable="custom" />
203
- <el-table-column label="操作" width="180" fixed="right">
204
- <template slot-scope="{ row }">
205
- <el-button type="text" size="mini" @click="openViewDialog(row)">查看详情</el-button>
206
- <el-button type="text" size="mini" @click="openEditDialog(row)">编辑</el-button>
207
- <el-button
208
- type="text"
209
- size="mini"
210
- class="danger-text-btn"
211
- @click="handleDisable(row)"
212
- >{{ row.disabled ? '已停用' : '停用' }}</el-button
213
- >
214
- </template>
215
- </el-table-column>
216
- </el-table>
217
- <div class="table-pagination">
218
- <el-pagination
219
- background
220
- @size-change="handlePageSizeChange"
221
- @current-change="handlePageChange"
222
- :current-page="pagination.currentPage"
223
- :page-sizes="[10, 20, 50, 100]"
224
- :page-size="pagination.pageSize"
225
- layout="total, sizes, prev, pager, next, jumper"
226
- :total="pagination.total"
227
- />
228
- </div>
229
- </el-card>
230
-
231
- <!-- 数据统计弹窗 -->
232
- <el-dialog
233
- title="数据总量"
234
- :visible.sync="statisticsDialogVisible"
235
- width="1000px"
236
- :close-on-click-modal="false"
237
- >
238
- <div class="statistics-bottom">
239
- <el-table :data="totalTableData" border style="width: 100%; margin-bottom: 20px">
240
- <el-table-column type="index" label="序号" width="80" />
241
- <el-table-column prop="assetCategory" label="资产类别" min-width="120" />
242
- <el-table-column prop="assetName" label="资产名称" min-width="160" />
243
- <el-table-column prop="eventNums" label="数据供给" min-width="100" />
244
- <el-table-column prop="eventCountRate" label="占总量比" min-width="100" />
245
- <el-table-column prop="auditRate" label="审核完成率" min-width="110" />
246
- <el-table-column prop="auditApprovedRate" label="审核通过率" min-width="110" />
247
- </el-table>
248
- </div>
249
-
250
- <span slot="footer" class="dialog-footer">
251
- <el-button @click="statisticsDialogVisible = false">关 闭</el-button>
252
- </span>
253
- </el-dialog>
254
-
255
- <!-- 查看详情弹窗 -->
256
- <el-dialog
257
- :title="detailDialogTitle"
258
- :visible.sync="detailDialogVisible"
259
- width="800px"
260
- :close-on-click-modal="false"
261
- >
262
- <el-form
263
- v-if="detailForm"
264
- :model="detailForm"
265
- label-width="140px"
266
- size="small"
267
- class="detail-form"
268
- >
269
- <el-form-item label="事件标题">
270
- <el-input
271
- v-model="detailForm.eventTitle"
272
- :disabled="detailReadOnly"
273
- :maxlength="128"
274
- show-word-limit
275
- />
276
- </el-form-item>
277
- <el-form-item label="事件内容" class="full-row">
278
- <el-input
279
- v-model="detailForm.eventContent"
280
- :disabled="detailReadOnly"
281
- type="textarea"
282
- :rows="2"
283
- />
284
- </el-form-item>
285
- <el-form-item label="事件摘要" class="full-row">
286
- <el-input
287
- v-model="detailForm.eventSummary"
288
- :disabled="detailReadOnly"
289
- type="textarea"
290
- :rows="2"
291
- />
292
- </el-form-item>
293
- <el-form-item label="资产类别">
294
- <el-select
295
- v-model="detailForm.assetCategory"
296
- :disabled="detailReadOnly"
297
- filterable
298
- clearable
299
- placeholder="请选择"
300
- >
301
- <el-option
302
- v-for="item in assetCategoryOptions"
303
- :key="item.value"
304
- :label="item.label"
305
- :value="item.value"
306
- />
307
- </el-select>
308
- </el-form-item>
309
- <el-form-item label="资产名称">
310
- <el-input v-model="detailForm.assetName" :disabled="detailReadOnly" />
311
- </el-form-item>
312
- <el-form-item label="事件情绪">
313
- <el-select
314
- v-model="detailForm.eventSentiment"
315
- :disabled="detailReadOnly"
316
- clearable
317
- placeholder="请选择"
318
- >
319
- <el-option
320
- v-for="item in eventSentimentOptions"
321
- :key="item.value"
322
- :label="item.label"
323
- :value="item.value"
324
- />
325
- </el-select>
326
- </el-form-item>
327
- <el-form-item label="事件完整解读" class="full-row">
328
- <el-input
329
- v-model="detailForm.rEventInterpretation"
330
- :disabled="detailReadOnly"
331
- type="textarea"
332
- :rows="2"
333
- />
334
- </el-form-item>
335
- <el-form-item label="事件100字解读" class="full-row">
336
- <el-input
337
- v-model="detailForm.interpretation"
338
- :disabled="detailReadOnly"
339
- type="textarea"
340
- :rows="2"
341
- />
342
- </el-form-item>
343
- <el-form-item label="板块相关性">
344
- <el-select
345
- v-model="detailForm.impact"
346
- :disabled="detailReadOnly"
347
- clearable
348
- placeholder="请选择"
349
- >
350
- <el-option
351
- v-for="item in impactOptions"
352
- :key="item.value"
353
- :label="item.label"
354
- :value="item.value"
355
- />
356
- </el-select>
357
- </el-form-item>
358
- <el-form-item label="综合影响力">
359
- <el-select
360
- v-model="detailForm.influence"
361
- :disabled="detailReadOnly"
362
- clearable
363
- placeholder="请选择"
364
- >
365
- <el-option
366
- v-for="item in influenceOptions"
367
- :key="item.value"
368
- :label="item.label"
369
- :value="item.value"
370
- />
371
- </el-select>
372
- </el-form-item>
373
- <el-form-item label="重要性分数">
374
- <el-input v-model="detailForm.importanceScore" :disabled="detailReadOnly" />
375
- </el-form-item>
376
- <el-form-item label="资讯发布时间">
377
- <el-date-picker
378
- v-model="detailForm.infoPublishTime"
379
- :disabled="detailReadOnly"
380
- type="date"
381
- value-format="yyyy-MM-dd"
382
- clearable
383
- />
384
- </el-form-item>
385
- <el-form-item label="解读发布时间">
386
- <el-date-picker
387
- v-model="detailForm.explainTime"
388
- :disabled="detailReadOnly"
389
- type="date"
390
- value-format="yyyy-MM-dd"
391
- clearable
392
- />
393
- </el-form-item>
394
- </el-form>
395
- <span slot="footer" class="dialog-footer">
396
- <el-button @click="detailDialogVisible = false">取 消</el-button>
397
- <el-button v-if="!detailReadOnly" type="primary" @click="handleDetailSave">保 存</el-button>
398
- </span>
399
- </el-dialog>
400
-
401
- <AssetClassConfiguration
402
- :visible.sync="assetConfigVisible"
403
- :initial-data="assetClassData"
404
- @confirm="handleAssetConfigConfirm"
405
- />
406
- </div>
407
- </template>
408
-
409
- <script>
410
- import AssetClassConfiguration from './AssetClassConfiguration.vue'
411
-
412
- export default {
413
- name: 'EventInterpretation',
414
- components: { AssetClassConfiguration },
415
- data() {
416
- return {
417
- // 筛选区展开/收回(收回时仅显示第一行)
418
- filterExpanded: false,
419
- // 筛选表单
420
- searchForm: {
421
- eventTitle: '',
422
- eventContent: '',
423
- assetCategory: [],
424
- eventSentiment: '',
425
- impact: '',
426
- influence: '',
427
- infoPublishTimeRange: [],
428
- explainTimeRange: [],
429
- },
430
- assetCategoryOptions: [
431
- { label: '股票', value: '股票' },
432
- { label: '债券', value: '债券' },
433
- { label: '商品', value: '商品' },
434
- { label: '外汇', value: '外汇' },
435
- { label: '基金', value: '基金' },
436
- ],
437
- eventSentimentOptions: [
438
- { label: '利空', value: '利空' },
439
- { label: '利好', value: '利好' },
440
- { label: '中性', value: '中性' },
441
- ],
442
- impactOptions: [
443
- { label: '不相关', value: '不相关' },
444
- { label: '间接相关', value: '间接相关' },
445
- { label: '直接相关', value: '直接相关' },
446
- ],
447
- influenceOptions: [
448
- { label: '普通', value: '普通' },
449
- { label: '重要', value: '重要' },
450
- ],
451
- // 页面描述
452
- pageSummary: '事件解读数据检索与展示(默认按解读发布时间降序)。',
453
- dailyStatsDate: '2025-12-24',
454
- dailyStatsAddedCount: 789,
455
- dailyStatsUnprocessedCount: 0,
456
- // 原始表格数据
457
- originalTableData: [
458
- {
459
- id: 1,
460
- eventTitle: '事件标题A',
461
- eventContent:
462
- '这是一段很长的事件内容,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。这是一段很长的事件内容,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。这是一段很长的事件内容,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。',
463
- eventSummary:
464
- '这是一段很长的事件摘要,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。这是一段很长的事件内容,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。这是一段很长的事件内容,需要展示在表格中,当内容超过3行时需要显示展开按钮来查看更多内容。',
465
- assetCategory: '股票',
466
- assetName: '资产A',
467
- eventSentiment: '利好',
468
- rEventInterpretation: '完整解读A(示例)',
469
- interpretation: '100字解读A(示例)',
470
- impact: '直接相关',
471
- influence: '重要',
472
- importanceScore: 85,
473
- infoPublishTime: '2024-01-15',
474
- explainTime: '2024-01-20',
475
- disabled: false,
476
- expandEventContent: false,
477
- expandEventSummary: false,
478
- },
479
- {
480
- id: 2,
481
- eventTitle: '事件标题B',
482
- eventContent: '事件内容B',
483
- eventSummary: '事件摘要B',
484
- assetCategory: '债券',
485
- assetName: '资产B',
486
- eventSentiment: '中性',
487
- rEventInterpretation: '完整解读B(示例)',
488
- interpretation: '100字解读B(示例)',
489
- impact: '间接相关',
490
- influence: '普通',
491
- importanceScore: 60,
492
- infoPublishTime: '2024-01-16',
493
- explainTime: '2024-01-21',
494
- disabled: false,
495
- expandEventContent: false,
496
- expandEventSummary: false,
497
- },
498
- ],
499
- // 排序配置
500
- sortConfig: {
501
- prop: 'explainTime',
502
- order: 'descending',
503
- },
504
- // 统计弹窗显示状态
505
- statisticsDialogVisible: false,
506
- totalTableData: [
507
- {
508
- assetCategory: '股票',
509
- assetName: '资产A',
510
- eventNums: 120,
511
- eventCountRate: '30%',
512
- auditRate: '80%',
513
- auditApprovedRate: '75%',
514
- },
515
- {
516
- assetCategory: '债券',
517
- assetName: '资产B',
518
- eventNums: 80,
519
- eventCountRate: '20%',
520
- auditRate: '70%',
521
- auditApprovedRate: '68%',
522
- },
523
- ],
524
- // 查看详情弹窗
525
- detailDialogVisible: false,
526
- detailForm: null,
527
- detailMode: 'view', // view | create | edit
528
- editingRowId: null,
529
- assetConfigVisible: false,
530
- assetClassData: [
531
- { assetName: '股票', assetType: '沪深300', assetStatus: 0, sortOrder: 1 },
532
- { assetName: '股票', assetType: '中证500', assetStatus: 0, sortOrder: 2 },
533
- { assetName: '股票', assetType: '上证50', assetStatus: 0, sortOrder: 3 },
534
- { assetName: '股票', assetType: '创业板', assetStatus: 0, sortOrder: 4 },
535
- { assetName: '股票', assetType: '科创50', assetStatus: 0, sortOrder: 5 },
536
- { assetName: '股票', assetType: '恒生指数', assetStatus: 0, sortOrder: 6 },
537
- { assetName: '股票', assetType: '纳斯达克', assetStatus: 0, sortOrder: 7 },
538
- { assetName: '股票', assetType: '标普500', assetStatus: 0, sortOrder: 8 },
539
- { assetName: '债券', assetType: '利率债', assetStatus: 0, sortOrder: 9 },
540
- { assetName: '债券', assetType: '信用债', assetStatus: 0, sortOrder: 10 },
541
- { assetName: '商品', assetType: '黄金', assetStatus: 0, sortOrder: 11 },
542
- { assetName: '商品', assetType: '原油', assetStatus: 0, sortOrder: 12 },
543
- ],
544
- tableData: [],
545
- pagination: {
546
- currentPage: 1,
547
- pageSize: 10,
548
- total: 0,
549
- },
550
- }
551
- },
552
- computed: {
553
- detailReadOnly() {
554
- return this.detailMode === 'view'
555
- },
556
- detailDialogTitle() {
557
- if (this.detailMode === 'create') return '新增'
558
- if (this.detailMode === 'edit') return '编辑'
559
- return '查看详情'
560
- },
561
- },
562
- mounted() {
563
- // 初始化原始数据
564
- this.originalTableData = JSON.parse(JSON.stringify(this.originalTableData))
565
- this.fetchTableData()
566
- },
567
- methods: {
568
- openAssetConfigDialog() {
569
- this.assetConfigVisible = true
570
- },
571
- handleAssetConfigConfirm(newData) {
572
- this.assetClassData = newData
573
- // Extract unique asset names for category options
574
- const uniqueCategories = [...new Set(newData.map(item => item.assetName))]
575
- this.assetCategoryOptions = uniqueCategories.map(name => ({
576
- label: name,
577
- value: name,
578
- }))
579
- this.$message.success('资产类别配置已保存')
580
- },
581
- toggleFilterExpanded() {
582
- this.filterExpanded = !this.filterExpanded
583
- },
584
- // 查询
585
- handleSearch() {
586
- console.log('查询条件:', this.searchForm)
587
- this.pagination.currentPage = 1
588
- this.fetchTableData()
589
- },
590
- // 重置
591
- handleReset() {
592
- this.searchForm = {
593
- eventTitle: '',
594
- eventContent: '',
595
- assetCategory: [],
596
- eventSentiment: '',
597
- impact: '',
598
- influence: '',
599
- infoPublishTimeRange: [],
600
- explainTimeRange: [],
601
- }
602
- this.pagination.currentPage = 1
603
- this.fetchTableData()
604
- },
605
- // 表格排序
606
- handleSortChange({ prop, order }) {
607
- if (!prop || !order) return
608
- if (prop === 'infoPublishTime' || prop === 'explainTime') {
609
- this.sortConfig = { prop, order }
610
- console.log('排序:', { prop, order })
611
- this.pagination.currentPage = 1
612
- this.fetchTableData()
613
- }
614
- },
615
- // // 基金简称筛选
616
- // handleFundAbbrFilter() {
617
- // // 通过 computed 属性自动过滤
618
- // },
619
- // 判断是否需要显示展开按钮(超过3行)
620
- shouldShowExpand(content) {
621
- if (!content) return false
622
- // 简单的判断:如果内容长度超过某个阈值,认为超过3行
623
- // 实际可以使用更精确的方法,比如计算实际行数
624
- return content.length > 100
625
- },
626
- // 切换展开/收起
627
- toggleExpand(row, field) {
628
- const expandField = `expand${field.charAt(0).toUpperCase() + field.slice(1)}`
629
- this.$set(row, expandField, !row[expandField])
630
- },
631
- // 打开统计弹窗
632
- openStatisticsDialog() {
633
- // TODO: 根据当前表格数据查询统计数据
634
- this.statisticsDialogVisible = true
635
- },
636
- handleFilterToday() {
637
- const d = this.dailyStatsDate
638
- this.searchForm.infoPublishTimeRange = [d, d]
639
- this.searchForm.explainTimeRange = [d, d]
640
- this.$message.success(`已筛选至${this.formatDateCn(d)}当天`)
641
- },
642
- formatDateCn(dateStr) {
643
- const [y, m, d] = (dateStr || '').split('-')
644
- if (!y || !m || !d) return dateStr
645
- return `${y}年${m}月${d}号`
646
- },
647
- buildEmptyDetailForm() {
648
- return {
649
- id: null,
650
- eventTitle: '',
651
- eventContent: '',
652
- eventSummary: '',
653
- assetCategory: '',
654
- assetName: '',
655
- eventSentiment: '',
656
- rEventInterpretation: '',
657
- interpretation: '',
658
- impact: '',
659
- influence: '',
660
- importanceScore: '',
661
- infoPublishTime: '',
662
- explainTime: '',
663
- disabled: false,
664
- expandEventContent: false,
665
- expandEventSummary: false,
666
- }
667
- },
668
- openViewDialog(row) {
669
- this.detailMode = 'view'
670
- this.editingRowId = row.id
671
- this.detailForm = JSON.parse(JSON.stringify(row))
672
- this.detailDialogVisible = true
673
- },
674
- openEditDialog(row) {
675
- this.detailMode = 'edit'
676
- this.editingRowId = row.id
677
- this.detailForm = JSON.parse(JSON.stringify(row))
678
- this.detailDialogVisible = true
679
- },
680
- openCreateDialog() {
681
- this.detailMode = 'create'
682
- this.editingRowId = null
683
- this.detailForm = this.buildEmptyDetailForm()
684
- this.detailDialogVisible = true
685
- },
686
- handleDetailSave() {
687
- if (!this.detailForm) return
688
-
689
- if (this.detailMode === 'create') {
690
- const maxId = this.originalTableData.reduce((m, it) => Math.max(m, Number(it.id) || 0), 0)
691
- const newRow = {
692
- ...this.buildEmptyDetailForm(),
693
- ...JSON.parse(JSON.stringify(this.detailForm)),
694
- id: maxId + 1,
695
- }
696
- this.originalTableData.unshift(newRow)
697
- this.detailDialogVisible = false
698
- this.$message.success('新增成功')
699
- this.fetchTableData()
700
- return
701
- }
702
-
703
- if (this.detailMode === 'edit') {
704
- const idx = this.originalTableData.findIndex(it => it.id === this.editingRowId)
705
- if (idx === -1) {
706
- this.$message.error('未找到要编辑的数据')
707
- return
708
- }
709
- const keep = this.originalTableData[idx]
710
- this.$set(this.originalTableData, idx, {
711
- ...keep,
712
- ...JSON.parse(JSON.stringify(this.detailForm)),
713
- })
714
- this.detailDialogVisible = false
715
- this.$message.success('保存成功')
716
- this.fetchTableData()
717
- }
718
- },
719
- // 停用
720
- handleDisable(row) {
721
- if (row.disabled) return
722
- this.$confirm('确认停用该条数据?', '提示', { type: 'warning' })
723
- .then(() => {
724
- this.$set(row, 'disabled', true)
725
- this.$message.success('已停用')
726
- })
727
- .catch(() => {})
728
- },
729
- // 数据导出
730
- handleExport() {
731
- // TODO: 实现数据导出逻辑
732
- this.$message.success('导出功能开发中...')
733
- },
734
- handlePageSizeChange(val) {
735
- this.pagination.pageSize = val
736
- this.pagination.currentPage = 1
737
- this.fetchTableData()
738
- },
739
- handlePageChange(val) {
740
- this.pagination.currentPage = val
741
- this.fetchTableData()
742
- },
743
- fetchTableData() {
744
- let data = [...this.originalTableData]
745
- if (this.searchForm.eventTitle) {
746
- data = data.filter(
747
- item => item.eventTitle && item.eventTitle.includes(this.searchForm.eventTitle),
748
- )
749
- }
750
- if (this.searchForm.eventContent) {
751
- data = data.filter(
752
- item => item.eventContent && item.eventContent.includes(this.searchForm.eventContent),
753
- )
754
- }
755
- if (this.searchForm.assetCategory && this.searchForm.assetCategory.length > 0) {
756
- data = data.filter(item => this.searchForm.assetCategory.includes(item.assetCategory))
757
- }
758
- if (this.searchForm.eventSentiment) {
759
- data = data.filter(item => item.eventSentiment === this.searchForm.eventSentiment)
760
- }
761
- if (this.searchForm.impact) {
762
- data = data.filter(item => item.impact === this.searchForm.impact)
763
- }
764
- if (this.searchForm.influence) {
765
- data = data.filter(item => item.influence === this.searchForm.influence)
766
- }
767
- if (
768
- this.searchForm.infoPublishTimeRange &&
769
- this.searchForm.infoPublishTimeRange.length === 2
770
- ) {
771
- const [startDate, endDate] = this.searchForm.infoPublishTimeRange
772
- data = data.filter(
773
- item => item.infoPublishTime >= startDate && item.infoPublishTime <= endDate,
774
- )
775
- }
776
- if (this.searchForm.explainTimeRange && this.searchForm.explainTimeRange.length === 2) {
777
- const [startDate, endDate] = this.searchForm.explainTimeRange
778
- data = data.filter(item => item.explainTime >= startDate && item.explainTime <= endDate)
779
- }
780
- if (this.sortConfig.prop) {
781
- data.sort((a, b) => {
782
- const aVal = a[this.sortConfig.prop]
783
- const bVal = b[this.sortConfig.prop]
784
- if (this.sortConfig.order === 'ascending') {
785
- return aVal > bVal ? 1 : aVal < bVal ? -1 : 0
786
- } else {
787
- return aVal < bVal ? 1 : aVal > bVal ? -1 : 0
788
- }
789
- })
790
- }
791
- this.pagination.total = data.length
792
- const start = (this.pagination.currentPage - 1) * this.pagination.pageSize
793
- const end = start + this.pagination.pageSize
794
- this.tableData = data.slice(start, end)
795
- },
796
- },
797
- }
798
- </script>
799
-
800
- <style scoped lang="scss">
801
- .event-interpretation {
802
- padding: 20px;
803
- background-color: #f5f7fa;
804
- min-height: calc(100vh - 40px);
805
-
806
- .filter-card {
807
- margin-bottom: 20px;
808
- background-color: #fff;
809
-
810
- .search-form {
811
- padding: 10px 0;
812
- }
813
- }
814
-
815
- .display-card {
816
- background-color: #fff;
817
-
818
- .description-section {
819
- display: flex;
820
- justify-content: space-between;
821
- align-items: center;
822
- padding: 15px 0;
823
- border-bottom: 1px solid #ebeef5;
824
- margin-bottom: 15px;
825
-
826
- .description-left {
827
- flex: 1;
828
-
829
- .fund-summary {
830
- font-size: 14px;
831
- color: #606266;
832
- }
833
- }
834
-
835
- .description-right {
836
- display: flex;
837
- align-items: center;
838
- gap: 10px;
839
-
840
- .text {
841
- font-size: 14px;
842
- color: #606266;
843
- }
844
- }
845
- }
846
-
847
- .result-table {
848
- .expandable-content {
849
- width: 100%;
850
-
851
- /* 折叠状态样式(明确类名) */
852
- .content-collapse {
853
- display: -webkit-box;
854
- -webkit-line-clamp: 3;
855
- line-clamp: 3;
856
- -webkit-box-orient: vertical;
857
- overflow: hidden;
858
- text-overflow: ellipsis;
859
- white-space: normal;
860
- word-wrap: break-word;
861
- }
862
-
863
- /* 展开状态样式 */
864
- .content-expanded {
865
- white-space: normal;
866
- word-wrap: break-word;
867
- overflow: visible;
868
- /* 确保展开后内容完全显示 */
869
- }
870
-
871
- /* 按钮样式优化 */
872
- .el-button {
873
- margin-top: 5px;
874
- color: #409eff;
875
- }
876
- }
877
-
878
- // .expandable-content {
879
- // .content-expanded {
880
- // white-space: normal;
881
- // word-wrap: break-word;
882
- // }
883
-
884
- // div:not(.content-expanded) {
885
- // display: -webkit-box;
886
- // -webkit-line-clamp: 3;
887
- // line-clamp: 3;
888
- // -webkit-box-orient: vertical;
889
- // overflow: hidden;
890
- // text-overflow: ellipsis;
891
- // white-space: normal;
892
- // word-wrap: break-word;
893
- // }
894
- // }
895
- }
896
- .table-pagination {
897
- margin-top: 12px;
898
- display: flex;
899
- justify-content: flex-end;
900
- }
901
- }
902
-
903
- // 统计弹窗样式
904
- .statistics-top {
905
- margin-bottom: 30px;
906
-
907
- .statistics-row {
908
- display: flex;
909
- justify-content: space-between;
910
- align-items: center;
911
- margin-bottom: 20px;
912
-
913
- &.statistics-three-columns {
914
- display: flex;
915
- gap: 20px;
916
- margin-top: 20px;
917
-
918
- .statistics-column {
919
- flex: 1;
920
- padding: 15px;
921
- background-color: #f5f7fa;
922
- border-radius: 4px;
923
- text-align: center;
924
-
925
- .column-label {
926
- font-size: 14px;
927
- color: #606266;
928
- margin-bottom: 10px;
929
- }
930
-
931
- .column-value {
932
- font-size: 24px;
933
- font-weight: bold;
934
- color: #409eff;
935
- }
936
- }
937
- }
938
-
939
- .statistics-item-left,
940
- .statistics-item-right {
941
- display: flex;
942
- align-items: center;
943
-
944
- .label {
945
- font-size: 14px;
946
- color: #606266;
947
- margin-right: 5px;
948
- }
949
-
950
- .value {
951
- font-size: 14px;
952
- color: #303133;
953
- font-weight: 500;
954
- }
955
- }
956
- }
957
- }
958
-
959
- .statistics-bottom {
960
- .section-title {
961
- font-size: 16px;
962
- font-weight: bold;
963
- color: #303133;
964
- margin-bottom: 15px;
965
- }
966
-
967
- .distribution-table {
968
- .expand-icon {
969
- cursor: pointer;
970
- display: inline-block;
971
- width: 20px;
972
- text-align: center;
973
- color: #409eff;
974
- margin-right: 5px;
975
- user-select: none;
976
- }
977
-
978
- .index-text {
979
- cursor: pointer;
980
- user-select: none;
981
- color: #409eff;
982
-
983
- &:hover {
984
- text-decoration: underline;
985
- }
986
- }
987
- }
988
- }
989
-
990
- /* 电脑端表单样式 */
991
- .search-form {
992
- display: grid;
993
- grid-template-columns: repeat(3, minmax(0, 1fr));
994
- column-gap: 16px;
995
- row-gap: 10px;
996
- align-items: start;
997
- }
998
-
999
- /* 表单项:统一高度/宽度与对齐,让每个子项在三列里宽度一致 */
1000
- .search-form :deep(.el-form-item) {
1001
- margin: 0;
1002
- width: 100%;
1003
- display: flex;
1004
- }
1005
-
1006
- .search-form :deep(.el-form-item__content) {
1007
- flex: 1;
1008
- min-width: 0;
1009
- display: flex;
1010
- }
1011
-
1012
- /* 控件统一撑满 */
1013
- .search-form :deep(.el-input),
1014
- .search-form :deep(.el-select),
1015
- .search-form :deep(.el-date-editor) {
1016
- width: 100%;
1017
- }
1018
-
1019
- /* 操作区:跨三列并右对齐 */
1020
- .search-form :deep(.form-actions) {
1021
- grid-column: 1 / -1;
1022
- }
1023
-
1024
- .search-form :deep(.form-actions .el-form-item__content) {
1025
- justify-content: flex-end;
1026
- gap: 10px;
1027
- }
1028
-
1029
- /* 操作列文字按钮颜色(停用) */
1030
- .danger-text-btn {
1031
- color: #f56c6c;
1032
- }
1033
-
1034
- .danger-text-btn.is-disabled,
1035
- .danger-text-btn[disabled] {
1036
- color: #fbc4c4;
1037
- }
1038
-
1039
- /* 查看详情弹窗:更规整的宽度与对齐 */
1040
- .detail-form {
1041
- max-width: 840px;
1042
- margin: 0 auto;
1043
- display: grid;
1044
- grid-template-columns: repeat(2, minmax(0, 1fr));
1045
- column-gap: 18px;
1046
- row-gap: 4px;
1047
- }
1048
-
1049
- .detail-form :deep(.el-form-item) {
1050
- margin-bottom: 12px;
1051
- }
1052
-
1053
- .detail-form :deep(.el-form-item__content) {
1054
- min-width: 0;
1055
- }
1056
-
1057
- .detail-form :deep(.el-input),
1058
- .detail-form :deep(.el-select),
1059
- .detail-form :deep(.el-date-editor) {
1060
- width: 100%;
1061
- }
1062
-
1063
- .detail-form :deep(.full-row) {
1064
- grid-column: 1 / -1;
1065
- }
1066
- }
1067
- </style>