Browse Source

Merge branch 'maziyang/feature-20251025172218-智能客服中台' into milestone-20251031-简版功能开发

milestone-20251031-简版功能开发
maziyang 3 weeks ago
parent
commit
64dcfcd507
  1. 21
      api/customerServicePlatform/customerServicePlatform.js
  2. 122
      pages/customerServicePlatform/questionDetail.vue

21
api/customerServicePlatform/customerServicePlatform.js

@ -9,9 +9,24 @@ export const uploadImageApi = (data) => {
data
})
}
//问题回答
export const getAnswerApi = (data) => {
//问题回答最终内容
export const getAnswerContentApi = (data) => {
return http({
method: 'POST',
url: '/api/customer/getAnswer',
data
})
}
//问题回答轮询
export const getAnswerStatusApi = (data) => {
return http({
method: 'POST',
url: '/api/customer/getState',
data
})
}
//问题回答获取Id
export const getAnswerIdApi = (data) => {
return http({
method: 'POST',
url: '/api/customer/askQuestion',

122
pages/customerServicePlatform/questionDetail.vue

@ -14,7 +14,7 @@
</view>
</view>
<scroll-view scroll-y class="content-container">
<scroll-view scroll-y class="content-container" :scroll-into-view="scrollIntoView">
<view class="content-header">
<view class="content-header-area">
@ -47,7 +47,7 @@
<view class="card-text">
<rich-text :nodes="renderMarkdown(answerContent)"></rich-text>
<view id="answer-end" style="width:1px;height:1px;"></view>
<!-- <text class="card-paragraph">
{{answerContent}}
</text> -->
@ -66,7 +66,9 @@
<script>
import {
getAnswerApi
getAnswerIdApi,
getAnswerStatusApi,
getAnswerContentApi
} from "../../api/customerServicePlatform/customerServicePlatform";
import marked from "marked"; // marked
@ -78,12 +80,21 @@
questionTitle: '',
answerContent: '正在思考...',
showLoginRegister: false,
//
pollInterval: null,
pollTimeout: null,
scrollIntoView: ''
};
},
mounted() {
this.iSMT = uni.getSystemInfoSync().statusBarHeight || 0;
this.getAnswerContent()
},
onUnload() {
clearInterval(this.pollInterval);
clearTimeout(this.pollTimeout);
clearInterval(this.interval);
},
onLoad(options) {
if (options.question) {
this.questionTitle = decodeURIComponent(options.question);
@ -95,6 +106,18 @@
}
},
methods: {
scrollToBottom() {
// 使 $nextTick rich-text /DOM
this.$nextTick(() => {
// idscroll-view 使
this.scrollIntoView = 'answer-end';
// 便
setTimeout(() => {
this.scrollIntoView = '';
}, 100);
});
},
renderMarkdown(content) {
const renderer = new marked.Renderer();
// renderer.heading = function (text, level) {
@ -120,39 +143,102 @@
},
async getAnswerContent() {
let conversationId = '';
let chatId = '';
//
try {
const cache = uni.getStorageSync('conversationId');
const chatIdCache = uni.getStorageSync('chatId');
if (cache) conversationId = cache;
if (chatIdCache) chatId = chatIdCache
} catch (e) {
conversationId = '';
}
try {
const res = await getAnswerApi({
const res = await getAnswerIdApi({
question: this.questionTitle,
conversationId: conversationId,
chatId: chatId
})
console.log(res)
if (res.code == 200) {
uni.setStorageSync('conversationId', res.data.conversationId);
const answer = res.data.answer
//
let currentIndex = 0;
const answerLength = answer.length;
if (res.code == 200 && res.data.chatId) {
const resConversationId = res.data.conversationId;
const resChatId = res.data.chatId;
uni.setStorageSync('conversationId', resConversationId);
uni.setStorageSync('chatId', resChatId);
let pollCount = 0;
const maxPoll = 10;
this.pollInterval && clearInterval(this.pollInterval);
this.pollTimeout && clearTimeout(this.pollTimeout);
// === ===
const checkStatus = async () => {
pollCount++;
const pollRes = await getAnswerStatusApi({
conversationId: resConversationId,
chatId: resChatId
});
console.log("pollRes =>", pollRes);
const status = pollRes?.data;
//
if (status === "completed") {
clearInterval(this.pollInterval);
clearTimeout(this.pollTimeout);
//
const answerRes = await getAnswerContentApi({
conversationId: resConversationId,
chatId: resChatId
});
console.log("answerRes =>", answerRes);
const answer = answerRes?.data;
//
if (answer) {
//
let currentIndex = 0;
const answerLength = answer.length;
this.interval && clearInterval(this.interval);
this.interval = setInterval(() => {
this.answerContent = answer.slice(0, currentIndex);
currentIndex++;
this.scrollToBottom();
if (currentIndex > answerLength) {
clearInterval(this.interval);
this.scrollToBottom();
}
}, Math.floor(Math.random() * (150 - 30 + 1)) + 30);
} else {
this.answerContent = "获取回答失败,请重试";
}
return;
}
//10
if (pollCount >= maxPoll) {
clearInterval(this.pollInterval);
clearTimeout(this.pollTimeout);
this.answerContent = "获取回答失败,请重试";
return;
}
//
this.interval = setInterval(() => {
this.answerContent = answer.slice(0, currentIndex);
currentIndex++;
};
if (currentIndex > answerLength) {
clearInterval(this.interval);
}
}, Math.floor(Math.random() * (150 - 30 + 1)) + 30);
// 2
this.pollInterval = setInterval(checkStatus, 2000);
// 10s
this.pollTimeout = setTimeout(() => {
clearInterval(this.pollInterval);
this.answerContent = "获取回答失败,请重试";
}, 20000);
} else {
this.answerContent = '获取回答失败,请重试';
}
} catch {
this.pollInterval && clearInterval(this.pollInterval);
this.pollTimeout && clearTimeout(this.pollTimeout);
this.interval && clearInterval(this.interval);
this.answerContent = '获取回答失败,请重试';
}
},

Loading…
Cancel
Save