ai-assistant-pro 0.0.7 → 0.0.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.
@@ -3,7 +3,9 @@ import { fetchEventSource } from '@microsoft/fetch-event-source';
3
3
  import constants from '../utils/constants';
4
4
 
5
5
  const baseURL = sessionStorage.getItem('AI-INTELLIGENT-TOOLS_BASE_URL') || constants.publicPath;
6
- const prefix = sessionStorage.getItem('AI-INTELLIGENT-TOOLS_PRE_FIX') || constants.publicPrefix;
6
+ let prefix = sessionStorage.getItem('AI-INTELLIGENT-TOOLS_PRE_FIX') || constants.publicPrefix;
7
+ // 0.0.8 版本接口升级
8
+ prefix += '/plugin/v2';
7
9
  import cache from '../plugins/cache';
8
10
  export const ssoAuth = (token) => {
9
11
  return request({
@@ -92,15 +94,37 @@ export const checkCourseIdIsExist = (resId) => {
92
94
  method: 'get',
93
95
  });
94
96
  }
97
+ /**
98
+ * 开场白及提示词查询
99
+ * */
100
+ export const queryCallWord = (resId) => {
101
+ return request({
102
+ url: prefix + `/ia/byCourseId?courseId=${resId}`,
103
+ method: 'get',
104
+ });
105
+ }
106
+
107
+ /**
108
+ * 自动追问
109
+ * @param iaId 请求参数id
110
+ * @param message 对话对
111
+ * @returns 返回节点详情数据
112
+ */
113
+ export async function getAutoQuestioning(iaId, message) {
114
+ return request.post(`${prefix}/ia/autoFollowUp`, {
115
+ iaId,
116
+ messages: message,
117
+ });
118
+ }
95
119
 
96
120
  export async function sendMessageEventSource(params, signal, onmessage) {
97
- return fetchEventSource(`${baseURL}${prefix}/assistant/conversation`, {
121
+ return fetchEventSource(`${baseURL}${prefix}/assistant/conversation?token=${cache.session.getJSON('SRKJ_TOKEN_CACHE')}`, {
98
122
  method: 'POST',
99
123
  signal: signal,
100
124
  openWhenHidden: true,
101
125
  headers: {
102
126
  'Content-Type': 'application/json',
103
- 'X-Id-Token': cache.session.getJSON('SRKJ_TOKEN_CACHE'),
127
+ // 'X-Id-Token': cache.session.getJSON('SRKJ_TOKEN_CACHE'),
104
128
  },
105
129
  body: JSON.stringify(params),
106
130
  onmessage,
@@ -2,7 +2,7 @@
2
2
  <div class="robot-tools">
3
3
  <div class="robot-reanswer"
4
4
  style="margin-bottom: 8px"
5
- v-if="listData.stop || listData.finish && !sending"
5
+ v-if="(listData.stop || listData.finish && !sending) && isLast"
6
6
  @click="reAnswer(listData)">
7
7
  <i class="el-icon-refresh-right"></i>
8
8
  重新回答
@@ -77,7 +77,19 @@ export default {
77
77
  sending: {
78
78
  type: Boolean,
79
79
  default: false
80
- }
80
+ },
81
+ resId: {
82
+ type: String,
83
+ default: '',
84
+ },
85
+ openCourseId: {
86
+ type: String,
87
+ default: ''
88
+ },
89
+ isLast: {
90
+ type: Boolean,
91
+ default: false
92
+ },
81
93
  },
82
94
  data() {
83
95
  return {
@@ -120,6 +132,8 @@ export default {
120
132
  chatId: this.chatId,
121
133
  msgId: list.msgId,
122
134
  parentMsgId: list.parentMsgId,
135
+ courseId: this.resId,
136
+ openCourseId: this.openCourseId ,
123
137
  });
124
138
  this.$message.success('已发送给老师')
125
139
  }).catch(() => {});
@@ -167,6 +181,7 @@ export default {
167
181
  .robot-tools {
168
182
  position: relative;
169
183
  margin-top: 8px;
184
+ min-height: 32px;
170
185
  .robot-reanswer {
171
186
  width: 104px;
172
187
  height: 32px;
@@ -11,21 +11,50 @@
11
11
  <div :class="{'user-info': list.type === 'user'}" class="robot-message">
12
12
  <div v-html="list.message"></div>
13
13
  <div v-if="list.type === 'robot' && list.links.length > 0" class="link">
14
+ <div v-if="!list.allIdWithStart">
15
+ <div class="link-title">参考文件</div>
16
+ <div class="link-content">
17
+ <template v-for="item in list.links" >
18
+ <div class="links" v-if="!item.title.startsWith(chatMajorId)">
19
+ <a :href="'https://ai-yuliao.hep.com.cn'+item.documentUrl" target="_blank">
20
+ <span>{{ item.title }}</span>
21
+ </a>
22
+ </div>
23
+ </template>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ <div v-if="list.type === 'robot' && list.connectUrl.length > 0" class="link">
14
28
  <div class="link-title">相关链接</div>
15
29
  <div class="link-content">
16
- <template v-for="item in list.links" >
17
- <div class="links" v-if="!item.title.startsWith(chatMajorId)">
18
- <a :href="'https://ai-yuliao.hep.com.cn'+item.documentUrl" target="_blank">
19
- <span>{{ item.title }}</span>
30
+ <template v-for="item in list.connectUrl">
31
+ <div class="links">
32
+ <a :href="item.iaUrl" target="_blank">
33
+ <span>{{ item.iaUrlName }}</span>
20
34
  </a>
21
35
  </div>
22
36
  </template>
23
37
  </div>
24
38
  </div>
39
+ <div v-if="list.type === 'robot' && finish && list.followUps && list.followUps.length > 0">
40
+ <div class="link-title">智能追问</div>
41
+ <div class="link-content">
42
+ <div class="hot-list"
43
+ v-for="(list, index) in list.followUps"
44
+ :key="index"
45
+ @click="selectModule(list)">
46
+ {{ list }}
47
+ <i class="el-icon-arrow-right go-icon"></i>
48
+ </div>
49
+ </div>
50
+ </div>
25
51
  <chat-tools v-if="list.type === 'robot'"
26
52
  :chatId="chatId"
27
53
  :detail-data="list"
28
54
  :sending="list.sending"
55
+ :resId="resId"
56
+ :open-course-id="openCourseId"
57
+ :is-last="index === messageData.length - 1"
29
58
  @on-reanswer="(list) => reanswer(list, index)"
30
59
  @on-stop-chat="onStopChat"/>
31
60
  </div>
@@ -35,7 +64,8 @@
35
64
  <script>
36
65
  import { errorList, cacheMessageList } from '../utils/config';
37
66
  import ChatTools from './chat-tools.vue';
38
- import { sendMessageEventSource } from "../api";
67
+ import { sendMessageEventSource, getAutoQuestioning } from "../api";
68
+ import { marked } from 'marked';
39
69
  const controller = new AbortController();
40
70
  const signal = controller.signal;
41
71
 
@@ -53,6 +83,10 @@ export default {
53
83
  type: String,
54
84
  default: '',
55
85
  },
86
+ openCourseId: {
87
+ type: String,
88
+ default: ''
89
+ },
56
90
  chatId: {
57
91
  type: String,
58
92
  default: '',
@@ -72,6 +106,7 @@ export default {
72
106
  input: "",
73
107
  errors: [],
74
108
  errorList: errorList,
109
+ finish: false,
75
110
  cacheKeyWord: '' // 由于外部需要快速清掉 keyword 但是存在重新发送请求的情况,因此需要一个混存记录
76
111
  }
77
112
  },
@@ -103,6 +138,7 @@ export default {
103
138
  },
104
139
  async postMessage(list, commonKey, parentMsgId) {
105
140
  let reanswerParams = {};
141
+ this.finish = false;
106
142
  if (list) {
107
143
  list.sending = true;
108
144
  reanswerParams = {
@@ -112,6 +148,8 @@ export default {
112
148
  content: this.messageData[list.index - 1].message,
113
149
  }
114
150
  this.messageData[list.index].message = '';
151
+ this.messageData[list.index].cacheMessage = '';
152
+ this.makeAutoMessage();
115
153
  }
116
154
  const params = {
117
155
  messageList: [
@@ -127,29 +165,47 @@ export default {
127
165
  };
128
166
  // list 存在说明是重新生成
129
167
  if (!list && !commonKey) {
130
- this.messageData.push({ type: 'user', message: this.keyWord.replace(/\n/g, '<br>') });
131
- setTimeout(() => this.messageData.push(
132
- {
133
- type: 'robot',
134
- message: '',
135
- zan: false,
136
- cai: false,
137
- stop: false,
138
- finish: false,
139
- sending: true,
140
- links: [],
141
- reAnswerCount: 0
142
- }
143
- ));
168
+ const userWord = this.keyWord || this.cacheKeyWord;
169
+ this.messageData.push({ type: 'user', message: userWord.replace(/\n/g, '<br>') });
170
+ setTimeout(() => {
171
+ this.messageData.push(
172
+ {
173
+ type: 'robot',
174
+ message: '',
175
+ cacheMessage: '',
176
+ zan: false,
177
+ cai: false,
178
+ stop: false,
179
+ finish: false,
180
+ sending: true,
181
+ links: [],
182
+ connectUrl: [],
183
+ reAnswerCount: 0
184
+ }
185
+ )
186
+ this.makeAutoMessage();
187
+ });
144
188
  }
145
189
  await sendMessageEventSource(params, signal, res => {
146
190
  this.makeMessageLine(res, list);
147
191
  });
148
192
  },
193
+ makeAutoMessage() {
194
+ const cacheMessage = [];
195
+ for (let i = 0; i < this.messageData.length; i++) {
196
+ const current = this.messageData[i];
197
+ cacheMessage.push({
198
+ role: current.type === 'robot' ? 'assistant' : 'user',
199
+ content: current.message || '正在思考中。',
200
+ });
201
+ }
202
+ this.makeAutoQuestioning(cacheMessage);
203
+ },
149
204
  makeMessageLine(res, list) {
150
- const { content, status, chatId, msgId, parentMsgId, reference, commonKey } = JSON.parse(res.data);
205
+ const { content, status, chatId, msgId, parentMsgId, reference, commonKey, connectUrl } = JSON.parse(res.data);
151
206
  let index = list ? list.index : this.messageData.length - 1;
152
207
  const currentList = this.messageData[index];
208
+ let allIdWithStart = true;
153
209
  // 结束标识
154
210
  if (status === 2 || status === 1) {
155
211
  if (commonKey) {
@@ -160,12 +216,23 @@ export default {
160
216
  currentList.finish = true;
161
217
  if (reference) {
162
218
  currentList.links = JSON.parse(reference);
219
+ currentList.links.map((item) => {
220
+ if (!item.title.startsWith(this.chatMajorId)) {
221
+ allIdWithStart = false;
222
+ }
223
+ });
224
+ }
225
+ if (connectUrl) {
226
+ currentList.connectUrl = JSON.parse(connectUrl);
163
227
  }
228
+ currentList.allIdWithStart = allIdWithStart;
164
229
  this.cacheKeyWord = '';
230
+ this.finish = true;
165
231
  this.$emit('on-message-finish', chatId);
166
232
  return;
167
233
  }
168
- currentList.message += content.replace(/\n/g, '<br>');
234
+ currentList.cacheMessage += content;
235
+ currentList.message = marked.parse(currentList.cacheMessage);
169
236
  currentList.msgId = msgId;
170
237
  currentList.parentMsgId = parentMsgId;
171
238
  currentList.chatId = chatId;
@@ -175,14 +242,31 @@ export default {
175
242
  // 防止出现调用基础模型前导致停止回答id错误
176
243
  setTimeout(() => currentList.sending = false,500);
177
244
  },
245
+ async makeAutoQuestioning (messages) {
246
+ // 首次不触发
247
+ if (messages.length <= 2) return;
248
+ const autoRes = await getAutoQuestioning(this.chatMajorId, messages);
249
+ const {
250
+ message: {
251
+ content: { followUps },
252
+ },
253
+ } = autoRes;
254
+ this.messageData[this.messageData.length - 1].followUps =
255
+ followUps.length > 3 ? followUps.splice(0, 3) : followUps;
256
+ },
178
257
  onStopChat(list){
179
258
  this.$emit('on-message-finish', list.chatId)
180
259
  },
260
+ selectModule(message) {
261
+ this.cacheKeyWord = message;
262
+ this.postMessage();
263
+ },
181
264
  reanswer(list, index) {
182
265
  list.index = index;
183
266
  list.stop = false;
184
267
  list.finish = false;
185
268
  list.links = [];
269
+ list.connectUrl = [];
186
270
  this.postMessage(list);
187
271
  this.$emit('on-reanser');
188
272
  }
@@ -264,6 +348,13 @@ export default {
264
348
  line-height: 24px;
265
349
  flex: 1;
266
350
  }
351
+ :deep {
352
+ .robot-message {
353
+ p {
354
+ margin: 0;
355
+ }
356
+ }
357
+ }
267
358
 
268
359
  .user-info {
269
360
  width: auto;
@@ -277,13 +368,6 @@ export default {
277
368
  width: 100%;
278
369
  margin-bottom: 16px;
279
370
 
280
- .link-title {
281
- color: #878aab;
282
- font-size: 14px;
283
- margin: 8px 0;
284
- text-align: left;
285
- }
286
-
287
371
  .link-content {
288
372
  background: #fafafd;
289
373
  border-radius: 8px;
@@ -313,10 +397,27 @@ export default {
313
397
  }
314
398
  }
315
399
  }
400
+ .link-title {
401
+ color: #878aab;
402
+ font-size: 14px;
403
+ margin: 8px 0;
404
+ text-align: left;
405
+ }
316
406
  .robot-image-div {
317
407
  width: 48px;
318
408
  height: 48px;
319
409
  background: url("../static/robot.png");
320
410
  background-size: 100%;
321
411
  }
412
+ .hot-list {
413
+ background-color: rgba(255, 255, 255, 1);
414
+ border-radius: 8px;
415
+ font-size: 16px;
416
+ padding: 10px 24px 10px 16px;
417
+ margin-top: 8px;
418
+ cursor: pointer;
419
+ &:hover {
420
+ background-color: rgba(96, 96, 224, 0.24);
421
+ }
422
+ }
322
423
  </style>
@@ -5,41 +5,64 @@
5
5
  <div class="robot-image-div"></div>
6
6
  </div>
7
7
  <div class="robot-message">
8
- <p>Hi,我是学习助手。</p>
9
- <p>在这里你可以获得专业、准确的课程讲解,包括对公式的深入理解和细腻的解答。</p>
10
- <!-- <div class="hot-list" v-for="list in aiMessage" :key="list.id" @click="selectModule(list)">-->
11
- <!-- {{ list.value }}-->
12
- <!-- <i class="el-icon-arrow-right go-icon"></i>-->
13
- <!-- </div>-->
8
+ <template v-if="prologue">
9
+ {{prologue}}
10
+ </template>
11
+ <template v-else>
12
+ <p>Hi,我是学习助手。</p>
13
+ <p>在这里你可以获得专业、准确的课程讲解,包括对公式的深入理解和细腻的解答。</p>
14
+ </template>
15
+ <div class="hot-list" v-for="(list, index) in aiMessage" :key="index" @click="selectModule(list)">
16
+ {{ list }}
17
+ <i class="el-icon-arrow-right go-icon"></i>
18
+ </div>
14
19
  </div>
15
20
  </div>
16
21
  </template>
17
22
  <script>
18
23
 
24
+ import { queryCallWord } from "../api";
25
+
19
26
  export default {
20
27
  name: 'HotSearch',
28
+ props: {
29
+ resId: {
30
+ type: String,
31
+ default: '',
32
+ },
33
+ },
21
34
  data() {
22
35
  return {
23
36
  aiMessage: [
24
- {
25
- value: '请解释一下牛顿第二定律的公式和物理意义。',
26
- id: 1,
27
- },
28
- {
29
- value: '电磁感应定律是如何描述的?请给出相关公式并解释。',
30
- id: 2,
31
- },
32
- {
33
- value: '在光学中,光的干涉现象是如何产生的?能否用公式来表示?',
34
- id: 3,
35
- }
37
+ // {
38
+ // value: '请解释一下牛顿第二定律的公式和物理意义。',
39
+ // id: 1,
40
+ // },
41
+ // {
42
+ // value: '电磁感应定律是如何描述的?请给出相关公式并解释。',
43
+ // id: 2,
44
+ // },
45
+ // {
46
+ // value: '在光学中,光的干涉现象是如何产生的?能否用公式来表示?',
47
+ // id: 3,
48
+ // }
36
49
  ],
50
+ prologue: ' ',
37
51
  }
38
52
  },
39
53
  methods: {
40
54
  selectModule (list) {
41
55
  this.$emit('select-module', list);
42
56
  }
57
+ },
58
+ async mounted () {
59
+ const wordRes = await queryCallWord(this.resId);
60
+ if (!wordRes) return;
61
+ const { guideExample, prologue } = wordRes;
62
+ if (guideExample && guideExample.length > 0) {
63
+ this.aiMessage = JSON.parse(guideExample);
64
+ }
65
+ this.prologue = prologue;
43
66
  }
44
67
  }
45
68
  </script>
@@ -12,10 +12,11 @@
12
12
  </div>
13
13
  <template v-if="courseFlag">
14
14
  <div class="ai-main-content">
15
- <hot-search v-if="!chatShow" @select-module="selectModule"></hot-search>
15
+ <hot-search v-if="!chatShow" @select-module="selectModule" :resId="resId"></hot-search>
16
16
  <chat v-if="chatShow"
17
17
  ref="chatRef"
18
18
  :resId="resId"
19
+ :open-course-id="openCourseId"
19
20
  :chatId="chatId"
20
21
  :key-word="aiMessageKeyWord"
21
22
  :message-data="messageList"
@@ -52,6 +53,7 @@
52
53
  import HotSearch from './hot-search.vue';
53
54
  import Chat from './chat.vue';
54
55
  import Cookies from "js-cookie";
56
+ import { marked } from 'marked';
55
57
  import { getUserInfo } from '../utils/config';
56
58
  import { newChat, chartClear, getDetailList, countAccess,checkCourseIdIsExist } from '../api/index';
57
59
  export default {
@@ -65,6 +67,10 @@ export default {
65
67
  resId: {
66
68
  type: String,
67
69
  default: ''
70
+ },
71
+ openCourseId: {
72
+ type: String,
73
+ default: ''
68
74
  }
69
75
  },
70
76
  watch: {
@@ -110,8 +116,10 @@ export default {
110
116
  }
111
117
  this.$emit('close');
112
118
  },
113
- selectModule() {
119
+ selectModule(hotKey) {
114
120
  this.chatShow = true;
121
+ this.aiMessage = hotKey;
122
+ this.goChat({});
115
123
  },
116
124
  showHot() {
117
125
  this.chatShow = false;
@@ -122,20 +130,30 @@ export default {
122
130
  if (!listRes || listRes.length < 1) return;
123
131
  let currentList = listRes[0].contents.reverse();
124
132
  const { chatMajorId } = listRes[0];
125
- this.chatMajorId = chatMajorId.toString();
133
+ this.chatMajorId = chatMajorId && chatMajorId.toString();
126
134
  const cacheArray = [];
127
135
  currentList.map((list) => {
136
+ let allIdWithStart = true;
137
+ if (this.chatMajorId && list.references) {
138
+ list.references.map((item) => {
139
+ if (!item.title.startsWith(this.chatMajorId)) {
140
+ allIdWithStart = false;
141
+ }
142
+ });
143
+ }
128
144
  const obj = {
129
145
  type: list.role === 'assistant' ? 'robot' : 'user',
130
- message: list.content.replace(/\n/g, '<br>'),
146
+ message: list.role === 'assistant' ? marked.parse(list.content) : list.content.replace(/\n/g, '<br>'),
131
147
  zan: list.type === 1,
132
148
  cai: list.type === 2,
133
149
  stop: list.status === 1,
134
150
  finish: true,
135
151
  links: list.references || [],
152
+ connectUrl: list.connectUrls || [],
136
153
  reAnswerCount: 0,
137
154
  msgId: list.contentId,
138
155
  parentMsgId: list.parentMsgId,
156
+ allIdWithStart
139
157
  };
140
158
  cacheArray.push(obj);
141
159
  })
@@ -1,5 +1,5 @@
1
1
  import { ssoAuth, authUser } from '../api/index';
2
- import constants from '../utils/constants';
2
+ // import constants from '../utils/constants';
3
3
  import cache from '../plugins/cache';
4
4
 
5
5
  export const errorList = [
@@ -43,15 +43,20 @@ export const cacheMessageList = [
43
43
  }
44
44
  ]
45
45
 
46
+ // export const getUserInfo = async (token) => {
47
+ // const ssoRes = await ssoAuth(token);
48
+ // const userRes = await authUser({
49
+ // 'X-Auth-User': encodeURIComponent(ssoRes.name),
50
+ // 'X-Auth-Token': ssoRes.password,
51
+ // 'X-Enterprise-Id': `${constants['X-Enterprise-Id']}`,
52
+ // 'X-App-Id': `${constants['X-App-Id']}`,
53
+ // 'X-App-Secret': `${constants['X-App-Secret']}`,
54
+ // 'X-Auth-User-Type': '1',
55
+ // });
56
+ // cache.session.setJSON('SRKJ_TOKEN_CACHE', userRes);
57
+ // }
58
+
46
59
  export const getUserInfo = async (token) => {
47
- const ssoRes = await ssoAuth(token);
48
- const userRes = await authUser({
49
- 'X-Auth-User': encodeURIComponent(ssoRes.name),
50
- 'X-Auth-Token': ssoRes.password,
51
- 'X-Enterprise-Id': `${constants['X-Enterprise-Id']}`,
52
- 'X-App-Id': `${constants['X-App-Id']}`,
53
- 'X-App-Secret': `${constants['X-App-Secret']}`,
54
- 'X-Auth-User-Type': '1',
55
- });
56
- cache.session.setJSON('SRKJ_TOKEN_CACHE', userRes);
60
+ await ssoAuth(token);
61
+ cache.session.setJSON('SRKJ_TOKEN_CACHE', token);
57
62
  }
@@ -16,8 +16,10 @@ const service = axios.create({
16
16
 
17
17
  service.interceptors.request.use(config => {
18
18
  if (cache.session.getJSON('SRKJ_TOKEN_CACHE')) {
19
- config.headers["X-Id-Token"] = cache.session.getJSON('SRKJ_TOKEN_CACHE');
20
- }
19
+ // config.headers["X-Id-Token"] = cache.session.getJSON('SRKJ_TOKEN_CACHE');
20
+ if (!config.params) config.params = {};
21
+ config.params.token = cache.session.getJSON('SRKJ_TOKEN_CACHE');
22
+ }
21
23
  // 是否需要防止数据重复提交
22
24
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
23
25
  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
@@ -51,12 +53,12 @@ service.interceptors.response.use(res => {
51
53
  return res.data
52
54
  }
53
55
  let srkjData = res.data;
54
- if (srkjData) {
55
- const respData = decrypt(srkjData);
56
- try {
57
- srkjData = JSON.parse(respData);
58
- } catch (e) {}
59
- }
56
+ // if (srkjData) {
57
+ // const respData = decrypt(srkjData);
58
+ // try {
59
+ // srkjData = JSON.parse(respData);
60
+ // } catch (e) {}
61
+ // }
60
62
  if (res.status === 401) {
61
63
  Message.warning(srkjData.message.description);
62
64
  return;