ai-read-over-mobile 0.0.1

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 (44) hide show
  1. package/README.md +33 -0
  2. package/components/demo/api/index.js +104 -0
  3. package/components/demo/index.js +7 -0
  4. package/components/demo/plugins/cache.js +77 -0
  5. package/components/demo/src/chat-tools.vue +420 -0
  6. package/components/demo/src/main.vue +783 -0
  7. package/components/demo/src/member-table.vue +298 -0
  8. package/components/demo/src/read-over.vue +398 -0
  9. package/components/demo/src/tab-filter.vue +313 -0
  10. package/components/demo/static/bg-img.svg +10 -0
  11. package/components/demo/static/cai-active.png +0 -0
  12. package/components/demo/static/cai.png +0 -0
  13. package/components/demo/static/correct.png +0 -0
  14. package/components/demo/static/error.png +0 -0
  15. package/components/demo/static/filter-block.svg +23 -0
  16. package/components/demo/static/filter-block_hover.svg +23 -0
  17. package/components/demo/static/filter-block_selected.svg +23 -0
  18. package/components/demo/static/filter.png +0 -0
  19. package/components/demo/static/iconfont/iconfont.css +29 -0
  20. package/components/demo/static/iconfont/iconfont.js +1 -0
  21. package/components/demo/static/iconfont/iconfont.json +37 -0
  22. package/components/demo/static/iconfont/iconfont.ttf +0 -0
  23. package/components/demo/static/logo.png +0 -0
  24. package/components/demo/static/robot.png +0 -0
  25. package/components/demo/static/send-icon.png +0 -0
  26. package/components/demo/static/zan-active.png +0 -0
  27. package/components/demo/static/zan.png +0 -0
  28. package/components/demo/utils/aes-utils.js +35 -0
  29. package/components/demo/utils/config.js +46 -0
  30. package/components/demo/utils/constants.js +15 -0
  31. package/components/demo/utils/request.js +74 -0
  32. package/components/index.js +15 -0
  33. package/dist/ai-read-over-mobile.common.js +12129 -0
  34. package/dist/ai-read-over-mobile.common.js.map +1 -0
  35. package/dist/ai-read-over-mobile.css +1 -0
  36. package/dist/ai-read-over-mobile.umd.js +12148 -0
  37. package/dist/ai-read-over-mobile.umd.js.map +1 -0
  38. package/dist/ai-read-over-mobile.umd.min.js +18 -0
  39. package/dist/ai-read-over-mobile.umd.min.js.map +1 -0
  40. package/dist/demo.html +1 -0
  41. package/dist/img/filter-block.6f369747.svg +23 -0
  42. package/dist/img/filter-block_hover.5314be0a.svg +23 -0
  43. package/dist/img/filter-block_selected.f523d7f3.svg +23 -0
  44. package/package.json +44 -0
@@ -0,0 +1,298 @@
1
+ <template>
2
+ <div class="member-table-contain" @keyup.enter="searchData">
3
+ <el-input
4
+ placeholder="请输入搜索内容"
5
+ v-model="searchInput">
6
+ <i slot="suffix" class="el-input__icon el-icon-search" @click="searchData"></i>
7
+ </el-input>
8
+ <div class="content">
9
+ <div class="member-list"
10
+ v-for="item in activeData"
11
+ :class="{'member-list-selected': selectedMap[item.id]}"
12
+ :key="item.id"
13
+ @click="selectMember(item)">
14
+ <div>
15
+ <span class="loading-block" v-if="!replyCache[item.id]">
16
+ <i class="el-icon-loading"></i>
17
+ </span>
18
+ {{ item.title }}
19
+ </div>
20
+ <span class="member-list-icon">
21
+ <i class="el-icon-success icon-select"></i>
22
+ <i class="el-icon-circle-plus-outline icon-hover"></i>
23
+ </span>
24
+ </div>
25
+ </div>
26
+ <div class="pagination">
27
+ <el-pagination
28
+ layout="prev, pager, next"
29
+ :small="true"
30
+ :page-size="pageSize"
31
+ :current-page="pageNo"
32
+ :total="cacheShowData.length"
33
+ @current-change="setActiveData">
34
+ </el-pagination>
35
+ </div>
36
+ </div>
37
+ </template>
38
+ <script>
39
+ export default {
40
+ name: 'MemberTable',
41
+ props: {
42
+ checkData: {
43
+ type: Array,
44
+ default: () => []
45
+ },
46
+ showData: {
47
+ type: Array,
48
+ default: () => []
49
+ },
50
+ replyCache: {
51
+ type: Object,
52
+ default: () => {
53
+ }
54
+ }
55
+ },
56
+ watch: {
57
+ checkData: {
58
+ handler() {
59
+ this.selectedMap = {};
60
+ this.checkData.map((item) => {
61
+ this.selectedMap[item.id] = item;
62
+ });
63
+ this.selectedData = [...this.checkData];
64
+ this.$forceUpdate();
65
+ },
66
+ immediate: true
67
+ },
68
+ showData: {
69
+ handler() {
70
+ this.cacheShowData = [...this.showData];
71
+ this.setActiveData();
72
+ },
73
+ immediate: true
74
+ },
75
+ },
76
+ data() {
77
+ return {
78
+ searchInput: '',
79
+ pageNo: 1,
80
+ pageSize: 10,
81
+ activeData: [],
82
+ selectedData: [],
83
+ selectedMap: {},
84
+ cacheShowData: [],
85
+ }
86
+ },
87
+ methods: {
88
+ setActiveData(pageNo) {
89
+ if (pageNo) this.pageNo = pageNo;
90
+ this.activeData = this.cacheShowData.slice(this.pageSize * (this.pageNo - 1), this.pageSize * this.pageNo);
91
+ },
92
+ selectMember(item) {
93
+ if (this.selectedMap[item.id]) return;
94
+ this.selectedData.unshift(item);
95
+ this.selectedData.pop();
96
+ this.$emit('on-select-member', this.selectedData);
97
+ },
98
+ searchData() {
99
+ this.pageNo = 1;
100
+ this.cacheShowData = this.searchInput === '' ? [...this.showData] :
101
+ this.showData.filter((item) => item.title.toString().indexOf(this.searchInput) > -1);
102
+ this.setActiveData();
103
+ }
104
+ },
105
+ }
106
+ </script>
107
+ <style lang="scss" scoped>
108
+ .member-table-contain {
109
+ width: 100%;
110
+ height: 100%;
111
+ padding: 16px;
112
+ padding-bottom: 8px;
113
+ box-sizing: border-box;
114
+ background: linear-gradient(168.988deg, rgb(255, 255, 255) 4%, rgb(238, 238, 255) 100%);
115
+ border-radius: 12px;
116
+ box-shadow: rgba(48, 96, 144, 0.48) 0 0 16px;
117
+ display: flex;
118
+ flex-direction: column;
119
+
120
+ ::v-deep(.el-input__inner) {
121
+ border-radius: 24px;
122
+ height: 40px;
123
+ line-height: 40px;
124
+ font-size: 14px;
125
+ }
126
+
127
+ .el-icon-search {
128
+ cursor: pointer;
129
+ color: rgba(44, 44, 44, 1);
130
+ font-size: 16px;
131
+ }
132
+
133
+ .member-list {
134
+ display: flex;
135
+ justify-content: space-between;
136
+ align-items: center;
137
+ height: 40px;
138
+ border-radius: 26px;
139
+ padding: 10px 16px;
140
+ box-sizing: border-box;
141
+ font-size: 14px;
142
+ cursor: pointer;
143
+ transition: all 0.3s ease;
144
+ margin-bottom: 8px;
145
+
146
+ &:hover {
147
+ background-color: rgba(32, 40, 64, 0.08);
148
+
149
+ .icon-hover {
150
+ display: block;
151
+ }
152
+ }
153
+
154
+ .loading-block {
155
+ margin-right: 8px;
156
+ display: inline-flex;
157
+ align-items: center;
158
+ }
159
+ }
160
+
161
+ .member-list-icon {
162
+ font-size: 20px;
163
+ display: inline-flex;
164
+ align-items: center;
165
+ color: #409eff;
166
+ }
167
+
168
+ .icon-select,
169
+ .icon-hover {
170
+ display: none;
171
+ }
172
+
173
+ .member-list-selected {
174
+ background-color: rgba(64, 158, 255, 0.1);
175
+
176
+ .icon-select {
177
+ display: block;
178
+ }
179
+
180
+ &:hover {
181
+ .icon-hover {
182
+ display: none;
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ .content {
189
+ flex: 1;
190
+ margin: 8px 0;
191
+ overflow-y: auto;
192
+ padding-right: 4px;
193
+
194
+ /* 滚动条样式 */
195
+ &::-webkit-scrollbar {
196
+ width: 4px;
197
+ border-radius: 10px;
198
+ }
199
+
200
+ &::-webkit-scrollbar-track {
201
+ background: transparent;
202
+ }
203
+
204
+ &::-webkit-scrollbar-thumb {
205
+ background: rgba(96, 128, 240, 0.6);
206
+ border-radius: 4px;
207
+ transition: all 0.2s linear;
208
+ }
209
+
210
+ &::-webkit-scrollbar-thumb:hover {
211
+ background: rgba(96, 128, 240, 0.8);
212
+ }
213
+ }
214
+
215
+ .pagination {
216
+ text-align: center;
217
+ padding: 8px 0;
218
+
219
+ ::v-deep(.el-pager li) {
220
+ background: transparent;
221
+ min-width: 32px;
222
+ height: 32px;
223
+ line-height: 32px;
224
+ font-size: 13px;
225
+ }
226
+
227
+ ::v-deep(.el-pagination .btn-next),
228
+ ::v-deep(.el-pagination .btn-prev) {
229
+ background: transparent;
230
+ min-width: 32px;
231
+ height: 32px;
232
+ line-height: 32px;
233
+ }
234
+
235
+ ::v-deep(.el-pagination button:disabled) {
236
+ background: transparent;
237
+ }
238
+ }
239
+
240
+ // 响应式设计
241
+ @media screen and (max-width: 768px) {
242
+ .member-table-contain {
243
+ padding: 20px;
244
+ padding-bottom: 8px;
245
+
246
+ ::v-deep(.el-input__inner) {
247
+ height: 44px;
248
+ line-height: 44px;
249
+ font-size: 15px;
250
+ }
251
+
252
+ .member-list {
253
+ height: 44px;
254
+ padding: 12px 18px;
255
+ font-size: 15px;
256
+ margin-bottom: 10px;
257
+ }
258
+
259
+ .member-list-icon {
260
+ font-size: 22px;
261
+ }
262
+ }
263
+
264
+ .pagination {
265
+ padding: 10px 0;
266
+
267
+ ::v-deep(.el-pager li) {
268
+ min-width: 36px;
269
+ height: 36px;
270
+ line-height: 36px;
271
+ font-size: 14px;
272
+ }
273
+
274
+ ::v-deep(.el-pagination .btn-next),
275
+ ::v-deep(.el-pagination .btn-prev) {
276
+ min-width: 36px;
277
+ height: 36px;
278
+ line-height: 36px;
279
+ }
280
+ }
281
+ }
282
+
283
+ // 平板设备
284
+ @media screen and (min-width: 769px) and (max-width: 1024px) {
285
+ .member-table-contain {
286
+ padding: 20px;
287
+ padding-bottom: 8px;
288
+ }
289
+ }
290
+
291
+ // 大屏幕设备
292
+ @media screen and (min-width: 1025px) {
293
+ .member-table-contain {
294
+ padding: 24px;
295
+ padding-bottom: 8px;
296
+ }
297
+ }
298
+ </style>
@@ -0,0 +1,398 @@
1
+ <template>
2
+ <div class="read-over-contain">
3
+ <div class="exercises-answer">
4
+ <div class="question-container">
5
+ <div class="question-stem-content">
6
+ <i class="iconfont icon-help-fill" style="color: #8282F0;font-size: 26px"></i>题干
7
+ <div class="question-score">{{ exercisesData.score }}分</div>
8
+ </div>
9
+ <div class="question-detail">
10
+ <p v-html="exercisesData.question"></p>
11
+ </div>
12
+ </div>
13
+ <div class="question-container answer-container">
14
+ <div class="question-stem-content answer-stem-content">
15
+ <i class="iconfont icon-messageSolid" style="color:#8282F0;font-size: 20px"></i>
16
+ 回答
17
+ </div>
18
+ <div class="question-detail answer-detail" v-html="exercisesData.answer" v-if="exercisesData.answer"></div>
19
+ <div class="question-detail answer-detail" v-else>
20
+ 暂无作答
21
+ </div>
22
+ </div>
23
+ </div>
24
+ <div class="exercises-read-over"
25
+ v-loading="!analyzeData || Object.keys(analyzeData).length < 1 || isReanswering"
26
+ :element-loading-text="isReanswering ? '重新批阅中...' : (!analyzeData ? '无数据' : '分析中,请稍后')">
27
+ <template v-if="analyzeData">
28
+ <div class="score-badge">{{ analyzeData.score }}分</div>
29
+ <div class="exercises-read-over-content">
30
+ <div class="list" v-for="item in analyzeData.jsonContent" :key="item.title || item.analysis"
31
+ style="width: 100%">
32
+ <p class="title" v-if="item.title">{{ item.title }}</p>
33
+ <p class="content" v-html="item.analysis"></p>
34
+ </div>
35
+ </div>
36
+ <div class="read-over-actions">
37
+ <div class="robot-reanswer" @click="reanswer(exercisesData)" :class="{'disabled': isReanswering}">
38
+ <i class="el-icon-refresh-right"></i>
39
+ 重新批阅
40
+ </div>
41
+ <div class="apply-button-container" v-if="!analyzeData.accepted">
42
+ <el-button type="primary" @click="notyApply">应用</el-button>
43
+ </div>
44
+ </div>
45
+ </template>
46
+ </div>
47
+ </div>
48
+ </template>
49
+ <script>
50
+ import ChatTools from "./chat-tools.vue";
51
+ import '../static/iconfont/iconfont.css';
52
+
53
+ export default {
54
+ name: 'ReadOver',
55
+ components: {
56
+ ChatTools
57
+ },
58
+ props: {
59
+ exercisesData: {
60
+ type: Object,
61
+ default: () => {
62
+ }
63
+ },
64
+ analyzeData: {
65
+ type: Object,
66
+ default: () => {
67
+ }
68
+ },
69
+ isReanswering: {
70
+ type: Boolean,
71
+ default: false
72
+ }
73
+ },
74
+ data() {
75
+ return {}
76
+ },
77
+ methods: {
78
+ reanswer(list) {
79
+ if (this.isReanswering) return;
80
+ this.$emit('on-reanswer', list);
81
+ },
82
+ notyApply() {
83
+ this.$emit('on-noty-apply', this.analyzeData, this.exercisesData);
84
+ }
85
+ },
86
+ }
87
+ </script>
88
+ <style lang="scss" scoped>
89
+ .read-over-contain {
90
+ width: 100%;
91
+ height: 100%;
92
+ overflow-y: auto;
93
+ padding: 16px;
94
+ box-sizing: border-box;
95
+
96
+ /* 滚动条样式 */
97
+ &::-webkit-scrollbar {
98
+ width: 6px;
99
+ border-radius: 10px;
100
+ }
101
+
102
+ &::-webkit-scrollbar-track {
103
+ background: transparent;
104
+ }
105
+
106
+ &::-webkit-scrollbar-thumb {
107
+ background: rgba(96, 128, 240, 0.6);
108
+ border-radius: 4px;
109
+ transition: all 0.2s linear;
110
+ }
111
+
112
+ &::-webkit-scrollbar-thumb:hover {
113
+ background: rgba(96, 128, 240, 0.8);
114
+ }
115
+ }
116
+
117
+ .exercises-answer {
118
+ position: relative;
119
+ overflow: hidden;
120
+ padding: 20px;
121
+ border-radius: 12px;
122
+ background: #fff;
123
+ margin-bottom: 20px;
124
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
125
+ }
126
+
127
+ .question-container {
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: 16px;
131
+ margin-bottom: 20px;
132
+
133
+ .question-stem-content {
134
+ font-weight: bold;
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 8px;
138
+
139
+ .question-score {
140
+ font-size: 10px;
141
+ color: rgb(32, 40, 64);
142
+ background-color: #D6D6FA;
143
+ padding: 5px 12px;
144
+ border-radius: 50px;
145
+ margin-left: auto;
146
+ }
147
+ }
148
+
149
+ .question-detail {
150
+ width: 100%;
151
+ font-size: 14px;
152
+
153
+ p {
154
+ margin: 0;
155
+ font-size: 14px;
156
+ color: rgb(32, 40, 64);
157
+ word-break: break-word;
158
+ }
159
+ }
160
+ }
161
+
162
+ :deep(.question-detail) {
163
+ img {
164
+ max-width: 100% !important;
165
+ height: auto !important;
166
+ }
167
+ }
168
+
169
+ .answer-container {
170
+ margin: 20px 0;
171
+
172
+ .question-detail {
173
+ border: 0;
174
+ }
175
+
176
+ .answer-stem-content {
177
+ .iconfont {
178
+ color: #6200ea;
179
+ }
180
+ }
181
+
182
+ .answer-detail {
183
+ p {
184
+ font-weight: normal;
185
+ }
186
+ }
187
+ }
188
+
189
+ .exercises-read-over {
190
+ position: relative;
191
+ padding: 5px;
192
+ border-radius: 12px;
193
+ background: #fff;
194
+ min-height: 160px;
195
+ margin-top: 20px;
196
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
197
+ display: flex;
198
+ flex-direction: column;
199
+
200
+ .score-badge {
201
+ position: absolute;
202
+ top: 20px;
203
+ right: 20px;
204
+ width: 50px;
205
+ height: 55px;
206
+ background: linear-gradient(to bottom right, #FF8686, #FF4242);
207
+ color: #fff;
208
+ text-align: center;
209
+ line-height: 52px;
210
+ border-radius: 0; /* 六边形不需要圆角 */
211
+ font-size: 14px;
212
+ font-weight: bold;
213
+ display: flex;
214
+ align-items: center;
215
+ justify-content: center;
216
+ transform: translateY(-10px);
217
+ z-index: 1;
218
+
219
+ clip-path: polygon(
220
+ 50% 0%,
221
+ 100% 25%,
222
+ 100% 75%,
223
+ 50% 100%,
224
+ 0% 75%,
225
+ 0% 25%
226
+ );
227
+ }
228
+
229
+ .exercises-read-over-content {
230
+ flex-grow: 1;
231
+ margin: 0 auto;
232
+ padding: 0 0px;
233
+ padding-right: 80px;
234
+
235
+ .title {
236
+ font-weight: 700;
237
+ font-size: 14px;
238
+ color: rgb(96, 96, 224);
239
+ margin-bottom: 8px;
240
+ }
241
+
242
+ .content {
243
+ font-size: 16px;
244
+ color: rgb(32, 40, 64);
245
+ line-height: 24px;
246
+ margin-bottom: 16px;
247
+ }
248
+ }
249
+
250
+ .read-over-actions {
251
+ display: flex;
252
+ justify-content: flex-end;
253
+ gap: 16px;
254
+ margin-top: 20px;
255
+
256
+ .robot-reanswer {
257
+ width: 100px;
258
+ height: 36px;
259
+ font-size: 14px;
260
+ text-align: center;
261
+ line-height: 36px;
262
+ cursor: pointer;
263
+ transition: all 0.3s ease;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ gap: 4px;
268
+ color: #6E6EE3;
269
+ margin-right: auto;
270
+
271
+ i {
272
+ font-size: 20px;
273
+ }
274
+
275
+ &.disabled {
276
+ opacity: 0.5;
277
+ cursor: not-allowed;
278
+ }
279
+ }
280
+
281
+ .apply-button-container {
282
+ .el-button {
283
+ width: 100px;
284
+ height: 36px;
285
+ background-color: #8080F0;
286
+ border-radius: 18px;
287
+ color: #fff;
288
+ transition: all 0.3s ease;
289
+ border: none;
290
+
291
+ &:hover {
292
+ transform: translateY(-1px);
293
+ box-shadow: 0 4px 8px rgba(98, 0, 234, 0.2);
294
+ }
295
+ }
296
+ }
297
+ }
298
+ }
299
+
300
+ // 响应式设计
301
+ @media screen and (max-width: 768px) {
302
+ .read-over-contain {
303
+ padding: 20px;
304
+ }
305
+
306
+ .exercises-answer {
307
+ padding: 24px;
308
+ }
309
+
310
+ .question-container {
311
+ gap: 16px;
312
+ margin-bottom: 20px;
313
+
314
+ .question-stem-content {
315
+ min-width: 64px;
316
+ height: 40px;
317
+ font-size: 16px;
318
+ }
319
+
320
+ .question-detail {
321
+ p {
322
+ font-size: 14px;
323
+ }
324
+ }
325
+ }
326
+
327
+ .exercises-read-over {
328
+ .exercises-read-over-content {
329
+ padding: 0 16px;
330
+
331
+ .title {
332
+ font-size: 15px;
333
+ margin-bottom: 8px;
334
+ }
335
+
336
+ .content {
337
+ font-size: 14px;
338
+ line-height: 24px;
339
+ margin-bottom: 16px;
340
+ width: calc(100% - 50px);
341
+ }
342
+ }
343
+
344
+ .score {
345
+ width: 64px;
346
+ height: 64px;
347
+ line-height: 64px;
348
+ font-size: 12px;
349
+ top: 20px;
350
+ left: 20px;
351
+
352
+ .score-number {
353
+ font-size: 26px;
354
+ }
355
+ }
356
+
357
+ .type {
358
+ width: 64px;
359
+ height: 32px;
360
+ line-height: 32px;
361
+ font-size: 12px;
362
+ right: 20px;
363
+ top: 20px;
364
+ }
365
+ }
366
+ }
367
+
368
+ // 平板设备
369
+ @media screen and (min-width: 769px) and (max-width: 1024px) {
370
+ .exercises-answer-bg {
371
+ max-width: 280px;
372
+ height: 186px;
373
+ }
374
+
375
+ .exercises-read-over {
376
+ .exercises-read-over-content {
377
+ max-width: 600px;
378
+ }
379
+ }
380
+ }
381
+
382
+ // 大屏幕设备
383
+ @media screen and (min-width: 1025px) {
384
+ .read-over-contain {
385
+ padding: 24px;
386
+ }
387
+
388
+ .exercises-answer {
389
+ padding: 24px;
390
+ }
391
+
392
+ .exercises-read-over {
393
+ .exercises-read-over-content {
394
+ max-width: 800px;
395
+ }
396
+ }
397
+ }
398
+ </style>