ai-chat-bot-interface 1.4.11 → 1.5.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-chat-bot-interface",
3
3
  "private": false,
4
- "version": "1.4.11",
4
+ "version": "1.5.1",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "description": "A AI chat bot interface. (private)",
@@ -17,6 +17,7 @@
17
17
  "bot"
18
18
  ],
19
19
  "dependencies": {
20
+ "markdown-it": "^14.1.0",
20
21
  "v-viewer": "^3.0.21",
21
22
  "vue": "^3.5.13"
22
23
  },
package/src/App.vue CHANGED
@@ -5,11 +5,13 @@ import ChatUi from './ChatUi.vue';
5
5
  <template>
6
6
  <div style="width: 100vw; height: 100vh">
7
7
  <chat-ui
8
- bot-id="7471093458661720104"
9
- token="pat_2yVcSFJUZB6c9Kdcv9iktIVFeGRuzyK3bAJY6GcqKrdGxTdjKMd1iDB09ipJ6YX8"
8
+ bot-id="7485656400967516197"
9
+ token="pat_gYSCaegGxJ7qZXl4fBkCc4KYhV1t7YPQ5PVwggWdZnFmSKtgSHs8SoebV4epdQvj"
10
10
  uid="262598"
11
11
  :def-msg="{ placeholder: '发消息...' }"
12
12
  :show-header="true"
13
+ :card-list="{dishes: false}"
14
+ content-tye="markdown"
13
15
  />
14
16
  </div>
15
17
  </template>
package/src/ChatUi.vue CHANGED
@@ -77,7 +77,8 @@
77
77
  </p>
78
78
  </template>
79
79
  <template v-if="conv.content">
80
- <assistant-replay :content="conv.content" />
80
+ <assistant-replay v-if="contentTye === 'text'" :content="conv.content" />
81
+ <markdown-viewer v-else-if="contentTye ==='markdown'" :content="conv.content" />
81
82
  <template v-if="!isAnswering">
82
83
  <div v-if="conv.extra.length">
83
84
  <template v-for="(comp, idx) in conv.extra" :key="idx">
@@ -89,7 +90,7 @@
89
90
  {{ comp.planParse }}
90
91
  </p>-->
91
92
  <dishes-list
92
- v-if="comp.showType === 'card'"
93
+ v-if="finalCardList.dishes && comp.showType === 'card'"
93
94
  :sku-list="comp.skuList"
94
95
  :is-mini="!showHeader"
95
96
  :def-msg="finalDefMsg"
@@ -97,13 +98,13 @@
97
98
  @select="(data) => handleCardTap(data, comp)"
98
99
  />
99
100
  <plan-card
100
- v-if="comp.showType === 'plan'"
101
+ v-if="finalCardList.plan && comp.showType === 'plan'"
101
102
  :info="comp"
102
103
  :def-msg="finalDefMsg"
103
104
  @select="handleCardTap({ type: 'match' }, comp)"
104
105
  />
105
106
  <store-list
106
- v-if="comp.showType === 'store'"
107
+ v-if="finalCardList.store && comp.showType === 'store'"
107
108
  :list="comp.storeList"
108
109
  @select="handleStoreSel"
109
110
  />
@@ -117,7 +118,7 @@
117
118
  </div>
118
119
  </template>
119
120
  </template>
120
- <loading-icon2 v-else/>
121
+ <loading-icon2 v-if="isAnswering"/>
121
122
  </div>
122
123
  </div>
123
124
  </div>
@@ -129,7 +130,7 @@
129
130
  <img class="avatar" :src="avatar" alt="avatar"/>
130
131
  </div>
131
132
  <div class="box">
132
- <p class="text" v-html="conv.content"></p>
133
+ <p class="text" v-html="conv.content" />
133
134
  <div v-if="conv.extra.length">
134
135
  <imge-list :list="conv.extra"/>
135
136
  </div>
@@ -173,6 +174,8 @@ import ThinkingIcon from './components/icons/ThinkingIcon.vue';
173
174
  import OkIcon from './components/icons/OkIcon.vue';
174
175
  import AssistantReplay from './components/assistantReplay/assistantReplay.vue';
175
176
  import StoreList from './components/StoreList/StoreList.vue';
177
+ import MarkdownViewer from "./components/MarkdownPlan/MarkdownViewer.vue";
178
+
176
179
 
177
180
  const chatOptions = computed(() => {
178
181
  return {
@@ -201,6 +204,11 @@ const msgObj = {
201
204
  thinkCompleted: '思考完成',
202
205
  useSolution: '用該方案配餐'
203
206
  };
207
+ const defCardList = {
208
+ store: true,
209
+ dishes: true,
210
+ plan: true,
211
+ }
204
212
 
205
213
  const props = defineProps({
206
214
  logo: {
@@ -248,6 +256,18 @@ const props = defineProps({
248
256
  type: Object,
249
257
  default: () => ({}),
250
258
  },
259
+ contentTye: {
260
+ type: String,
261
+ default: 'text'
262
+ },
263
+ cardList: {
264
+ type: Object,
265
+ default: () => ({
266
+ store: true,
267
+ dishes: true,
268
+ plan: true,
269
+ })
270
+ },
251
271
  storage: {
252
272
  type: String,
253
273
  default: 'sessionStorage'
@@ -262,6 +282,12 @@ const finalDefMsg = computed(() => {
262
282
  ...props.defMsg,
263
283
  };
264
284
  });
285
+ const finalCardList = computed(() => {
286
+ return {
287
+ ...defCardList,
288
+ ...props.cardList
289
+ }
290
+ })
265
291
 
266
292
  const endTarget = ref(null);
267
293
  const inputText = ref('');
@@ -399,7 +425,6 @@ const chatConv = async (data) => {
399
425
  }
400
426
  }
401
427
  });
402
-
403
428
  historyList.value.push(uObj);
404
429
  const res = await fetch(
405
430
  `https://api.coze.cn/v3/chat?conversation_id=${conversationId.value}`,
@@ -694,6 +719,8 @@ const scrollToEnd = () => {
694
719
  });
695
720
  };
696
721
 
722
+
723
+
697
724
  const handleTextNeedBtn = (str) => {
698
725
  const regExp = /#全日總熱量:(\d*?)kcal/g;
699
726
  return regExp.test(str);
@@ -0,0 +1,36 @@
1
+ <script setup>
2
+ import {computed, onMounted, ref} from "vue";
3
+ import MarkdownIt from "markdown-it";
4
+
5
+ const md = new MarkdownIt()
6
+ const props = defineProps({
7
+ content: {
8
+ type: String,
9
+ default: `
10
+ # 这是一个 Markdown 标题
11
+
12
+ 这是一段普通的 Markdown 文本。
13
+
14
+ - 列表项 1
15
+ - 列表项 2
16
+
17
+ **加粗文本**
18
+
19
+ [链接到百度](https://www.baidu.com)
20
+ `
21
+ }
22
+ })
23
+ const parsedHtml = computed(() => {
24
+ return md.render(props.content)
25
+ })
26
+
27
+
28
+ </script>
29
+
30
+ <template>
31
+ <div v-html="parsedHtml"></div>
32
+ </template>
33
+
34
+ <style scoped>
35
+
36
+ </style>
@@ -212,11 +212,13 @@ const sendMsg = () => {
212
212
  return;
213
213
  }
214
214
  const list = [{ content: textValue.value, text: textValue.value }];
215
+ console.log("====== u file list =======", uFileList.value);
215
216
  if (uFileList.value.length) {
216
217
  list.push({
217
218
  type: 'object_string',
218
219
  content: uFileList.value.map((file) => ({
219
- type: 'image',
220
+ type: handleMsgType(file.file_type),
221
+ name: file.file.name,
220
222
  file_id: file.data.id,
221
223
  file_url: file.file_url,
222
224
  })),
@@ -338,6 +340,20 @@ const handleFocus = () => {
338
340
  });
339
341
  });
340
342
  };
343
+ const handleMsgType = (file_type) => {
344
+ /* text:文本类型。
345
+ * file:文件类型。
346
+ * image:图片类型。
347
+ * audio:音频类型。
348
+ * */
349
+ if(file_type.includes('image')) {
350
+ return 'image'
351
+ }else if(file_type.includes('application')) {
352
+ return 'file'
353
+ }else if(file_type.includes('audio')) {
354
+ return 'audio'
355
+ }
356
+ }
341
357
  const handleBlur = () => {};
342
358
  </script>
343
359
 
@@ -5,7 +5,7 @@
5
5
  :key="info.file_id"
6
6
  class="img"
7
7
  width="100%"
8
- :src="info.file_url"
8
+ :src="caseExtra(info)"
9
9
  :alt="info.name"
10
10
  @click.stop="previewImg"
11
11
  />
@@ -22,12 +22,25 @@ const props = defineProps({
22
22
  required: true,
23
23
  },
24
24
  });
25
+ const pdfIcon = 'https://prodstatic.weis1606.cn/api/smartFood/icon/pdf_icon.png';
25
26
 
26
27
  const previewImg = () => {
27
- viewerApi({
28
- images: props.list.map((item) => item.file_url),
29
- });
28
+ const imgList = props.list.filter((item) => item.type === 'image' && item.file_url);
29
+ if(imgList.length) {
30
+ viewerApi({
31
+ images: imgList.map(item => item.file_url),
32
+ });
33
+ }
30
34
  };
35
+ const caseExtra = ({type, name, file_url}) => {
36
+ console.log(props.list);
37
+ let url = file_url;
38
+ if(type === 'file' && name.toLowerCase().endsWith('pdf')) {
39
+ url = pdfIcon;
40
+ }
41
+ return url;
42
+ }
43
+
31
44
  </script>
32
45
 
33
46
  <style scoped lang="less">