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,667 @@
1
+ <template>
2
+ <section class="template-editor-form">
3
+ <div class="template-editor-form__row">
4
+ <label class="template-editor-field template-editor-field--row">
5
+ <span class="template-editor-label"
6
+ >主要語言<span class="template-editor-label__required">*</span></span
7
+ >
8
+ <div class="template-editor-field__control template-editor-field__control--lang">
9
+ <el-select v-model="form.language" class="template-editor-field__lang">
10
+ <el-option
11
+ v-for="item in languageOptions"
12
+ :key="item.value"
13
+ :label="item.label"
14
+ :value="item.value"
15
+ />
16
+ </el-select>
17
+ </div>
18
+ </label>
19
+ </div>
20
+
21
+ <div class="template-editor-form__row">
22
+ <label class="template-editor-field template-editor-field--row">
23
+ <span class="template-editor-label"
24
+ >模板標題<span class="template-editor-label__required">*</span></span
25
+ >
26
+ <div class="template-editor-field__control">
27
+ <el-input
28
+ v-model="form.title"
29
+ :maxlength="TEMPLATE_TITLE_MAX"
30
+ show-word-limit
31
+ class="template-editor-field__input"
32
+ />
33
+ </div>
34
+ </label>
35
+ </div>
36
+
37
+ <div class="template-editor-form__row">
38
+ <label
39
+ class="template-editor-field template-editor-field--row template-editor-field--textarea-row"
40
+ >
41
+ <span class="template-editor-label"
42
+ >模板描述<span class="template-editor-label__required">*</span></span
43
+ >
44
+ <div class="template-editor-field__control">
45
+ <el-input
46
+ v-model="form.description"
47
+ type="textarea"
48
+ :rows="4"
49
+ :maxlength="TEMPLATE_DESC_MAX"
50
+ show-word-limit
51
+ resize="none"
52
+ class="template-editor-field__textarea"
53
+ />
54
+ </div>
55
+ </label>
56
+ </div>
57
+
58
+ <div class="template-editor-chapters">
59
+ <div v-for="chapter in form.chapters" :key="chapter.id" class="template-editor-chapter">
60
+ <button
61
+ type="button"
62
+ class="template-editor-chapter__header"
63
+ @click="toggleChapter(chapter.id)"
64
+ >
65
+ <span class="template-editor-chapter__drag" aria-hidden="true"> <i /><i /><i /> </span>
66
+ <span class="template-editor-chapter__header-title-wrap">
67
+ <span class="template-editor-chapter__header-title">
68
+ {{ getChapterDisplayTitle(chapter) }}
69
+ </span>
70
+ <el-icon
71
+ v-if="isChapterTitleEdited(chapter)"
72
+ class="template-editor-chapter__title-edited"
73
+ aria-label="章節標題已修改"
74
+ >
75
+ <Edit />
76
+ </el-icon>
77
+ </span>
78
+ <el-icon
79
+ class="template-editor-chapter__chevron"
80
+ :class="{ 'template-editor-chapter__chevron--expanded': chapter.expanded }"
81
+ >
82
+ <ArrowRight />
83
+ </el-icon>
84
+ </button>
85
+
86
+ <div v-if="chapter.expanded" class="template-editor-chapter__body">
87
+ <div class="template-editor-chapter__toolbar">
88
+ <button
89
+ v-if="isEditMode"
90
+ type="button"
91
+ class="template-center-toolbar-btn gen-ai-action-btn template-editor-chapter__action-btn"
92
+ :class="
93
+ isChapterEditing(chapter.id)
94
+ ? 'template-center-toolbar-btn--outline template-center-toolbar-btn--delete'
95
+ : 'template-center-toolbar-btn--ghost'
96
+ "
97
+ :disabled="isChapterEditing(chapter.id) && form.chapters.length <= 1"
98
+ @click.stop="handleChapterToolbarAction(chapter)"
99
+ >
100
+ {{ isChapterEditing(chapter.id) ? '刪除' : '編輯' }}
101
+ </button>
102
+ <button
103
+ v-else
104
+ type="button"
105
+ class="template-center-toolbar-btn gen-ai-action-btn template-center-toolbar-btn--outline template-center-toolbar-btn--delete template-editor-chapter__action-btn"
106
+ :disabled="form.chapters.length <= 1"
107
+ @click.stop="handleDeleteChapter(chapter)"
108
+ >
109
+ 刪除
110
+ </button>
111
+ </div>
112
+
113
+ <template v-if="showChapterFields(chapter.id)">
114
+ <label class="template-editor-field template-editor-field--row">
115
+ <span class="template-editor-label">章節標題</span>
116
+ <div class="template-editor-field__control">
117
+ <el-input
118
+ v-model="chapter.title"
119
+ :maxlength="CHAPTER_TITLE_MAX"
120
+ show-word-limit
121
+ class="template-editor-field__input"
122
+ />
123
+ </div>
124
+ </label>
125
+
126
+ <label
127
+ class="template-editor-field template-editor-field--row template-editor-field--textarea-row"
128
+ >
129
+ <span class="template-editor-label">章節描述</span>
130
+ <div class="template-editor-field__control">
131
+ <el-input
132
+ v-model="chapter.description"
133
+ type="textarea"
134
+ :rows="4"
135
+ :maxlength="CHAPTER_DESC_MAX"
136
+ show-word-limit
137
+ resize="none"
138
+ class="template-editor-field__textarea"
139
+ />
140
+ </div>
141
+ </label>
142
+
143
+ <ReportTemplatePromptField
144
+ v-model="chapter.prompt"
145
+ :maxlength="CHAPTER_PROMPT_MAX"
146
+ :rows="CHAPTER_PROMPT_ROWS"
147
+ :chapter-title="chapter.title"
148
+ :chapter-description="chapter.description"
149
+ v-bind="resolvePromptFieldProps(chapter)"
150
+ />
151
+ </template>
152
+ </div>
153
+ </div>
154
+ </div>
155
+
156
+ <div class="template-editor-form__add">
157
+ <button
158
+ type="button"
159
+ class="template-editor-form__add-btn"
160
+ aria-label="新增章節"
161
+ :disabled="form.chapters.length >= CHAPTER_MAX_COUNT"
162
+ @click="addChapter"
163
+ >
164
+ +
165
+ </button>
166
+ </div>
167
+
168
+ <div v-if="$slots['footer-actions']" class="template-editor-form__footer-actions">
169
+ <slot name="footer-actions" />
170
+ </div>
171
+ </section>
172
+ </template>
173
+
174
+ <script setup lang="ts">
175
+ import { ArrowRight, Edit } from '@element-plus/icons-vue'
176
+ import { ElMessage, ElMessageBox } from 'element-plus'
177
+ import { computed, ref, watch } from 'vue'
178
+ import {
179
+ createEmptyChapter,
180
+ type TemplateChapterForm,
181
+ type TemplateEditorForm,
182
+ type TemplateEditorMode,
183
+ } from '../report-template-data'
184
+ import { PromptField as ReportTemplatePromptField, type PromptFieldLayoutBind } from '../../common'
185
+ const TEMPLATE_TITLE_MAX = 100
186
+ const TEMPLATE_DESC_MAX = 3000
187
+ const CHAPTER_TITLE_MAX = 100
188
+ const CHAPTER_DESC_MAX = 1000
189
+ const CHAPTER_PROMPT_MAX = 8000
190
+ const CHAPTER_PROMPT_ROWS = 8
191
+ const CHAPTER_MAX_COUNT = 100
192
+
193
+ const languageOptions = [
194
+ { label: '中文', value: 'zh' },
195
+ { label: 'English', value: 'en' },
196
+ ]
197
+
198
+ const props = defineProps<{
199
+ modelValue: TemplateEditorForm
200
+ editorMode: TemplateEditorMode
201
+ }>()
202
+
203
+ const emit = defineEmits<{
204
+ 'update:modelValue': [value: TemplateEditorForm]
205
+ }>()
206
+
207
+ const form = computed({
208
+ get: () => props.modelValue,
209
+ set: (value) => emit('update:modelValue', value),
210
+ })
211
+
212
+ const editingChapterId = ref<string | null>(null)
213
+ const chapterOriginalTitles = ref<Record<string, string>>({})
214
+
215
+ const isEditMode = computed(() => props.editorMode === 'edit')
216
+ const isCreateMode = computed(() => props.editorMode === 'create')
217
+
218
+ function syncChapterOriginalTitles() {
219
+ const map: Record<string, string> = {}
220
+ for (const chapter of form.value.chapters) {
221
+ map[chapter.id] = chapter.title
222
+ }
223
+ chapterOriginalTitles.value = map
224
+ }
225
+
226
+ watch(
227
+ () => props.modelValue,
228
+ () => syncChapterOriginalTitles(),
229
+ { deep: true, immediate: true }
230
+ )
231
+
232
+ function isChapterEditing(chapterId: string) {
233
+ return isEditMode.value && editingChapterId.value === chapterId
234
+ }
235
+
236
+ function showChapterFields(chapterId: string) {
237
+ return !isEditMode.value || isChapterEditing(chapterId)
238
+ }
239
+
240
+ function isChapterTitleEdited(chapter: TemplateChapterForm) {
241
+ const original = chapterOriginalTitles.value[chapter.id] ?? ''
242
+ return chapter.title.trim() !== original.trim()
243
+ }
244
+
245
+ function expandChapter(id: string) {
246
+ form.value = {
247
+ ...form.value,
248
+ chapters: form.value.chapters.map((chapter) => ({
249
+ ...chapter,
250
+ expanded: chapter.id === id,
251
+ })),
252
+ }
253
+ }
254
+
255
+ function toggleChapter(id: string) {
256
+ const target = form.value.chapters.find((chapter) => chapter.id === id)
257
+ if (!target) return
258
+
259
+ if (target.expanded) {
260
+ if (editingChapterId.value === id) {
261
+ editingChapterId.value = null
262
+ }
263
+ form.value = {
264
+ ...form.value,
265
+ chapters: form.value.chapters.map((chapter) =>
266
+ chapter.id === id ? { ...chapter, expanded: false } : chapter
267
+ ),
268
+ }
269
+ return
270
+ }
271
+
272
+ expandChapter(id)
273
+ }
274
+
275
+ function handleStartEditChapter(chapter: TemplateChapterForm) {
276
+ if (editingChapterId.value && editingChapterId.value !== chapter.id) {
277
+ ElMessage.warning('請先保存當前章節,再編輯其他章節')
278
+ return
279
+ }
280
+
281
+ editingChapterId.value = chapter.id
282
+ expandChapter(chapter.id)
283
+ }
284
+
285
+ function handleChapterToolbarAction(chapter: TemplateChapterForm) {
286
+ if (isChapterEditing(chapter.id)) {
287
+ void handleDeleteChapter(chapter)
288
+ return
289
+ }
290
+ handleStartEditChapter(chapter)
291
+ }
292
+
293
+ function addChapter() {
294
+ if (form.value.chapters.length >= CHAPTER_MAX_COUNT) {
295
+ ElMessage.warning(`章節數量已達上限 ${CHAPTER_MAX_COUNT} 個`)
296
+ return
297
+ }
298
+
299
+ const collapsed = form.value.chapters.map((chapter) => ({ ...chapter, expanded: false }))
300
+ const newChapter = createEmptyChapter(true)
301
+ form.value = {
302
+ ...form.value,
303
+ chapters: [...collapsed, newChapter],
304
+ }
305
+ chapterOriginalTitles.value = {
306
+ ...chapterOriginalTitles.value,
307
+ [newChapter.id]: '',
308
+ }
309
+ }
310
+
311
+ function removeChapter(id: string) {
312
+ if (form.value.chapters.length <= 1) return
313
+ if (editingChapterId.value === id) {
314
+ editingChapterId.value = null
315
+ }
316
+ const next = form.value.chapters.filter((chapter) => chapter.id !== id)
317
+ if (!next.some((chapter) => chapter.expanded) && next[0]) {
318
+ next[0] = { ...next[0], expanded: true }
319
+ }
320
+ form.value = { ...form.value, chapters: next }
321
+ const { [id]: _removed, ...rest } = chapterOriginalTitles.value
322
+ chapterOriginalTitles.value = rest
323
+ }
324
+
325
+ async function handleDeleteChapter(chapter: TemplateChapterForm) {
326
+ if (form.value.chapters.length <= 1) return
327
+
328
+ const chapterName = getChapterDisplayTitle(chapter)
329
+ try {
330
+ await ElMessageBox.confirm(`確定刪除章節「${chapterName}」嗎?`, '刪除', {
331
+ confirmButtonText: '確定',
332
+ cancelButtonText: '取消',
333
+ type: 'warning',
334
+ })
335
+ removeChapter(chapter.id)
336
+ ElMessage.success(`已刪除:${chapterName}`)
337
+ } catch {
338
+ // 用戶取消
339
+ }
340
+ }
341
+
342
+ function getChapterDisplayTitle(chapter: TemplateChapterForm) {
343
+ return chapter.title.trim() || '章節標題'
344
+ }
345
+
346
+ function resolvePromptFieldProps(_chapter: TemplateChapterForm): PromptFieldLayoutBind {
347
+ return {
348
+ labelWidth: '100px',
349
+ fieldGap: '16px',
350
+ width: '100%',
351
+ }
352
+ }
353
+
354
+ function resetEditingState() {
355
+ editingChapterId.value = null
356
+ }
357
+
358
+ defineExpose({
359
+ resetEditingState,
360
+ isCreateMode,
361
+ })
362
+ </script>
363
+
364
+ <style scoped>
365
+ .template-editor-form {
366
+ --gen-ai-fs-base: clamp(13px, calc(14 * 100vw / 1920), 14px);
367
+ --template-editor-label-w: 100px;
368
+ --template-editor-field-gap: 16px;
369
+ --report-accent: #c53355;
370
+ --report-accent-soft: #fdf0f2;
371
+ display: flex;
372
+ flex-direction: column;
373
+ gap: 20px;
374
+ font-size: var(--gen-ai-fs-base);
375
+ }
376
+
377
+ .template-editor-form__row {
378
+ width: 100%;
379
+ }
380
+
381
+ .template-editor-field {
382
+ margin: 0;
383
+ }
384
+
385
+ .template-editor-field--row {
386
+ display: grid;
387
+ grid-template-columns: var(--template-editor-label-w) minmax(0, 1fr);
388
+ column-gap: var(--template-editor-field-gap);
389
+ align-items: center;
390
+ width: 100%;
391
+ }
392
+
393
+ .template-editor-field--textarea-row {
394
+ align-items: start;
395
+ }
396
+
397
+ .template-editor-field--textarea-row .template-editor-label {
398
+ padding-top: 8px;
399
+ }
400
+
401
+ .template-editor-label {
402
+ flex-shrink: 0;
403
+ font-size: 14px;
404
+ font-weight: 500;
405
+ font-family: var(--gen-ai-font-family, 'Noto Sans', 'Noto Sans TC', sans-serif);
406
+ color: #303133;
407
+ white-space: nowrap;
408
+ }
409
+
410
+ .template-editor-label__required {
411
+ margin-left: 2px;
412
+ color: #f56c6c;
413
+ }
414
+
415
+ .template-editor-field__control {
416
+ min-width: 0;
417
+ width: 100%;
418
+ }
419
+
420
+ .template-editor-field__control--lang {
421
+ width: auto;
422
+ max-width: 270px;
423
+ }
424
+
425
+ .template-editor-field__lang {
426
+ width: 270px;
427
+ }
428
+
429
+ .template-editor-field__input,
430
+ .template-editor-field__textarea {
431
+ width: 100%;
432
+ }
433
+
434
+ .template-editor-field__input :deep(.el-input__wrapper),
435
+ .template-editor-field__textarea :deep(.el-textarea__inner) {
436
+ font-size: var(--gen-ai-fs-base);
437
+ }
438
+
439
+ .template-editor-field__lang :deep(.el-select__wrapper) {
440
+ min-height: 32px;
441
+ }
442
+
443
+ .template-editor-field__input :deep(.el-input__count),
444
+ .template-editor-field__textarea :deep(.el-input__count) {
445
+ right: 0;
446
+ bottom: -18px;
447
+ background: transparent;
448
+ font-size: 12px;
449
+ color: #909399;
450
+ }
451
+
452
+ .template-editor-chapters {
453
+ display: flex;
454
+ flex-direction: column;
455
+ gap: 0;
456
+ margin-top: 15px;
457
+ padding-top: 15px;
458
+ border-top: 1px solid #ebeef5;
459
+ }
460
+
461
+ .template-editor-chapter {
462
+ border-bottom: 1px solid #ebeef5;
463
+ }
464
+
465
+ .template-editor-chapter:first-child {
466
+ margin-top: 16px;
467
+ }
468
+
469
+ .template-editor-chapter__header {
470
+ display: grid;
471
+ grid-template-columns: 20px var(--template-editor-label-w) minmax(0, 1fr) 20px;
472
+ column-gap: var(--template-editor-field-gap);
473
+ align-items: center;
474
+ width: 100%;
475
+ min-height: 48px;
476
+ padding: 0 4px;
477
+ border: none;
478
+ background: #fff;
479
+ text-align: left;
480
+ cursor: pointer;
481
+ transition: background-color 0.2s ease;
482
+ }
483
+
484
+ .template-editor-chapter__header:hover {
485
+ background: #f5f7fa;
486
+ }
487
+
488
+ .template-editor-chapter__body {
489
+ display: flex;
490
+ flex-direction: column;
491
+ gap: 20px;
492
+ padding: 0 4px 16px;
493
+ }
494
+
495
+ .template-editor-chapter__toolbar {
496
+ display: grid;
497
+ grid-template-columns: var(--template-editor-label-w) minmax(0, 1fr);
498
+ column-gap: var(--template-editor-field-gap);
499
+ margin-top: 20px;
500
+ }
501
+
502
+ .template-editor-chapter__action-btn {
503
+ grid-column: 2;
504
+ justify-self: end;
505
+ width: 83px;
506
+ min-width: 83px;
507
+ height: 32px;
508
+ padding: 0;
509
+ }
510
+
511
+ .template-center-toolbar-btn {
512
+ display: inline-flex;
513
+ align-items: center;
514
+ justify-content: center;
515
+ gap: 6px;
516
+ box-sizing: border-box;
517
+ height: 32px;
518
+ min-width: 83px;
519
+ padding: 0 14px;
520
+ border-radius: 4px;
521
+ border: 1px solid #dcdfe6;
522
+ background: #fff;
523
+ color: #606266;
524
+ font-size: 15px;
525
+ font-family: var(--gen-ai-font-family, 'Noto Sans', 'Noto Sans TC', sans-serif);
526
+ font-weight: 400;
527
+ line-height: 1;
528
+ white-space: nowrap;
529
+ cursor: pointer;
530
+ transition: all 0.2s ease;
531
+ }
532
+
533
+ .template-center-toolbar-btn--outline {
534
+ border-color: var(--report-accent);
535
+ color: var(--report-accent);
536
+ background: #fff;
537
+ }
538
+
539
+ .template-center-toolbar-btn--outline:hover:not(:disabled) {
540
+ border-color: var(--report-accent);
541
+ color: var(--report-accent);
542
+ background: var(--report-accent-soft);
543
+ }
544
+
545
+ .template-center-toolbar-btn--delete {
546
+ border-color: var(--report-accent);
547
+ color: var(--report-accent);
548
+ background: #fff;
549
+ }
550
+
551
+ .template-center-toolbar-btn--delete:hover:not(:disabled) {
552
+ border-color: var(--report-accent);
553
+ color: var(--report-accent);
554
+ background: var(--report-accent-soft);
555
+ }
556
+
557
+ .template-center-toolbar-btn--ghost {
558
+ border: 1px solid #dcdfe6;
559
+ background: #fff;
560
+ color: #606266;
561
+ }
562
+
563
+ .template-center-toolbar-btn--ghost:hover:not(:disabled) {
564
+ border-color: var(--report-accent);
565
+ color: var(--report-accent);
566
+ background: var(--report-accent-soft);
567
+ }
568
+
569
+ .template-editor-chapter__drag {
570
+ grid-column: 1;
571
+ display: inline-flex;
572
+ flex-direction: column;
573
+ justify-content: center;
574
+ gap: 3px;
575
+ width: 12px;
576
+ flex-shrink: 0;
577
+ }
578
+
579
+ .template-editor-chapter__drag i {
580
+ display: block;
581
+ width: 4px;
582
+ height: 4px;
583
+ border-radius: 50%;
584
+ background: #909399;
585
+ }
586
+
587
+ .template-editor-chapter__header-title-wrap {
588
+ grid-column: 2 / 4;
589
+ display: inline-flex;
590
+ align-items: center;
591
+ gap: 4px;
592
+ min-width: 0;
593
+ }
594
+
595
+ .template-editor-chapter__header-title {
596
+ min-width: 0;
597
+ font-size: 14px;
598
+ font-weight: 500;
599
+ font-family: var(--gen-ai-font-family, 'Noto Sans', 'Noto Sans TC', sans-serif);
600
+ color: #303133;
601
+ overflow: hidden;
602
+ text-overflow: ellipsis;
603
+ white-space: nowrap;
604
+ }
605
+
606
+ .template-editor-chapter__title-edited {
607
+ flex-shrink: 0;
608
+ font-size: 14px;
609
+ color: #c53355;
610
+ }
611
+
612
+ .template-editor-chapter__chevron {
613
+ grid-column: 4;
614
+ justify-self: end;
615
+ flex-shrink: 0;
616
+ font-size: 16px;
617
+ color: #dcdfe6;
618
+ transition: transform 0.2s ease;
619
+ }
620
+
621
+ .template-editor-chapter__chevron--expanded {
622
+ transform: rotate(90deg);
623
+ }
624
+
625
+ .template-editor-field--textarea-row .template-editor-field__control {
626
+ position: relative;
627
+ padding-bottom: 18px;
628
+ }
629
+
630
+ .template-editor-form__add {
631
+ display: flex;
632
+ justify-content: center;
633
+ padding: 8px 0 0;
634
+ }
635
+
636
+ .template-editor-form__footer-actions {
637
+ display: flex;
638
+ justify-content: center;
639
+ }
640
+
641
+ .template-editor-form__add-btn {
642
+ display: inline-flex;
643
+ align-items: center;
644
+ justify-content: center;
645
+ box-sizing: border-box;
646
+ width: 160px;
647
+ height: 39px;
648
+ border: 1px solid #dcdfe6;
649
+ border-radius: 4px;
650
+ background: #fff;
651
+ color: #606266;
652
+ font-size: 24px;
653
+ line-height: 1;
654
+ cursor: pointer;
655
+ transition: all 0.2s ease;
656
+ }
657
+
658
+ .template-editor-form__add-btn:hover:not(:disabled) {
659
+ border-color: #c53355;
660
+ color: #c53355;
661
+ }
662
+
663
+ .template-editor-form__add-btn:disabled {
664
+ opacity: 0.45;
665
+ cursor: not-allowed;
666
+ }
667
+ </style>