ai-chat-bot-interface 1.7.8 → 1.7.9

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 (55) hide show
  1. package/dist/assets/index-DQulfwi9.css +9 -0
  2. package/dist/assets/index-Dkddqe_3.js +123 -0
  3. package/{index.html → dist/index.html} +2 -1
  4. package/dist/src/index.d.ts +0 -0
  5. package/package.json +26 -5
  6. package/.prettierignore +0 -5
  7. package/.prettierrc.cjs +0 -37
  8. package/.vscode/extensions.json +0 -3
  9. package/index.js +0 -11
  10. package/src/App.vue +0 -39
  11. package/src/ChatUi.less +0 -301
  12. package/src/ChatUi.vue +0 -1087
  13. package/src/assets/styles/public.less +0 -152
  14. package/src/assets/vue.svg +0 -1
  15. package/src/components/DishesCard.vue +0 -369
  16. package/src/components/DishesList.vue +0 -218
  17. package/src/components/MarkdownPlan/MarkdownViewer.vue +0 -34
  18. package/src/components/OperateModule.less +0 -186
  19. package/src/components/OperateModule.vue +0 -392
  20. package/src/components/PlanCard.vue +0 -114
  21. package/src/components/StoreList/StoreCard.vue +0 -72
  22. package/src/components/StoreList/StoreList.vue +0 -27
  23. package/src/components/StoreList/mock.js +0 -411
  24. package/src/components/assistantReplay/assistantReplay.vue +0 -78
  25. package/src/components/icons/ArrowDown.vue +0 -26
  26. package/src/components/icons/ArrowRight.vue +0 -19
  27. package/src/components/icons/BackIcon.vue +0 -19
  28. package/src/components/icons/ClearIcon.vue +0 -18
  29. package/src/components/icons/CloseIcon.vue +0 -17
  30. package/src/components/icons/NewSessionIcon.vue +0 -20
  31. package/src/components/icons/OkIcon.vue +0 -26
  32. package/src/components/icons/SendIcon.vue +0 -22
  33. package/src/components/icons/ThinkingIcon.vue +0 -28
  34. package/src/components/icons/addIcon.vue +0 -18
  35. package/src/components/icons/cameraIcon.vue +0 -22
  36. package/src/components/icons/closeBorderIcon.vue +0 -35
  37. package/src/components/icons/fileIcon.vue +0 -18
  38. package/src/components/icons/loadingIcon.vue +0 -76
  39. package/src/components/icons/loadingIcon2.vue +0 -88
  40. package/src/components/icons/newChat.vue +0 -18
  41. package/src/components/icons/pictureIcon.vue +0 -22
  42. package/src/components/icons/processBar.vue +0 -115
  43. package/src/components/icons/progressRing.vue +0 -63
  44. package/src/components/icons/sendLoadingIcon.vue +0 -35
  45. package/src/components/icons/tagIcon.vue +0 -18
  46. package/src/components/imgeList.vue +0 -63
  47. package/src/components/personalForm/personalForm.vue +0 -634
  48. package/src/components/popup/popup.vue +0 -178
  49. package/src/main.js +0 -26
  50. package/src/style.css +0 -4
  51. package/src/utils/imagesViewer.js +0 -8
  52. package/src/utils/request.js +0 -52
  53. package/src/utils/tools.js +0 -20
  54. package/vite.config.js +0 -33
  55. /package/{public → dist}/vite.svg +0 -0
@@ -1,634 +0,0 @@
1
- <script setup>
2
- import { computed, onMounted, ref } from 'vue';
3
- import ArrowRight from '../icons/ArrowRight.vue';
4
- import Popup from '../popup/popup.vue';
5
- import { showToast } from 'vant';
6
- import { Field } from 'vant';
7
-
8
- const showPopup = ref(false);
9
- const props = defineProps({
10
- query: {
11
- type: String,
12
- default: '',
13
- },
14
- });
15
-
16
- const dialogInfo = ref({
17
- key: 'sex',
18
- sex: '',
19
- age: '',
20
- height: '',
21
- weight: '',
22
- sport: '',
23
- taste: [],
24
- taboo: [],
25
- title: '标题',
26
- unit: '',
27
- dialogHeight: '50vh',
28
- min: 0,
29
- max: 100,
30
- type: 'digit',
31
- });
32
-
33
- const sportList = [
34
- {
35
- key: 'rest',
36
- name: '休息状态',
37
- sub: '卧床或者坐式休息',
38
- },
39
- {
40
- key: 'sedentary',
41
- name: '久坐',
42
- sub: '坐式工作',
43
- },
44
- {
45
- key: 'light',
46
- name: '轻体力',
47
- sub: '站立或需要走动的工作',
48
- },
49
- {
50
- key: 'medium',
51
- name: '中体力',
52
- sub: '走动多的工作',
53
- },
54
- {
55
- key: 'heavy',
56
- name: '重体力',
57
- sub: '高强度体力工作',
58
- },
59
- ];
60
- const tasteList = [
61
- '不吃辣',
62
- '不吃葱',
63
- '不吃姜',
64
- '不吃蒜',
65
- '不吃糖',
66
- '不吃鱼',
67
- '不吃虾',
68
- '不吃牛肉',
69
- '不吃鸡肉',
70
- '不吃猪肉',
71
- ];
72
- const tabooList = ['高GI', '高饱和脂肪酸', '高嘌呤', '高盐', '高胆固醇'];
73
-
74
- const pfForm = ref([
75
- {
76
- key: 'sex',
77
- label: '性别',
78
- value: '',
79
- placeholder: '请输选择',
80
- required: true,
81
- },
82
- {
83
- key: 'age',
84
- label: '年龄',
85
- value: '',
86
- placeholder: '请输入年龄',
87
- unit: '岁',
88
- required: true,
89
- },
90
- {
91
- key: 'height',
92
- label: '身高',
93
- value: '',
94
- placeholder: '请输入身高',
95
- unit: 'cm',
96
- required: true,
97
- },
98
- {
99
- key: 'weight',
100
- label: '体重',
101
- value: '',
102
- placeholder: '请输入体重',
103
- unit: 'kg',
104
- required: true,
105
- },
106
- {
107
- key: 'sport',
108
- label: '日常运动水平',
109
- value: '久坐',
110
- placeholder: '请输入',
111
- required: true,
112
- },
113
- {
114
- key: 'taste',
115
- label: '口味偏好及饮食禁忌',
116
- value: '',
117
- taste: [],
118
- taboo: [],
119
- placeholder: '无忌口',
120
- required: false,
121
- },
122
- ]);
123
-
124
- const Emits = defineEmits(['submit']);
125
-
126
- onMounted(() => {
127
- const form = localStorage.getItem('personalInfo');
128
- if (form) {
129
- const formData = JSON.parse(form);
130
- for (let i = 0; i < pfForm.value.length; i++) {
131
- const idx = formData.findIndex((con) => con.key === pfForm.value[i].key);
132
- pfForm.value[i] = { ...pfForm.value[i], ...formData[idx] };
133
- }
134
- }
135
- });
136
-
137
- const isValid = computed(() => {
138
- return pfForm.value
139
- .filter((item) => item.key !== 'taste')
140
- .every((item) => item.value !== '');
141
- });
142
-
143
- const handleSelect = (item) => {
144
- dialogInfo.value.key = item.key;
145
-
146
- switch (item.key) {
147
- case 'sex':
148
- dialogInfo.value.title = '选择性别';
149
- dialogInfo.value.dialogHeight = '300px';
150
- dialogInfo.value.sex = item.value;
151
- break;
152
- case 'age':
153
- dialogInfo.value.title = '设置年龄';
154
- dialogInfo.value.dialogHeight = '240px';
155
- dialogInfo.value.unit = item.unit;
156
- dialogInfo.value.age = item.value;
157
- dialogInfo.value.min = 6;
158
- dialogInfo.value.max = 100;
159
- dialogInfo.value.type = 'number';
160
- break;
161
- case 'height':
162
- dialogInfo.value.title = '设置身高';
163
- dialogInfo.value.dialogHeight = '240px';
164
- dialogInfo.value.unit = item.unit;
165
- dialogInfo.value.height = item.value;
166
- dialogInfo.value.min = 100;
167
- dialogInfo.value.max = 220;
168
- dialogInfo.value.type = 'digit';
169
- break;
170
- case 'weight':
171
- dialogInfo.value.title = '设置体重';
172
- dialogInfo.value.dialogHeight = '240px';
173
- dialogInfo.value.unit = item.unit;
174
- dialogInfo.value.weight = item.value;
175
- dialogInfo.value.min = 10;
176
- dialogInfo.value.max = 150;
177
- dialogInfo.value.type = 'digit';
178
- break;
179
- case 'sport':
180
- dialogInfo.value.title = '日常运动水平';
181
- dialogInfo.value.dialogHeight = '420px';
182
- dialogInfo.value.unit = '';
183
- dialogInfo.value.sport = item.value;
184
- break;
185
- case 'taste':
186
- dialogInfo.value.title = '口味偏好&饮食禁忌';
187
- dialogInfo.value.dialogHeight = '500px';
188
- dialogInfo.value.unit = '';
189
- dialogInfo.value.taste = [...item.taste];
190
- dialogInfo.value.taboo = [...item.taboo];
191
- break;
192
- }
193
- console.log(dialogInfo.value, item);
194
- showPopup.value = true;
195
- };
196
-
197
- const handleConfirm = () => {
198
- switch (dialogInfo.value.key) {
199
- case 'sex':
200
- if (!dialogInfo.value.sex) {
201
- showToast('请选择性别');
202
- return;
203
- }
204
- pfForm.value.find((item) => item.key === 'sex').value =
205
- dialogInfo.value.sex;
206
- break;
207
- case 'age':
208
- if (!dialogInfo.value.age) {
209
- showToast('请输入年龄');
210
- return;
211
- }
212
- pfForm.value.find((item) => item.key === 'age').value =
213
- dialogInfo.value.age;
214
- break;
215
- case 'height':
216
- if (!dialogInfo.value.height) {
217
- showToast('请输入身高');
218
- return;
219
- }
220
- pfForm.value.find((item) => item.key === 'height').value =
221
- dialogInfo.value.height;
222
- break;
223
- case 'weight':
224
- if (!dialogInfo.value.weight) {
225
- showToast('请输入体重');
226
- return;
227
- }
228
- pfForm.value.find((item) => item.key === 'weight').value =
229
- dialogInfo.value.weight;
230
- break;
231
- case 'sport':
232
- if (!dialogInfo.value.sport) {
233
- showToast('请选择日常运动水平');
234
- return;
235
- }
236
- pfForm.value.find((item) => item.key === 'sport').value =
237
- dialogInfo.value.sport;
238
- break;
239
- case 'taste':
240
- pfForm.value.find((item) => item.key === 'taste').taste =
241
- dialogInfo.value.taste;
242
- pfForm.value.find((item) => item.key === 'taste').taboo =
243
- dialogInfo.value.taboo;
244
- pfForm.value.find((item) => item.key === 'taste').value = [
245
- ...dialogInfo.value.taste,
246
- ...dialogInfo.value.taboo,
247
- ].join('、');
248
- break;
249
- }
250
-
251
- showPopup.value = false;
252
- };
253
-
254
- const handleSubmit = () => {
255
- if (!isValid.value) {
256
- showToast('请填写完整信息');
257
- return;
258
- }
259
-
260
- const ageIdx = pfForm.value.findIndex((item) => item.key === 'age');
261
- const heightIdx = pfForm.value.findIndex((item) => item.key === 'height');
262
- const weightIdx = pfForm.value.findIndex((item) => item.key === 'weight');
263
-
264
- if (pfForm.value[ageIdx].value < 6 || pfForm.value[ageIdx].value > 100) {
265
- showToast('年龄需要在6-100岁');
266
- return;
267
- }
268
- if (
269
- pfForm.value[heightIdx].value < 100 ||
270
- pfForm.value[heightIdx].value > 220
271
- ) {
272
- showToast('身高需要在100-220cm');
273
- return;
274
- }
275
- if (
276
- pfForm.value[weightIdx].value < 10 ||
277
- pfForm.value[weightIdx].value > 150
278
- ) {
279
- showToast('体重需要在10-150kg');
280
- return;
281
- }
282
-
283
- localStorage.setItem('personalInfo', JSON.stringify(pfForm.value));
284
- const msg = `${props.query};
285
- 性别:${pfForm.value.find((item) => item.key === 'sex').value};
286
- 年龄:${pfForm.value[ageIdx].value}${pfForm.value[ageIdx].unit || ''};
287
- 身高:${pfForm.value[heightIdx].value}${pfForm.value[heightIdx].unit || ''};
288
- 体重:${pfForm.value[weightIdx].value}${pfForm.value[weightIdx].unit || ''};
289
- 日常运动水平:${pfForm.value.find((item) => item.key === 'sport').value};
290
- 口味偏好及饮食禁忌:${
291
- pfForm.value.find((item) => item.key === 'taste').value
292
- ? pfForm.value.find((item) => item.key === 'taste').value
293
- : '没有饮食禁忌'
294
- };`;
295
- console.log(msg);
296
- Emits('submit', [{ content: msg, text: msg }]);
297
- };
298
-
299
- const selectTag = (item, type) => {
300
- if (dialogInfo.value[type].includes(item)) {
301
- dialogInfo.value[type] = dialogInfo.value[type].filter((i) => i !== item);
302
- } else {
303
- dialogInfo.value[type].push(item);
304
- }
305
- };
306
-
307
- const selectSport = (item) => {
308
- dialogInfo.value.sport = item.name;
309
- handleConfirm();
310
- };
311
-
312
- const selectSex = (item) => {
313
- dialogInfo.value.sex = item;
314
- handleConfirm();
315
- };
316
- </script>
317
-
318
- <template>
319
- <div class="pf_wrap">
320
- <div class="pf_form">
321
- <div v-for="item in pfForm" :key="item.key" class="pf_row">
322
- <div class="title" :class="{ is_required: item.required }">
323
- {{ item.label }}
324
- </div>
325
- <div class="content" @click="handleSelect(item)">
326
- <span
327
- class="text_row"
328
- :style="{ color: item.value ? '#000' : '#75759d' }"
329
- >{{
330
- item.value ? `${item.value} ${item.unit || ''}` : item.placeholder
331
- }}</span
332
- >
333
- <arrow-right class="arrow" />
334
- </div>
335
- </div>
336
- </div>
337
- <div
338
- class="pf_btn"
339
- :class="{ disabled: !isValid }"
340
- @click.stop="handleSubmit"
341
- >
342
- 按身体数据领取食谱
343
- </div>
344
- </div>
345
-
346
- <popup
347
- v-model:show="showPopup"
348
- :title="dialogInfo.title"
349
- :height="dialogInfo.dialogHeight"
350
- @confirm="handleConfirm"
351
- >
352
- <template #default>
353
- <div v-if="dialogInfo.key === 'sex'" class="sex_wrap">
354
- <div
355
- :class="{ sex: true, selected: dialogInfo.sex === '男' }"
356
- @click.stop="selectSex('男')"
357
- >
358
-
359
- </div>
360
- <div
361
- :class="{ sex: true, selected: dialogInfo.sex === '女' }"
362
- @click.stop="selectSex('女')"
363
- >
364
-
365
- </div>
366
- </div>
367
- <div
368
- v-if="['age', 'height', 'weight'].includes(dialogInfo.key)"
369
- class="input_wrap"
370
- >
371
- <Field
372
- v-model="dialogInfo[dialogInfo.key]"
373
- class="input"
374
- :type="dialogInfo.type"
375
- :min="dialogInfo.min"
376
- :max="dialogInfo.max"
377
- @keyup.enter="handleConfirm"
378
- placeholder="请输入"
379
- />
380
- <div class="unit">{{ dialogInfo.unit }}</div>
381
- </div>
382
- <div v-if="dialogInfo.key === 'sport'" class="sport_wrap">
383
- <div
384
- v-for="item in sportList"
385
- :key="item.key"
386
- :class="{ row: true, selected: dialogInfo.sport === item.name }"
387
- @click.stop="selectSport(item)"
388
- >
389
- <div class="name">{{ item.name }}</div>
390
- <div class="sub">{{ item.sub }}</div>
391
- </div>
392
- </div>
393
- <div v-if="dialogInfo.key === 'taste'" class="taste_wrap">
394
- <div class="title">口味偏好</div>
395
- <div class="box">
396
- <div
397
- :class="{ tag: true, selected: dialogInfo.taste.includes(item) }"
398
- v-for="item in tasteList"
399
- :key="item"
400
- @click.stop="selectTag(item, 'taste')"
401
- >
402
- {{ item }}
403
- </div>
404
- </div>
405
- <div class="line"></div>
406
- <div class="title">饮食禁忌</div>
407
- <div class="box">
408
- <div
409
- :class="{ tag: true, selected: dialogInfo.taboo.includes(item) }"
410
- v-for="item in tabooList"
411
- :key="item"
412
- @click.stop="selectTag(item, 'taboo')"
413
- >
414
- {{ item }}
415
- </div>
416
- </div>
417
- </div>
418
- </template>
419
- </popup>
420
- </template>
421
-
422
- <style scoped lang="less">
423
- .pf {
424
- &_wrap {
425
- width: 100%;
426
- }
427
-
428
- &_form {
429
- padding: 0 15px;
430
- background: #fff;
431
- border-radius: 8px;
432
- }
433
-
434
- &_row {
435
- display: flex;
436
- gap: 6px;
437
- flex-direction: row;
438
- align-items: center;
439
- justify-content: space-between;
440
- border-bottom: 1px solid #dadada;
441
- height: 54px;
442
- line-height: 24px;
443
-
444
- &:last-child {
445
- border-bottom: none;
446
- }
447
-
448
- .title {
449
- font-size: 14px;
450
- font-weight: 600;
451
- position: relative;
452
- line-height: 24px;
453
-
454
- &.is_required {
455
- &::after {
456
- content: '*';
457
- color: #ff0000;
458
- font-size: 14px;
459
- line-height: 24px;
460
- position: absolute;
461
- right: -0.6em;
462
- }
463
- }
464
- }
465
-
466
- .content {
467
- display: flex;
468
- flex-direction: row;
469
- align-items: center;
470
- justify-content: flex-end;
471
- }
472
-
473
- .arrow {
474
- color: #000;
475
- font-size: 22px;
476
- }
477
- .text_row {
478
- display: inline-block;
479
- font-size: 14px;
480
- text-align: right;
481
- width: 156px;
482
- text-overflow: ellipsis;
483
- white-space: nowrap;
484
- overflow: hidden;
485
- }
486
- .input {
487
- font-size: 14px;
488
- text-align: right;
489
- outline: none;
490
- border: none;
491
- }
492
- }
493
-
494
- &_btn {
495
- cursor: pointer;
496
- height: 40px;
497
- line-height: 40px;
498
- border-radius: 20px;
499
- text-align: center;
500
- font-size: 14px;
501
- font-weight: 600;
502
- color: #000;
503
- background: #00dc4e;
504
- margin-top: 15px;
505
-
506
- &.disabled {
507
- color: #fff;
508
- background: #d9d9d9;
509
- }
510
- }
511
- }
512
- .sex {
513
- &_wrap {
514
- padding: 50px 0;
515
- .sex {
516
- transition: 100ms ease-in-out;
517
- font-size: 15px;
518
- font-weight: 400;
519
- text-align: center;
520
- height: 58px;
521
- line-height: 58px;
522
- border-top: 1px solid #fff;
523
- border-bottom: 1px solid #fff;
524
- &.selected {
525
- font-size: 20px;
526
- font-weight: 600;
527
- color: #039938;
528
- border-color: #d9d9d9;
529
- }
530
- }
531
- }
532
- }
533
- .input {
534
- &_wrap {
535
- text-align: center;
536
- padding: 20px 0;
537
-
538
- .input {
539
- height: 64px;
540
- line-height: 64px;
541
- font-size: 36px;
542
- text-align: center;
543
- width: 200px;
544
- outline: none;
545
- border: none;
546
- margin: auto;
547
- /deep/ .van-field__control {
548
- text-align: center;
549
- }
550
- }
551
- .unit {
552
- font-size: 15px;
553
- font-weight: 400;
554
- line-height: 22px;
555
- }
556
- }
557
- }
558
- .sport {
559
- &_wrap {
560
- padding: 20px 0;
561
-
562
- .row {
563
- transition: 100ms ease-in-out;
564
- height: 58px;
565
- border-top: 1px solid #fff;
566
- border-bottom: 1px solid #fff;
567
- .name {
568
- font-size: 15px;
569
- font-weight: 400;
570
- text-align: center;
571
- line-height: 28px;
572
- }
573
- .sub {
574
- font-size: 13px;
575
- font-weight: 400;
576
- text-align: center;
577
- line-height: 18px;
578
- }
579
-
580
- &.selected {
581
- .name {
582
- color: #039938;
583
- font-size: 16px;
584
- font-weight: 600;
585
- text-align: center;
586
- line-height: 32px;
587
- }
588
- .sub {
589
- color: #039938;
590
- font-size: 12px;
591
- font-weight: 400;
592
- text-align: center;
593
- line-height: 16px;
594
- }
595
- color: #039938;
596
- border-color: #d9d9d9;
597
- }
598
- }
599
- }
600
- }
601
- .taste {
602
- &_wrap {
603
- padding: 20px;
604
- .title {
605
- font-size: 15px;
606
- font-weight: 600;
607
- line-height: 32px;
608
- margin-bottom: 16px;
609
- }
610
- .box {
611
- display: inline-flex;
612
- flex-wrap: wrap;
613
- gap: 10px;
614
- }
615
- .line {
616
- border-top: 1px solid #e9e9e9;
617
- margin: 25px 0;
618
- }
619
- .tag {
620
- height: 32px;
621
- line-height: 32px;
622
- padding: 0 15px;
623
- background-color: #f3f4f5;
624
- border-radius: 16px;
625
- font-size: 14px;
626
- text-align: center;
627
- &.selected {
628
- color: #fff;
629
- background-color: #000;
630
- }
631
- }
632
- }
633
- }
634
- </style>