Ver código fonte

refactor(AI chat): AI修改为内嵌网页

wangpx 10 meses atrás
pai
commit
a9b34d04b0
2 arquivos alterados com 21 adições e 361 exclusões
  1. 14 0
      api/AI.js
  2. 7 361
      pages/message/chat/index.vue

+ 14 - 0
api/AI.js

@@ -1,6 +1,20 @@
 import request from '@/utils/request.js'
 const preUrl = '/clientServices.do?iscrypt=1'
 
+export function getToken(userId) {
+	return request({
+		url: preUrl,
+		timeout: 100000, //请求超时 延长为100s
+		method: 'post',
+		data: {
+			serviceId: 'miniapp_ai_getToken',
+			params: {
+				userId: userId,
+			}
+		}
+	})
+}
+ 
 export function sendMessageToAI(message) {
 	return request({
 		url: preUrl,

+ 7 - 361
pages/message/chat/index.vue

@@ -1,78 +1,7 @@
 <template>
 	<page-meta root-font-size="system" />
 	<view class="container">
-		<scroll-view class="chat-messages" scroll-y="true" :scroll-with-animation="true"
-			:scroll-into-view="scrollToView"
-			:style="{ width: $scrollViewWidth + 'px', padding: $viewPadding + 'px', maxHeight: $viewMaxHeight + 'px' }">
-			<!-- 循环渲染消息 -->
-			<view v-for="(message, index) in messages" :key="index" :id="'msg' + index" style="clear: both;">
-				<view :class="['message', message.sender === 'user' ? 'user-message' : 'ai-message']">
-					<text :user-select="true" :selectable="true">{{ message.content }}</text>
-				</view>
-			</view>
-			<!-- 加载中 -->
-			<view style="clear: both;" v-if="loadingButton">
-				<view class="message ai-message">
-					<button :loading="true" class="loading_button" type="default"></button>
-				</view>
-			</view>
-		</scroll-view>
-		<view class="chat-input">
-			<textarea @linechange="chatMsgMaxHeightChange" auto-height v-model="inputMessage" placeholder="输入消息..."
-				class="input-field" />
-			<button class="send-button" :disabled="!buttonState" @click="sendMessage">发送</button>
-		</view>
-	</view>
-	<view class="fab_button">
-		<view class="history_button">
-			<uni-fab :pattern="{ icon: 'list' }" :popMenu="false" horizontal="right" vertical="bottom"
-				@fabClick="showHistorySession()"></uni-fab>
-		</view>
-	</view>
-	<view class="drawer_container">
-		<uni-drawer ref="showLeftDrawer" :width="220">
-			<view>
-				<scroll-view scroll-y="true" :style="{height: '100vh'}">
-					<view class="list_container">
-						<uni-list>
-							<uni-list-item title="新建会话" :clickable="true" @click="createSession()">
-								<template v-slot:footer>
-									<uni-icons type="plus-filled" size="24"></uni-icons>
-								</template>
-							</uni-list-item>
-							<view v-for="(session,index) in sessionList" :key="index">
-								<uni-list-item :title="session.sessionName" :clickable="true"
-									@click="changeSession(session.sessionId)" :ellipsis="2">
-									<template v-slot:footer>
-										<uni-icons type="compose" size="24"
-											@click.stop.prevent="toEditSession(session)"></uni-icons>
-									</template>
-								</uni-list-item>
-							</view>
-						</uni-list>
-					</view>
-				</scroll-view>
-			</view>
-		</uni-drawer>
-	</view>
-	<view class="edit_popup">
-		<uni-popup ref="editPopup" type="center" :mask-click="true">
-			<view class="edit_session_container">
-				<uni-card title="编辑会话信息">
-					<uni-forms ref="editForm" :modelValue="editSession" :rules="rules">
-						<uni-forms-item label="会话名" name="sessionName">
-							<uni-easyinput type="textarea" v-model="editSession.sessionName" placeholder="请输入会话名" />
-						</uni-forms-item>
-						<uni-forms-item>
-							<button type="primary" :disabled="!editButtonState" @click="submitEditSession()">确认</button>
-						</uni-forms-item>
-						<uni-forms-item>
-							<button type="warn" :disabled="!editButtonState" @click="deleteSession()">删除</button>
-						</uni-forms-item>
-					</uni-forms>
-				</uni-card>
-			</view>
-		</uni-popup>
+		<web-view :src="'https://api.ygtxfj.com:3443/auth?token=' + token"></web-view>
 	</view>
 </template>
 
@@ -83,181 +12,16 @@ import {
 	onMounted,
 	reactive
 } from 'vue';
-import $modal from '@/plugins/modal.js'
 import { useUserStore } from '@/store/user.js'
-import { sendMessageToAI, getSessionList, getMessageList, setSessionName, delSession } from '@/api/AI.js'
-
+import { getToken } from '@/api/AI.js'
+const token = ref('')
+const userStore = useUserStore()
 onMounted(() => {
 	// 在组件挂载后获取窗口高度
-	const res = uni.getWindowInfo();
-	// 计算滚动视图宽度
-	$scrollViewWidth.value = res.windowWidth - $viewPadding.value * 2;
-	$windowHeight.value = res.windowHeight;
-	$viewMaxHeight.value = res.windowHeight - 100;
-	initHistorySession()
-});
-// 弹出会话列表侧边栏
-const showLeftDrawer = ref(null)
-function showHistorySession() {
-	showLeftDrawer.value.open()
-}
-// 初始化会话列表
-const userStore = useUserStore()
-const sessionList = reactive([])
-function initHistorySession() {
-	sessionList.length = 0
-	getSessionList(userStore.user.useId).then(({ returnParams }) => {
-		sessionList.push(...returnParams)
+	getToken(userStore.user.useId).then(({ returnParams }) => {
+		token.value = returnParams.aiToken
 	})
-}
-// 新建会话
-function createSession() {
-	messages.length = 0
-	thisSessionId.value = 0
-	showLeftDrawer.value.close()
-}
-// 切换会话
-function changeSession(sessionId) {
-	thisSessionId.value = sessionId
-	initHistoryMessage(sessionId)
-}
-// 修改会话信息
-const editSession = ref({})
-const editPopup = ref(null)
-const editButtonState = ref(true)
-function toEditSession(session) {
-	showLeftDrawer.value.close()
-	editSession.value = session
-	editPopup.value.open()
-}
-function submitEditSession() {
-	editButtonState.value = false
-	setSessionName(editSession.value).then(res => {
-		initHistorySession()
-		editPopup.value.close()
-		editButtonState.value = true
-	})
-}
-function deleteSession() {
-	editButtonState.value = false
-	$modal.confirm("确认删除").then(res => {
-		delSession(editSession.value.sessionId).then(res => {
-			initHistorySession()
-			createSession()
-			editPopup.value.close()
-				editButtonState.value = true
-			})
-		})
-		.catch(res => {
-			editButtonState.value = true
-		})
-	}
-	
-	const messages = reactive([{
-			sender: 'assistant',
-			content: '您好,我是ai助手'
-		}
-	]);
-function initHistoryMessage(sessionId) {
-	getMessageList(sessionId).then(res => {
-		const returnParams = res.returnParams
-		messages.length = 0
-		for (let i = 0; i < returnParams.length; i++) {
-			const item = returnParams[i]
-			messages.push({
-				sender: 'user',
-				content: item.sendContent
-			})
-			messages.push({
-				sender: 'assistant',
-				content: item.receiveContent
-			})
-		}
-		scrollToBottom(); // 滚动到底部
-	})
-}
-
-	const thisSessionId = ref(0);
-	const inputMessage = ref('');
-	const scrollToView = ref('');// 滚动到特定消息的标识
-	const buttonState = ref(true)
-	const loadingButton = ref(false)
-
-	// 发送消息函数
-	function sendMessage() {
-		buttonState.value = false
-		if (inputMessage.value.trim() === '') {
-			buttonState.value = true
-			return;
-		}
-		messages.push({
-			sender: 'user',
-			content: inputMessage.value
-		});
-		loadingButton.value = true
-		scrollToBottom(); // 滚动到底部
-		const message = {
-			sessionId: thisSessionId.value,
-			prompt: inputMessage.value,
-			userId: userStore.user.useId,
-			sort: messages.filter(item => item.sender == 'user').length
-		}
-		sendMessageToAI(message).then((res) => {
-			const returnParams = res.returnParams
-			if (thisSessionId.value == 0) { // 添加新会话
-				thisSessionId.value = returnParams.sessionId // 新会话ID
-				sessionList.unshift({
-					sessionName: returnParams.sessionName,
-					sessionId: returnParams.sessionId
-				})
-			} else {
-				initHistorySession()
-			}
-			inputMessage.value = ''; // 清空输入框
-			loadingButton.value = false
-			if (thisSessionId.value != returnParams.sessionId) {
-				buttonState.value = true;
-				return
-			}
-			let content = ""
-			const index = messages.length // 新增消息索引
-			messages.push({ // 
-				sender: 'assistant',
-				content: content
-			});
-			let i = 0
-			const charLength = 3 // 每次显示字数
-			const messageLength = returnParams.receiveContent.length
-			const interval = setInterval(() => { //模拟流式输出
-				if (i < messageLength) {
-					let sliceLength = i + charLength > messageLength?messageLength:i + charLength // 当前显示字数
-					messages[index].content += returnParams.receiveContent.slice(i, sliceLength); // 每次输出 3 个字符
-					i += charLength;
-				} else {
-					clearInterval(interval);
-					buttonState.value = true;
-				}
-			}, 50); // 50ms 一次
-		})
-	};
-
-	// 滚动到底部的函数
-	function scrollToBottom() {
-		nextTick(() => {
-			scrollToView.value = 'msg' + (messages.length - 1); // 更新滚动到的消息
-		});
-	};
-
-	const $scrollViewWidth = ref(0); // 滚动视图宽度
-	const $viewMaxHeight = ref(0); // 滚动视图最大高度
-	const $viewPadding = ref(10); // 滚动视图内边距
-	const $windowHeight = ref(0); // 窗口高度
-
-	// 输入框行数变化时更新最大高度
-	function chatMsgMaxHeightChange(e) {
-		// console.log($windowHeight,e.detail.height);
-		$viewMaxHeight.value = $windowHeight.value - e.detail.height - 70;
-	}
+});
 </script>
 
 
@@ -267,123 +31,5 @@ function initHistoryMessage(sessionId) {
 	flex-direction: column;
 	height: 100vh;
 	position: relative;
-
-}
-
-.chat-messages {
-	flex: 1;
-	background-color: #f3f3f3;
-	overflow-y: auto;
-
-}
-
-.message {
-	max-width: 70%;
-	margin: 5px 0;
-	padding: 8px;
-	border-radius: 10px;
-	display: inline-block;
-	word-wrap: break-word;
-}
-
-.loading_button {
-	background-color: #ECECEC !important;
-}
-.loading_button::after {
-	border: 0px;
 }
-
-.user-message {
-	background-color: #DCF8C6;
-	align-self: flex-end;
-	float: right;
-}
-
-.ai-message {
-	background-color: #ECECEC;
-	align-self: flex-start;
-}
-
-.chat-input {
-	display: flex;
-	padding: 10px;
-	background-color: #FFFFFF;
-	border-top: 1px solid #E0E0E0;
-	position: absolute;
-	bottom: 0;
-	left: 0;
-	right: 0;
-}
-
-.input-field {
-	flex: 1;
-	border: 1px solid #E0E0E0;
-	border-radius: 20px;
-	padding: 12px;
-	margin-right: 10px;
-}
-
-.send-button {
-	border: none;
-	border-radius: 20px;
-	padding: 0 20px;
-	background-color: #007AFF;
-		color: white;
-		height: 46px;
-	}
-	
-	.fab_button {
-		::v-deep .history_button {
-			.uni-fab__circle {
-				bottom: 100px !important;
-			}
-			.uni-fab__circle {
-				width: calc(55px + .5*(1rem - 16px)) !important;
-				height: calc(55px + .5*(1rem - 16px)) !important;
-			
-				.uni-icons {
-					font-size: calc(32px + .5*(1rem - 16px)) !important;
-				}
-			}
-		}
-	}
-	.drawer_container {
-		::v-deep .list_container {
-			.uni-list-item__content {
-				.uni-list-item__content-title {
-					font-size: calc(14px + .5*(1rem - 16px)) !important;
-				}
-			}
-			.uni-icons {
-				font-size: calc(24px + .5*(1rem - 16px)) !important;
-			}
-		}
-	}
-	.edit_popup {
-		::v-deep .edit_session_container {
-			.uni-card__header {
-				.uni-card__header-content-title {
-					font-size: calc(15px + .5*(1rem - 16px)) !important;
-				}
-			}
-			.uni-card__content {
-				.uni-forms-item {
-					.uni-forms-item__label {
-						font-size: calc(14px + .5*(1rem - 16px)) !important;
-					}
-					.uni-forms-item__content {
-						.uni-easyinput {
-							.uni-easyinput__content-textarea {
-								font-size: calc(14px + .5*(1rem - 16px)) !important;
-								min-width: 200px;
-							}
-							.uni-icons {
-								font-size: calc(24px + .5*(1rem - 16px)) !important;
-							}
-						}
-					}
-				}
-			}
-		}
-	}
 </style>