ai-assistant-pro 0.0.7 → 0.0.8

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,7 @@
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";
39
68
  const controller = new AbortController();
40
69
  const signal = controller.signal;
41
70
 
@@ -53,6 +82,10 @@ export default {
53
82
  type: String,
54
83
  default: '',
55
84
  },
85
+ openCourseId: {
86
+ type: String,
87
+ default: ''
88
+ },
56
89
  chatId: {
57
90
  type: String,
58
91
  default: '',
@@ -72,6 +105,7 @@ export default {
72
105
  input: "",
73
106
  errors: [],
74
107
  errorList: errorList,
108
+ finish: false,
75
109
  cacheKeyWord: '' // 由于外部需要快速清掉 keyword 但是存在重新发送请求的情况,因此需要一个混存记录
76
110
  }
77
111
  },
@@ -103,6 +137,7 @@ export default {
103
137
  },
104
138
  async postMessage(list, commonKey, parentMsgId) {
105
139
  let reanswerParams = {};
140
+ this.finish = false;
106
141
  if (list) {
107
142
  list.sending = true;
108
143
  reanswerParams = {
@@ -112,6 +147,7 @@ export default {
112
147
  content: this.messageData[list.index - 1].message,
113
148
  }
114
149
  this.messageData[list.index].message = '';
150
+ this.makeAutoMessage();
115
151
  }
116
152
  const params = {
117
153
  messageList: [
@@ -127,29 +163,46 @@ export default {
127
163
  };
128
164
  // list 存在说明是重新生成
129
165
  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
- ));
166
+ const userWord = this.keyWord || this.cacheKeyWord;
167
+ this.messageData.push({ type: 'user', message: userWord.replace(/\n/g, '<br>') });
168
+ setTimeout(() => {
169
+ this.messageData.push(
170
+ {
171
+ type: 'robot',
172
+ message: '',
173
+ zan: false,
174
+ cai: false,
175
+ stop: false,
176
+ finish: false,
177
+ sending: true,
178
+ links: [],
179
+ connectUrl: [],
180
+ reAnswerCount: 0
181
+ }
182
+ )
183
+ this.makeAutoMessage();
184
+ });
144
185
  }
145
186
  await sendMessageEventSource(params, signal, res => {
146
187
  this.makeMessageLine(res, list);
147
188
  });
148
189
  },
190
+ makeAutoMessage() {
191
+ const cacheMessage = [];
192
+ for (let i = 0; i < this.messageData.length; i++) {
193
+ const current = this.messageData[i];
194
+ cacheMessage.push({
195
+ role: current.type === 'robot' ? 'assistant' : 'user',
196
+ content: current.message || '正在思考中。',
197
+ });
198
+ }
199
+ this.makeAutoQuestioning(cacheMessage);
200
+ },
149
201
  makeMessageLine(res, list) {
150
- const { content, status, chatId, msgId, parentMsgId, reference, commonKey } = JSON.parse(res.data);
202
+ const { content, status, chatId, msgId, parentMsgId, reference, commonKey, connectUrl } = JSON.parse(res.data);
151
203
  let index = list ? list.index : this.messageData.length - 1;
152
204
  const currentList = this.messageData[index];
205
+ let allIdWithStart = true;
153
206
  // 结束标识
154
207
  if (status === 2 || status === 1) {
155
208
  if (commonKey) {
@@ -160,8 +213,18 @@ export default {
160
213
  currentList.finish = true;
161
214
  if (reference) {
162
215
  currentList.links = JSON.parse(reference);
216
+ currentList.links.map((item) => {
217
+ if (!item.title.startsWith(this.chatMajorId)) {
218
+ allIdWithStart = false;
219
+ }
220
+ });
221
+ }
222
+ if (connectUrl) {
223
+ currentList.connectUrl = JSON.parse(connectUrl);
163
224
  }
225
+ currentList.allIdWithStart = allIdWithStart;
164
226
  this.cacheKeyWord = '';
227
+ this.finish = true;
165
228
  this.$emit('on-message-finish', chatId);
166
229
  return;
167
230
  }
@@ -175,14 +238,31 @@ export default {
175
238
  // 防止出现调用基础模型前导致停止回答id错误
176
239
  setTimeout(() => currentList.sending = false,500);
177
240
  },
241
+ async makeAutoQuestioning (messages) {
242
+ // 首次不触发
243
+ if (messages.length <= 2) return;
244
+ const autoRes = await getAutoQuestioning(this.chatMajorId, messages);
245
+ const {
246
+ message: {
247
+ content: { followUps },
248
+ },
249
+ } = autoRes;
250
+ this.messageData[this.messageData.length - 1].followUps =
251
+ followUps.length > 3 ? followUps.splice(0, 3) : followUps;
252
+ },
178
253
  onStopChat(list){
179
254
  this.$emit('on-message-finish', list.chatId)
180
255
  },
256
+ selectModule(message) {
257
+ this.cacheKeyWord = message;
258
+ this.postMessage();
259
+ },
181
260
  reanswer(list, index) {
182
261
  list.index = index;
183
262
  list.stop = false;
184
263
  list.finish = false;
185
264
  list.links = [];
265
+ list.connectUrl = [];
186
266
  this.postMessage(list);
187
267
  this.$emit('on-reanser');
188
268
  }
@@ -277,13 +357,6 @@ export default {
277
357
  width: 100%;
278
358
  margin-bottom: 16px;
279
359
 
280
- .link-title {
281
- color: #878aab;
282
- font-size: 14px;
283
- margin: 8px 0;
284
- text-align: left;
285
- }
286
-
287
360
  .link-content {
288
361
  background: #fafafd;
289
362
  border-radius: 8px;
@@ -313,10 +386,27 @@ export default {
313
386
  }
314
387
  }
315
388
  }
389
+ .link-title {
390
+ color: #878aab;
391
+ font-size: 14px;
392
+ margin: 8px 0;
393
+ text-align: left;
394
+ }
316
395
  .robot-image-div {
317
396
  width: 48px;
318
397
  height: 48px;
319
398
  background: url("../static/robot.png");
320
399
  background-size: 100%;
321
400
  }
401
+ .hot-list {
402
+ background-color: rgba(255, 255, 255, 1);
403
+ border-radius: 8px;
404
+ font-size: 16px;
405
+ padding: 10px 24px 10px 16px;
406
+ margin-top: 8px;
407
+ cursor: pointer;
408
+ &:hover {
409
+ background-color: rgba(96, 96, 224, 0.24);
410
+ }
411
+ }
322
412
  </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"
@@ -65,6 +66,10 @@ export default {
65
66
  resId: {
66
67
  type: String,
67
68
  default: ''
69
+ },
70
+ openCourseId: {
71
+ type: String,
72
+ default: ''
68
73
  }
69
74
  },
70
75
  watch: {
@@ -110,8 +115,10 @@ export default {
110
115
  }
111
116
  this.$emit('close');
112
117
  },
113
- selectModule() {
118
+ selectModule(hotKey) {
114
119
  this.chatShow = true;
120
+ this.aiMessage = hotKey;
121
+ this.goChat({});
115
122
  },
116
123
  showHot() {
117
124
  this.chatShow = false;
@@ -122,9 +129,17 @@ export default {
122
129
  if (!listRes || listRes.length < 1) return;
123
130
  let currentList = listRes[0].contents.reverse();
124
131
  const { chatMajorId } = listRes[0];
125
- this.chatMajorId = chatMajorId.toString();
132
+ this.chatMajorId = chatMajorId && chatMajorId.toString();
126
133
  const cacheArray = [];
127
134
  currentList.map((list) => {
135
+ let allIdWithStart = true;
136
+ if (this.chatMajorId && list.references) {
137
+ list.references.map((item) => {
138
+ if (!item.title.startsWith(this.chatMajorId)) {
139
+ allIdWithStart = false;
140
+ }
141
+ });
142
+ }
128
143
  const obj = {
129
144
  type: list.role === 'assistant' ? 'robot' : 'user',
130
145
  message: list.content.replace(/\n/g, '<br>'),
@@ -133,9 +148,11 @@ export default {
133
148
  stop: list.status === 1,
134
149
  finish: true,
135
150
  links: list.references || [],
151
+ connectUrl: list.connectUrls || [],
136
152
  reAnswerCount: 0,
137
153
  msgId: list.contentId,
138
154
  parentMsgId: list.parentMsgId,
155
+ allIdWithStart
139
156
  };
140
157
  cacheArray.push(obj);
141
158
  })
@@ -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;