npmapps 1.0.21 → 1.0.23

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 (105) hide show
  1. package/app/Wscats.vue-1.0.26.vsix +0 -0
  2. package/app/febean.vue-format-0.1.8.vsix +0 -0
  3. package/app/wujie-vue3-child/.claude/settings.local.json +8 -0
  4. package/app/wujie-vue3-child/.vscode/extensions.json +3 -0
  5. package/app/wujie-vue3-child/PROJECT_MEMORY.md +427 -0
  6. package/app/wujie-vue3-child/README.md +5 -0
  7. package/app/wujie-vue3-child/index.html +13 -0
  8. package/app/wujie-vue3-child/package-lock.json +5744 -0
  9. package/app/wujie-vue3-child/package.json +28 -0
  10. package/app/wujie-vue3-child/public/vite.svg +1 -0
  11. package/app/wujie-vue3-child/src/App.vue +130 -0
  12. package/app/wujie-vue3-child/src/assets/vue.svg +1 -0
  13. package/app/wujie-vue3-child/src/components/HelloWorld.vue +43 -0
  14. package/app/wujie-vue3-child/src/components/tags-view.vue +193 -0
  15. package/app/wujie-vue3-child/src/components/tags-view1.vue +131 -0
  16. package/app/wujie-vue3-child/src/hooks/useClickOutside.js +11 -0
  17. package/app/wujie-vue3-child/src/hooks/useTableDragSort.js +28 -0
  18. package/app/wujie-vue3-child/src/main.js +15 -0
  19. package/app/wujie-vue3-child/src/router/index.js +104 -0
  20. package/app/wujie-vue3-child/src/store/tagsViewStroe.js +34 -0
  21. package/app/wujie-vue3-child/src/style.css +4 -0
  22. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/README.md +836 -0
  23. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/REFLEX_EXAMPLES.md +728 -0
  24. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.jsx +687 -0
  25. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.module.scss +560 -0
  26. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.jsx +570 -0
  27. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.module.scss +330 -0
  28. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.jsx +378 -0
  29. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.module.scss +228 -0
  30. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.jsx +399 -0
  31. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.module.scss +252 -0
  32. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.jsx +585 -0
  33. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.module.scss +331 -0
  34. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.jsx +392 -0
  35. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.module.scss +39 -0
  36. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/README.md +248 -0
  37. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/SelectorTrigger.jsx +194 -0
  38. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/index.jsx +1459 -0
  39. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/mockData.js +301 -0
  40. package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.jsx +28 -4
  41. package/app/wujie-vue3-child/src/views/aiCoach/index.jsx +32 -0
  42. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.jsx +121 -0
  43. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.module.scss +76 -0
  44. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/DonutChart/index.jsx +104 -0
  45. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.jsx +75 -0
  46. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.module.scss +12 -0
  47. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.jsx +62 -0
  48. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.module.scss +43 -0
  49. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.jsx +29 -0
  50. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.module.scss +5 -0
  51. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.jsx +58 -0
  52. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.module.scss +85 -0
  53. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.jsx +92 -0
  54. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.module.scss +56 -0
  55. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.jsx +40 -0
  56. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.module.scss +53 -0
  57. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsDonut.jsx +106 -0
  58. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsRankBar.jsx +132 -0
  59. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.jsx +176 -0
  60. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.module.scss +96 -0
  61. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.jsx +162 -0
  62. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.module.scss +16 -0
  63. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.jsx +29 -0
  64. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.module.scss +25 -0
  65. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.jsx +106 -0
  66. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.module.scss +164 -0
  67. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.jsx +182 -0
  68. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.module.scss +203 -0
  69. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.jsx +145 -0
  70. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.module.scss +126 -0
  71. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.jsx +67 -0
  72. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.module.scss +105 -0
  73. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.jsx +81 -0
  74. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.module.scss +47 -0
  75. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.jsx +64 -0
  76. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.module.scss +85 -0
  77. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.jsx +39 -0
  78. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.module.scss +44 -0
  79. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.jsx +83 -0
  80. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.module.scss +101 -0
  81. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.jsx +50 -0
  82. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.module.scss +25 -0
  83. package/app/wujie-vue3-child/src/views/child-to-parent.vue +117 -0
  84. package/app/wujie-vue3-child/src/views/home.vue +53 -0
  85. package/app/wujie-vue3-child/src/views/jsx/btnSelect/btnSelect.vue +169 -0
  86. package/app/wujie-vue3-child/src/views/jsx/btnSelect/index.vue +69 -0
  87. package/app/wujie-vue3-child/src/views/jsx/com.vue +44 -0
  88. package/app/wujie-vue3-child/src/views/jsx/dialog.jsx +66 -0
  89. package/app/wujie-vue3-child/src/views/jsx/index.vue +72 -0
  90. package/app/wujie-vue3-child/src/views/jsx/props.vue +33 -0
  91. package/app/wujie-vue3-child/src/views/parent-to-child.vue +225 -0
  92. package/app/wujie-vue3-child/src/views/phone-code.vue +318 -0
  93. package/app/wujie-vue3-child/src/views/router-jump.vue +123 -0
  94. package/app/wujie-vue3-child/src/views/test.vue +192 -0
  95. package/app/wujie-vue3-child/vite.config.js +15 -0
  96. package/package.json +1 -1
  97. package/app/aiCoach/index.jsx +0 -20
  98. package/npmapps-1.0.20.tgz +0 -0
  99. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.jsx +0 -0
  100. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.module.scss +0 -0
  101. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.module.scss +0 -0
  102. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.jsx +0 -0
  103. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.module.scss +0 -0
  104. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.jsx +0 -0
  105. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.module.scss +0 -0
@@ -0,0 +1,182 @@
1
+ import { defineComponent, ref } from 'vue'
2
+ import styles from './index.module.scss'
3
+
4
+ /**
5
+ * 对话记录组件
6
+ * @description 显示陪练过程中的完整对话记录
7
+ */
8
+ export default defineComponent({
9
+ name: 'DialogueRecord',
10
+
11
+ setup() {
12
+ // 对话记录数据
13
+ const dialogues = ref([
14
+ {
15
+ question: '您好,我是XX银行的理财经理小李,请问您现在方便接听电话吗?',
16
+ answer: '方便的,你说吧。',
17
+ score: 85,
18
+ scoreDetails: [
19
+ { name: '关键词', score: 18, total: 20, tags: ['自我介绍'] },
20
+ { name: '语义准确', score: 67, total: 80, tags: [] },
21
+ ],
22
+ suggestion: '开场白较为规范,建议语气可以更加热情一些。',
23
+ },
24
+ {
25
+ question: '好的,王总。我看到您最近在我行有一笔定期存款即将到期,我想向您推荐一款更适合您的理财产品,不知道您是否感兴趣?',
26
+ answer: '什么产品?收益怎么样?',
27
+ score: 78,
28
+ scoreDetails: [
29
+ { name: '关键词', score: 16, total: 20, tags: ['定期存款', '理财产品'] },
30
+ { name: '语义准确', score: 62, total: 80, tags: [] },
31
+ ],
32
+ suggestion: '产品引入比较自然,但可以先了解客户的理财需求再推荐。',
33
+ },
34
+ {
35
+ question: '您好,速汇盈直联后我们内部系统就和你们打通了,安全性有保障吗?',
36
+ answer:
37
+ '王总,系统的安全性能您可以放心,我行会提供多重保障,主要是有三方面向您汇报。首先,第一是在客户端,我们会通过前置机加UK对物理数据进行一个隔离,那就像防火墙一样,保障信息的安全。二呢,是在数据端,系统会自动对企业发出的原始指令进行数据加密和加密,就跟摩斯密码一样,确保外部无法解析,但是在银行端呢,我们采用了国际上最高的安全标准,就像中国电建、上汽集团这样的国央企呢,已经和我们进行了试点。这个模式的安全性在国资委已经获得了普及...',
38
+ score: 98,
39
+ scoreDetails: [
40
+ { name: '关键词', score: 20, total: 20, tags: ['多重保障'] },
41
+ { name: '语义准确', score: 78, total: 80, tags: [] },
42
+ ],
43
+ suggestion: '你在对话中表现的非常好,请继续保持!',
44
+ },
45
+ {
46
+ question: '这个产品的收益率是多少?',
47
+ answer:
48
+ '关于收益率,我们这款产品是浮动收益型的,近一年的年化收益率在4.5%-5.2%之间,相比市场同类产品具有较强的竞争力。而且我们有专业的投资团队进行管理,历史业绩表现稳定。',
49
+ score: 95,
50
+ scoreDetails: [
51
+ { name: '关键词', score: 18, total: 20, tags: ['年化收益率'] },
52
+ { name: '语义准确', score: 77, total: 80, tags: [] },
53
+ ],
54
+ suggestion: '回答准确,继续保持!',
55
+ },
56
+ {
57
+ question: '产品的风险等级是多少?我能承受的风险有限。',
58
+ answer: '这款产品的风险等级是R2级,属于中低风险产品,比较适合稳健型投资者。',
59
+ score: 88,
60
+ scoreDetails: [
61
+ { name: '关键词', score: 18, total: 20, tags: ['风险等级', 'R2'] },
62
+ { name: '语义准确', score: 70, total: 80, tags: [] },
63
+ ],
64
+ suggestion: '风险等级说明清楚,建议可以进一步询问客户的风险承受能力。',
65
+ },
66
+ {
67
+ question: '购买这个产品有什么条件吗?起购金额是多少?',
68
+ answer: '这个产品的起购金额是5万元,没有其他特殊条件,只要您是我行的客户就可以购买。',
69
+ score: 82,
70
+ scoreDetails: [
71
+ { name: '关键词', score: 17, total: 20, tags: ['起购金额', '5万'] },
72
+ { name: '语义准确', score: 65, total: 80, tags: [] },
73
+ ],
74
+ suggestion: '起购金额说明准确,可以补充说明产品的申购渠道。',
75
+ },
76
+ {
77
+ question: '那这个产品什么时候可以赎回?有没有封闭期?',
78
+ answer: '产品有3个月的封闭期,封闭期结束后可以随时赎回,赎回资金T+1到账。',
79
+ score: 90,
80
+ scoreDetails: [
81
+ { name: '关键词', score: 19, total: 20, tags: ['封闭期', '赎回', 'T+1'] },
82
+ { name: '语义准确', score: 71, total: 80, tags: [] },
83
+ ],
84
+ suggestion: '赎回规则说明清晰,表现优秀!',
85
+ },
86
+ {
87
+ question: '好的,我考虑一下,可能明天给你答复。',
88
+ answer: '没问题王总,您可以先考虑一下。如果有任何问题随时可以联系我,我的工号是XX,期待您的回复。',
89
+ score: 92,
90
+ scoreDetails: [
91
+ { name: '关键词', score: 19, total: 20, tags: ['工号'] },
92
+ { name: '语义准确', score: 73, total: 80, tags: [] },
93
+ ],
94
+ suggestion: '收尾专业得体,客户体验良好!',
95
+ },
96
+ ])
97
+
98
+ return () => {
99
+ return (
100
+ <div class={styles.dialogueRecord}>
101
+ <div class={styles.header}>
102
+ <h3 class={styles.title}>完整对话记录</h3>
103
+ <div class={styles.stats}>
104
+ <span class={styles.statItem}>总轮次:{dialogues.value.length}</span>
105
+ <span class={styles.statItem}>
106
+ 平均得分:
107
+ {Math.round(
108
+ dialogues.value.reduce((sum, d) => sum + d.score, 0) /
109
+ dialogues.value.length
110
+ )}
111
+
112
+ </span>
113
+ </div>
114
+ </div>
115
+
116
+ <div class={styles.dialogueContainer}>
117
+ <div class={styles.chatFlow}>
118
+ {dialogues.value.map((dialogue, index) => (
119
+ <>
120
+ {/* AI提问 */}
121
+ <div key={`q-${index}`} class={styles.messageLeft}>
122
+ <div class={styles.messageBubble}>
123
+ <span class={styles.audioIcon}>🔊</span>
124
+ <span>{dialogue.question}</span>
125
+ </div>
126
+ </div>
127
+
128
+ {/* 用户回答 */}
129
+ <div key={`a-${index}`} class={styles.messageRight}>
130
+ <div class={styles.messageBubble}>
131
+ <div class={styles.answerContent}>{dialogue.answer}</div>
132
+ <div class={styles.scoreTag}>
133
+ <span class={styles.scoreValue}>{dialogue.score}分</span>
134
+ </div>
135
+
136
+ {/* 得分明细 */}
137
+ <div class={styles.scoreCard}>
138
+ <div class={styles.scoreDetails}>
139
+ <div class={styles.detailsTitle}>得分明细</div>
140
+ {dialogue.scoreDetails.map((detail, idx) => (
141
+ <div key={idx} class={styles.detailItem}>
142
+ <div class={styles.detailHeader}>
143
+ <span class={styles.detailName}>{detail.name}</span>
144
+ <span class={styles.detailScore}>
145
+ {detail.score}/{detail.total}分
146
+ </span>
147
+ </div>
148
+ {detail.tags && detail.tags.length > 0 && (
149
+ <div class={styles.tags}>
150
+ <span class={styles.tagLabel}>
151
+ 关键词共{detail.tags.length}个,命中{detail.tags.length}个
152
+ </span>
153
+ {detail.tags.map((tag, tagIdx) => (
154
+ <el-tag key={tagIdx} type="success" size="small">
155
+ {tag}
156
+ </el-tag>
157
+ ))}
158
+ </div>
159
+ )}
160
+ </div>
161
+ ))}
162
+ </div>
163
+
164
+ {/* 指导建议 */}
165
+ {dialogue.suggestion && (
166
+ <div class={styles.suggestion}>
167
+ <div class={styles.suggestionTitle}>指导建议</div>
168
+ <div class={styles.suggestionContent}>{dialogue.suggestion}</div>
169
+ </div>
170
+ )}
171
+ </div>
172
+ </div>
173
+ </div>
174
+ </>
175
+ ))}
176
+ </div>
177
+ </div>
178
+ </div>
179
+ )
180
+ }
181
+ },
182
+ })
@@ -0,0 +1,203 @@
1
+ // 对话记录样式
2
+ .dialogueRecord {
3
+ width: 100%;
4
+ padding: 0;
5
+ }
6
+
7
+ // 头部区域
8
+ .header {
9
+ display: flex;
10
+ justify-content: space-between;
11
+ align-items: center;
12
+ padding: 20px 24px;
13
+ background: #fff;
14
+ border-radius: 8px;
15
+ margin-bottom: 24px;
16
+ }
17
+
18
+ .title {
19
+ font-size: 20px;
20
+ font-weight: 600;
21
+ color: #262626;
22
+ margin: 0;
23
+ }
24
+
25
+ .stats {
26
+ display: flex;
27
+ gap: 32px;
28
+ }
29
+
30
+ .statItem {
31
+ font-size: 15px;
32
+ color: #595959;
33
+
34
+ &:last-child {
35
+ color: #1890ff;
36
+ font-weight: 500;
37
+ }
38
+ }
39
+
40
+ // 对话容器
41
+ .dialogueContainer {
42
+ background: #f5f5f5;
43
+ border-radius: 8px;
44
+ padding: 24px;
45
+ }
46
+
47
+ // 聊天流
48
+ .chatFlow {
49
+ display: flex;
50
+ flex-direction: column;
51
+ gap: 16px;
52
+ }
53
+
54
+ // 左侧消息(AI提问)
55
+ .messageLeft {
56
+ display: flex;
57
+ justify-content: flex-start;
58
+ align-items: flex-start;
59
+
60
+ .messageBubble {
61
+ background: #fff;
62
+ color: #262626;
63
+ padding: 14px 16px;
64
+ border-radius: 8px 8px 8px 2px;
65
+ max-width: 70%;
66
+ line-height: 1.7;
67
+ font-size: 14px;
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 8px;
71
+ }
72
+ }
73
+
74
+ // 右侧消息(用户回答)
75
+ .messageRight {
76
+ display: flex;
77
+ justify-content: flex-end;
78
+ align-items: flex-start;
79
+ padding-right: 20px;
80
+
81
+ .messageBubble {
82
+ background: #e4ebfd;
83
+ color: #262626;
84
+ padding: 16px;
85
+ border-radius: 8px;
86
+ max-width: 70%;
87
+ line-height: 1.7;
88
+ font-size: 14px;
89
+ display: flex;
90
+ flex-direction: column;
91
+ gap: 12px;
92
+ }
93
+ }
94
+
95
+ .answerContent {
96
+ width: 100%;
97
+ }
98
+
99
+ .scoreTag {
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: flex-end;
103
+ gap: 6px;
104
+ }
105
+
106
+ .scoreValue {
107
+ font-size: 14px;
108
+ font-weight: 600;
109
+ color: #ff8c00;
110
+ }
111
+
112
+ .audioIcon {
113
+ font-size: 16px;
114
+ cursor: pointer;
115
+ opacity: 0.6;
116
+ flex-shrink: 0;
117
+ }
118
+
119
+ // 得分明细卡片
120
+ .scoreCard {
121
+ background: #ffffff;
122
+ padding: 16px;
123
+ border-radius: 8px;
124
+ align-self: stretch;
125
+ }
126
+
127
+ // 得分明细
128
+ .scoreDetails {
129
+ margin-bottom: 16px;
130
+
131
+ &:last-child {
132
+ margin-bottom: 0;
133
+ }
134
+ }
135
+
136
+ .detailsTitle {
137
+ font-size: 15px;
138
+ font-weight: 600;
139
+ color: #fa8c16;
140
+ margin-bottom: 12px;
141
+ }
142
+
143
+ .detailItem {
144
+ margin-bottom: 12px;
145
+
146
+ &:last-child {
147
+ margin-bottom: 0;
148
+ }
149
+ }
150
+
151
+ .detailHeader {
152
+ display: flex;
153
+ justify-content: space-between;
154
+ align-items: center;
155
+ margin-bottom: 6px;
156
+ }
157
+
158
+ .detailName {
159
+ font-size: 14px;
160
+ color: #262626;
161
+ font-weight: 500;
162
+ }
163
+
164
+ .detailScore {
165
+ font-size: 15px;
166
+ color: #52c41a;
167
+ font-weight: 600;
168
+ }
169
+
170
+ .tags {
171
+ display: flex;
172
+ gap: 8px;
173
+ flex-wrap: wrap;
174
+ align-items: center;
175
+ }
176
+
177
+ .tagLabel {
178
+ font-size: 13px;
179
+ color: #595959;
180
+ }
181
+
182
+ // 指导建议
183
+ .suggestion {
184
+ padding-top: 16px;
185
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
186
+ }
187
+
188
+ .suggestionTitle {
189
+ font-size: 15px;
190
+ font-weight: 600;
191
+ color: #fa8c16;
192
+ margin-bottom: 8px;
193
+ }
194
+
195
+ .suggestionContent {
196
+ font-size: 14px;
197
+ color: #262626;
198
+ line-height: 1.7;
199
+ }
200
+
201
+
202
+
203
+
@@ -0,0 +1,145 @@
1
+ import { defineComponent, ref } from 'vue'
2
+ import styles from './index.module.scss'
3
+ import DialogueBubble from '../DialogueBubble/index.jsx'
4
+ import SubDimensionItem from '../SubDimensionItem/index.jsx'
5
+
6
+ /**
7
+ * 维度详情组件
8
+ * @description 显示某个评分维度的详细信息,包括对话示例和子维度评分
9
+ */
10
+ export default defineComponent({
11
+ name: 'DimensionDetail',
12
+
13
+ props: {
14
+ // 维度信息
15
+ dimension: {
16
+ type: Object,
17
+ required: true,
18
+ // 数据格式: { name: '话术准确度', score: 10, total: 10, icon: '👏', description: '说明文字' }
19
+ },
20
+ // 类型:dialogue(对话类型)或 subdimension(子维度类型)
21
+ type: {
22
+ type: String,
23
+ default: 'dialogue',
24
+ validator: (value) => ['dialogue', 'subdimension'].includes(value),
25
+ },
26
+ // 对话数组(type为dialogue时使用)
27
+ dialogues: {
28
+ type: Array,
29
+ default: () => [],
30
+ },
31
+ // 子维度列表(type为subdimension时使用)
32
+ subDimensions: {
33
+ type: Array,
34
+ default: () => [],
35
+ },
36
+ },
37
+
38
+ setup(props) {
39
+ // 抽屉显示状态
40
+ const drawerVisible = ref(false)
41
+
42
+ // 打开抽屉
43
+ const openDrawer = () => {
44
+ drawerVisible.value = true
45
+ }
46
+
47
+ // 关闭抽屉
48
+ const closeDrawer = () => {
49
+ drawerVisible.value = false
50
+ }
51
+
52
+ // 获取评分的颜色类
53
+ const getScoreColor = (score, total) => {
54
+ const percentage = (score / total) * 100
55
+ if (percentage >= 90) return styles.scoreGreen
56
+ if (percentage >= 60) return styles.scoreOrange
57
+ return styles.scoreRed
58
+ }
59
+
60
+ return () => {
61
+ return (
62
+ <div class={styles.dimensionDetail}>
63
+ {/* 维度头部 */}
64
+ <div class={styles.header}>
65
+ <div class={styles.titleSection}>
66
+ <h2 class={styles.title}>{props.dimension.name}</h2>
67
+ <span class={[styles.score, getScoreColor(props.dimension.score, props.dimension.total)]}>
68
+ {props.dimension.score}/{props.dimension.total}分
69
+ </span>
70
+ </div>
71
+ {props.dimension.description && (
72
+ <div class={styles.description}>{props.dimension.description}</div>
73
+ )}
74
+ </div>
75
+
76
+ {/* 内容区域 */}
77
+ <div class={styles.content}>
78
+ {/* 对话类型:显示对话气泡 */}
79
+ {props.type === 'dialogue' && props.dialogues.length > 0 && (
80
+ <div class={styles.dialogueSection}>
81
+ {/* 高分话术标题 */}
82
+ <div class={styles.dialogueHeader}>
83
+ <div class={styles.dialogueTitle}>
84
+ <span class={styles.star}>💫</span>
85
+ <span>高分话术</span>
86
+ </div>
87
+ {props.dialogues.length > 1 && (
88
+ <div class={styles.viewMore} onClick={openDrawer}>
89
+ 查看更多
90
+ <span class={styles.arrow}>›</span>
91
+ </div>
92
+ )}
93
+ </div>
94
+
95
+ {/* 显示第一条对话 */}
96
+ <DialogueBubble
97
+ dialogue={props.dialogues[0]}
98
+ scoreDetails={props.dialogues[0].scoreDetails}
99
+ suggestion={props.dialogues[0].suggestion}
100
+ />
101
+ </div>
102
+ )}
103
+
104
+ {/* 子维度类型:显示子维度列表 */}
105
+ {props.type === 'subdimension' &&
106
+ props.subDimensions.map((subDim, index) => (
107
+ <SubDimensionItem
108
+ key={index}
109
+ name={subDim.name}
110
+ score={subDim.score}
111
+ total={subDim.total}
112
+ comment={subDim.comment}
113
+ />
114
+ ))}
115
+ </div>
116
+
117
+ {/* 抽屉:显示所有对话 */}
118
+ {props.type === 'dialogue' && (
119
+ <el-drawer
120
+ v-model={drawerVisible.value}
121
+ title="全部高分话术"
122
+ size="60%"
123
+ direction="rtl"
124
+ >
125
+ <div class={styles.drawerContent}>
126
+ {props.dialogues.map((dialogue, index) => (
127
+ <div key={index} class={styles.drawerItem}>
128
+ <div class={styles.drawerItemTitle}>
129
+ 对话 {index + 1}
130
+ </div>
131
+ <DialogueBubble
132
+ dialogue={dialogue}
133
+ scoreDetails={dialogue.scoreDetails}
134
+ suggestion={dialogue.suggestion}
135
+ />
136
+ </div>
137
+ ))}
138
+ </div>
139
+ </el-drawer>
140
+ )}
141
+ </div>
142
+ )
143
+ }
144
+ },
145
+ })
@@ -0,0 +1,126 @@
1
+ // 维度详情样式
2
+ .dimensionDetail {
3
+ background: #fff;
4
+ border-radius: 8px;
5
+ overflow: hidden;
6
+ }
7
+
8
+ .header {
9
+ background: #fff;
10
+ padding: 20px 24px;
11
+ border-bottom: 1px solid #f0f0f0;
12
+ }
13
+
14
+ .titleSection {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 12px;
18
+ margin-bottom: 12px;
19
+ }
20
+
21
+ .title {
22
+ font-size: 18px;
23
+ font-weight: 600;
24
+ color: #262626;
25
+ margin: 0;
26
+ }
27
+
28
+ .score {
29
+ font-size: 16px;
30
+ font-weight: 600;
31
+ background: #f0fdf4;
32
+ padding: 4px 12px;
33
+ border-radius: 4px;
34
+ }
35
+
36
+ .scoreGreen {
37
+ color: #52c41a;
38
+ }
39
+
40
+ .scoreOrange {
41
+ color: #fa8c16;
42
+ }
43
+
44
+ .scoreRed {
45
+ color: #ff4d4f;
46
+ }
47
+
48
+ .description {
49
+ font-size: 14px;
50
+ color: #8c8c8c;
51
+ line-height: 1.6;
52
+ }
53
+
54
+ .content {
55
+ padding: 20px 24px;
56
+ }
57
+
58
+ // 对话区域样式
59
+ .dialogueSection {
60
+ width: 100%;
61
+ }
62
+
63
+ .dialogueHeader {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ margin-bottom: 0;
68
+ background: #f8f8f8;
69
+ padding: 12px 16px;
70
+ border-radius: 8px 8px 0 0;
71
+ }
72
+
73
+ .dialogueTitle {
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 8px;
77
+ font-size: 16px;
78
+ font-weight: 600;
79
+ color: #262626;
80
+ }
81
+
82
+ .star {
83
+ font-size: 18px;
84
+ }
85
+
86
+ .viewMore {
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 4px;
90
+ font-size: 14px;
91
+ color: #8c8c8c;
92
+ cursor: pointer;
93
+ transition: color 0.3s;
94
+
95
+ &:hover {
96
+ color: #1890ff;
97
+ }
98
+ }
99
+
100
+ .arrow {
101
+ font-size: 16px;
102
+ font-weight: bold;
103
+ }
104
+
105
+ // 抽屉内容样式
106
+ .drawerContent {
107
+ padding: 0 24px;
108
+ }
109
+
110
+ .drawerItem {
111
+ margin-bottom: 32px;
112
+
113
+ &:last-child {
114
+ margin-bottom: 0;
115
+ }
116
+ }
117
+
118
+ .drawerItemTitle {
119
+ font-size: 16px;
120
+ font-weight: 600;
121
+ color: #262626;
122
+ margin-bottom: 16px;
123
+ padding-bottom: 12px;
124
+ border-bottom: 1px solid #f0f0f0;
125
+ }
126
+