Browse Source

添加新增聊天并清空当前聊天功能

yangg 8 months ago
parent
commit
05320e8070
3 changed files with 272 additions and 96 deletions
  1. 270 94
      pages/ai-assistant/index.vue
  2. 1 1
      pages/complaint/index.vue
  3. 1 1
      pages/my/index.vue

+ 270 - 94
pages/ai-assistant/index.vue

@@ -28,6 +28,10 @@
 				</view>
 				</view>
 			</block>
 			</block>
 		</scroll-view>
 		</scroll-view>
+		<!-- 添加新建对话按钮 -->
+		<view class="new-chat-btn">
+			<button @tap="startNewChat" class="btn-new">新建对话</button>
+		</view>
 		<view class="input-container">
 		<view class="input-container">
 			<textarea v-model="userInput" @keydown="handleKeydown" placeholder="有问题可以咨询我..." maxlength="100"></textarea>
 			<textarea v-model="userInput" @keydown="handleKeydown" placeholder="有问题可以咨询我..." maxlength="100"></textarea>
 			<button @tap="sendMessage" class="btn">发送</button>
 			<button @tap="sendMessage" class="btn">发送</button>
@@ -49,11 +53,10 @@
 					time: "",
 					time: "",
 					done: true,
 					done: true,
 				}, ],
 				}, ],
-				generating: false,
 				userInput: "",
 				userInput: "",
 				websocket: null,
 				websocket: null,
 				AiUrl: '',
 				AiUrl: '',
-				apiUrl: 'http://192.168.66.208:8082',
+				apiUrl: 'https://ylaiapi.raycos.com.cn',
 				scrollTop: 0,
 				scrollTop: 0,
 				tweaks: {},
 				tweaks: {},
 				userAvatar: '/static/用户.png',
 				userAvatar: '/static/用户.png',
@@ -61,15 +64,28 @@
 				level: 1,
 				level: 1,
 				idArray: [],
 				idArray: [],
 				minioUrls: [], // 新增:用于存储 Minio URL
 				minioUrls: [], // 新增:用于存储 Minio URL
+				generating: false, // 是否正在生成回复
+				typewriterTimer: null,
+				currentIndex: 0,
+				fullMessage: '',
+				session_id: "",
+				platform: {
+					type: '', // 平台类型
+					name: '', // 平台名称
+					isWeixin: false
+				}
 			};
 			};
 		},
 		},
 		created() {
 		created() {
 
 
-
 		},
 		},
 		onLoad() {
 		onLoad() {
-			this.getKbmUrl()
+			// this.getKbmUrl()
 			this.loadUserInfo()
 			this.loadUserInfo()
+			this.getPlatformInfo();
+		},
+		onShow() {
+			this.getKbmUrl()
 		},
 		},
 		watch: {
 		watch: {
 			messages: {
 			messages: {
@@ -82,6 +98,112 @@
 			}
 			}
 		},
 		},
 		methods: {
 		methods: {
+			// 添加新建对话方法
+			startNewChat() {
+				uni.showModal({
+					title: '确认新建对话',
+					content: '是否清空当前对话内容开始新的对话?',
+					success: (res) => {
+						if (res.confirm) {
+							// 重置消息列表,只保留欢迎消息
+							this.messages = [{
+								user: "bot",
+								messageType: "TEXT",
+								message: "欢迎使用智能AI助理",
+								html: "",
+								time: "",
+								done: true,
+							}];
+
+							// 清空session_id
+							this.session_id = "";
+
+							// 清空MinioUrls
+							this.minioUrls = [];
+
+							// 重置其他相关状态
+							this.generating = false;
+							this.currentIndex = 0;
+							this.fullMessage = '';
+
+							// 显示提示
+							uni.showToast({
+								title: '已开始新对话',
+								icon: 'success',
+								duration: 1500
+							});
+						}
+					}
+				});
+			},
+			// 获取平台信息
+			getPlatformInfo() {
+				try {
+					const systemInfo = uni.getSystemInfoSync();
+					// console.log('系统信息:', systemInfo);
+
+					// 判断平台类型
+					// #ifdef MP-WEIXIN
+					this.platform.type = 'mp-weixin';
+					this.platform.name = '微信小程序';
+					this.platform.isWeixin = true;
+					// #endif
+
+					// #ifdef MP-ALIPAY
+					this.platform.type = 'mp-alipay';
+					this.platform.name = '支付宝小程序';
+					// #endif
+
+					// #ifdef MP-BAIDU
+					this.platform.type = 'mp-baidu';
+					this.platform.name = '百度小程序';
+					// #endif
+
+					// #ifdef MP-TOUTIAO
+					this.platform.type = 'mp-toutiao';
+					this.platform.name = '头条小程序';
+					// #endif
+
+					// #ifdef H5
+					this.platform.type = 'h5';
+					this.platform.name = 'H5';
+					// 在H5中判断是否在微信浏览器中
+					if (navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1) {
+						this.platform.isWeixin = true;
+						this.platform.name = 'H5微信浏览器';
+					}
+					// #endif
+
+					// #ifdef APP-PLUS
+					this.platform.type = 'app';
+					this.platform.name = 'App';
+					// #endif
+
+					// console.log('当前平台:', this.platform);
+
+					// 获取更详细的平台信息
+					const platformInfo = {
+						brand: systemInfo.brand, // 手机品牌
+						model: systemInfo.model, // 手机型号
+						system: systemInfo.system, // 操作系统版本
+						platform: systemInfo.platform, // 客户端平台
+						SDKVersion: systemInfo.SDKVersion, // 小程序基础库版本
+						version: systemInfo.version, // 微信版本号
+					};
+
+					// console.log('平台详细信息:', platformInfo);
+
+					return this.platform;
+
+				} catch (error) {
+					console.error('获取平台信息失败:', error);
+					return {
+						type: 'unknown',
+						name: '未知平台',
+						isWeixin: false
+					};
+				}
+			},
 			getMainContent(message) {
 			getMainContent(message) {
 				const parts = message.split('相关资料来源');
 				const parts = message.split('相关资料来源');
 				return parts[0].trim();
 				return parts[0].trim();
@@ -138,7 +260,7 @@
 			},
 			},
 			scrollToBottom() {
 			scrollToBottom() {
 				// 使用一个很大的值来确保滚动到底部
 				// 使用一个很大的值来确保滚动到底部
-				this.scrollTop += 1000;
+				this.scrollTop += 9999;
 				// 重置 scrollTop 以便下次滚动生效
 				// 重置 scrollTop 以便下次滚动生效
 				// this.$nextTick(() => {
 				// this.$nextTick(() => {
 				//   this.scrollTop = 0;
 				//   this.scrollTop = 0;
@@ -282,10 +404,12 @@
 			async sendMessage() {
 			async sendMessage() {
 				const wsUrl = this.AiUrl;
 				const wsUrl = this.AiUrl;
 				let message = this.userInput.trim();
 				let message = this.userInput.trim();
-				if (message) {
+				if (!message || this.typewriterTimer) return; // 防止重复发送
+
+				try {
 					// 添加用户消息
 					// 添加用户消息
 					const userMessage = {
 					const userMessage = {
-						id: this.getUuid(), // 为每条消息添加唯一ID
+						id: this.getUuid(),
 						user: "user",
 						user: "user",
 						messageType: "TEXT",
 						messageType: "TEXT",
 						message: message,
 						message: message,
@@ -294,7 +418,7 @@
 					};
 					};
 					this.messages.push(userMessage);
 					this.messages.push(userMessage);
 
 
-					// 清空输入框并滚动
+					// 清空输入框
 					this.userInput = "";
 					this.userInput = "";
 					this.scrollToBottom();
 					this.scrollToBottom();
 
 
@@ -303,44 +427,53 @@
 						id: this.getUuid(),
 						id: this.getUuid(),
 						user: "bot",
 						user: "bot",
 						messageType: "TEXT",
 						messageType: "TEXT",
-						message: "",
+						message: "正在思考中...",
 						time: Date.now(),
 						time: Date.now(),
 						done: false,
 						done: false,
 					};
 					};
 					this.messages.push(botMessage);
 					this.messages.push(botMessage);
 
 
-					try {
-						const response = await uni.request({
-							url: wsUrl,
-							method: 'POST',
-							header: {
-								'Content-Type': 'application/json'
-							},
-							data: {
-								message: message,
-								chat_config_id: '17',
-								user_id: this.userInfo.phoneNumber,
-								session_id: this.session_id || "",
-							}
-						});
-
-						if (response.statusCode === 200 && response.data) {
-							if (this.level === '0' && response.data.data?.milvus_ids) {
-								await this.getMinioUrls({
-									ids: response.data.data.milvus_ids
-								});
-							}
-							await this.handleResponse(response.data, botMessage);
+					const response = await uni.request({
+						url: wsUrl,
+						method: 'POST',
+						header: {
+							'Content-Type': 'application/json'
+						},
+						data: {
+							message: message,
+							chat_config_id: '17',
+							user_id: this.userInfo.phoneNumber,
+							session_id: this.session_id || "",
+							source: this.platform.type //uni.getAccountInfoSync().miniProgram.appName,
 						}
 						}
-					} catch (error) {
-						console.error("Error sending message:", error);
-						botMessage.message = "抱歉,发送消息失败,请重试。";
-						botMessage.done = true;
-						uni.showToast({
-							title: '发送消息失败,请重试',
-							icon: 'none'
+					});
+
+					// 检查响应状态和数据
+					if (response.statusCode !== 200 || !response.data || !response.data.data?.answer) {
+						throw new Error('Invalid response from server');
+					}
+
+					if (this.level === '0' && response.data.data?.milvus_ids) {
+						await this.getMinioUrls({
+							ids: response.data.data.milvus_ids
 						});
 						});
 					}
 					}
+					this.session_id = response.data.data.session_id;
+					await this.handleResponse(response.data, botMessage);
+
+				} catch (error) {
+					console.error("Error sending message:", error);
+					// 找到最后一条消息(应该是机器人的消息)并更新它
+					const lastMessage = this.messages[this.messages.length - 1];
+					if (lastMessage && lastMessage.user === 'bot') {
+						lastMessage.message = "抱歉,处理消息时出现错误,请重试。";
+						lastMessage.done = true;
+					}
+
+					uni.showToast({
+						title: '发送消息失败,请重试',
+						icon: 'none'
+					});
 				}
 				}
 			},
 			},
 
 
@@ -381,23 +514,13 @@
 					}
 					}
 
 
 					const data = value.data.answer;
 					const data = value.data.answer;
-					let mainText = data;
+					this.fullMessage = data;
+					this.currentIndex = 0;
+					existingMessage.message = '';
 
 
-					// 直接设置主要回答内容
-					existingMessage.message = mainText;
+					// 开始打字效果
+					this.startTypewriter(existingMessage);
 
 
-					// 如果有 MinioUrls,添加资料来源标记
-					if (this.minioUrls && this.minioUrls.length > 0) {
-						existingMessage.message += '\n\n相关资料来源';
-					}
-
-					// 标记消息完成
-					existingMessage.done = true;
-
-					// 确保滚动到底部
-					this.$nextTick(() => {
-						this.scrollToBottom();
-					});
 				} catch (error) {
 				} catch (error) {
 					console.error("Error handling response:", error);
 					console.error("Error handling response:", error);
 					existingMessage.message = "抱歉,处理响应时出现错误。";
 					existingMessage.message = "抱歉,处理响应时出现错误。";
@@ -405,6 +528,42 @@
 				}
 				}
 			},
 			},
 
 
+			// 新的打字效果实现
+			startTypewriter(existingMessage) {
+				// 清除可能存在的旧计时器
+				if (this.typewriterTimer) {
+					clearInterval(this.typewriterTimer);
+					this.typewriterTimer = null;
+				}
+
+				const doTypewriter = () => {
+					if (this.currentIndex < this.fullMessage.length) {
+						existingMessage.message = this.fullMessage.slice(0, this.currentIndex + 1);
+						this.currentIndex++;
+
+						// 使用 nextTick 确保视图更新
+						this.$nextTick(() => {
+							this.scrollToBottom();
+						});
+
+						// 使用 setTimeout 代替 setInterval
+						this.typewriterTimer = setTimeout(() => {
+							doTypewriter();
+						}, 30);
+					} else {
+						// 打字效果完成
+						if (this.minioUrls && this.minioUrls.length > 0) {
+							existingMessage.message += '\n\n相关资料来源';
+						}
+						existingMessage.done = true;
+						this.typewriterTimer = null;
+						this.scrollToBottom();
+					}
+				};
+
+				// 立即开始打字效果
+				doTypewriter();
+			},
 			// 修改 renderMarkdown 方法以保留 HTML 标签
 			// 修改 renderMarkdown 方法以保留 HTML 标签
 			/* renderMarkdown(rawMarkdown) {
 			/* renderMarkdown(rawMarkdown) {
 				if (typeof rawMarkdown !== 'string') {
 				if (typeof rawMarkdown !== 'string') {
@@ -440,7 +599,7 @@
 			}, */
 			}, */
 
 
 			// 修改 sendMessage 方法
 			// 修改 sendMessage 方法
-			async sendMessage() {
+			/* async sendMessage() {
 				const wsUrl = this.AiUrl;
 				const wsUrl = this.AiUrl;
 				let message = this.userInput.trim();
 				let message = this.userInput.trim();
 				if (message) {
 				if (message) {
@@ -505,7 +664,7 @@
 						});
 						});
 					}
 					}
 				}
 				}
-			},
+			}, */
 			// 修改 renderMarkdown 方法
 			// 修改 renderMarkdown 方法
 			/* renderMarkdown(rawMarkdown) {
 			/* renderMarkdown(rawMarkdown) {
 			    if (typeof rawMarkdown !== 'string') {
 			    if (typeof rawMarkdown !== 'string') {
@@ -655,15 +814,15 @@
 		/* 上下保持原有的 margin,左右自动调整以居中 */
 		/* 上下保持原有的 margin,左右自动调整以居中 */
 		overflow-y: auto;
 		overflow-y: auto;
 		/* 如果消息太多,允许滚动 */
 		/* 如果消息太多,允许滚动 */
-		height: calc(100vh - 160px);
+		height: calc(100vh - 190px);
 		/* 高度需要根据输入框和其他元素的高度调整 */
 		/* 高度需要根据输入框和其他元素的高度调整 */
-		padding: 10px;
+		padding: 10px 10px 0;
 		/* 或你希望的内边距大小 */
 		/* 或你希望的内边距大小 */
 	}
 	}
 
 
 	.message {
 	.message {
 		display: flex;
 		display: flex;
-		padding:10px;
+		padding: 10px;
 		align-items: flex-start;
 		align-items: flex-start;
 	}
 	}
 
 
@@ -812,7 +971,7 @@
 		/* 例如,按钮的最小宽度为 100px */
 		/* 例如,按钮的最小宽度为 100px */
 		width: 40px;
 		width: 40px;
 		height: 30px;
 		height: 30px;
-		line-height: 14px;
+		line-height: 20px;
 		font-size: 12px;
 		font-size: 12px;
 		white-space: nowrap;
 		white-space: nowrap;
 		/* 防止文字折行 */
 		/* 防止文字折行 */
@@ -838,59 +997,76 @@
 	}
 	}
 
 
 	.message-content :deep(p) {
 	.message-content :deep(p) {
-	  font-size: 12px !important;
-	  margin: 5px 0 10px;
-	  padding: 0;
-	  line-height: 22px;
-	  font-weight: inherit;
+		font-size: 12px !important;
+		margin: 5px 0 10px;
+		padding: 0;
+		line-height: 22px;
+		font-weight: inherit;
 	}
 	}
-	
+
 	.message-content :deep(ol) {
 	.message-content :deep(ol) {
-	  padding-bottom: 10px;
+		padding-bottom: 10px;
 	}
 	}
-	
+
 	.message-content :deep(.source-section) {
 	.message-content :deep(.source-section) {
-	  margin: 20px 0 3px;
-	  color: #333;
-	  font-size: 16px;
+		margin: 20px 0 3px;
+		color: #333;
+		font-size: 16px;
 	}
 	}
-	
+
 	.message-content :deep(ol li) {
 	.message-content :deep(ol li) {
-	  padding-top: 3px;
+		padding-top: 3px;
 	}
 	}
-	
+
 	.message-content :deep(ol li a) {
 	.message-content :deep(ol li a) {
-	  font-size: 14px;
-	  color: #1296db;
+		font-size: 14px;
+		color: #1296db;
 	}
 	}
-	
+
 	/* 添加资料来源相关的新样式 */
 	/* 添加资料来源相关的新样式 */
 	.source-section {
 	.source-section {
-	  border-top: 1px solid #e5e5e5;
-	  padding-top: 10px;
-	  margin-top: 10px;
+		border-top: 1px solid #e5e5e5;
+		padding-top: 10px;
+		margin-top: 10px;
 	}
 	}
-	
+
 	.source-title {
 	.source-title {
-	  font-size: 14px;
-	  color: #666;
-	  margin-bottom: 8px;
+		font-size: 14px;
+		color: #666;
+		margin-bottom: 8px;
 	}
 	}
-	
+
 	.source-links {
 	.source-links {
-	  display: flex;
-	  flex-direction: column;
-	  gap: 5px;
+		display: flex;
+		flex-direction: column;
+		gap: 5px;
 	}
 	}
-	
+
 	.source-link {
 	.source-link {
-	  color: #1296db;
-	  font-size: 12px;
-	  cursor: pointer;
-	 /* text-decoration: underline; */
+		color: #1296db;
+		font-size: 12px;
+		cursor: pointer;
+		/* text-decoration: underline; */
 	}
 	}
-	
+
 	.source-link:hover {
 	.source-link:hover {
-	  opacity: 0.8;
+		opacity: 0.8;
+	}
+	/* 添加新建对话按钮样式 */
+	.new-chat-btn {
+	  padding: 0px 20px;
+	  display: flex;
+	  justify-content: flex-start;
+	  background-color: #fff;
+	}
+	
+	.btn-new {
+	  background-color: #1296db;
+	  color: #fff;
+	  font-size: 14px;
+	  border-radius: 5px;
+	  border: none;
+	  height: 35px;  
+	  margin: 0;
 	}
 	}
 </style>
 </style>

+ 1 - 1
pages/complaint/index.vue

@@ -20,7 +20,7 @@
 					contactPhone: '',
 					contactPhone: '',
 					opinion: ''
 					opinion: ''
 				},
 				},
-				apiUrl: 'http://192.168.66.208:8082'
+				apiUrl: 'https://ylaiapi.raycos.com.cn'
 			}
 			}
 		},
 		},
 		onLoad() {
 		onLoad() {

+ 1 - 1
pages/my/index.vue

@@ -158,7 +158,7 @@
 					phoneNumber: '',
 					phoneNumber: '',
 					idCard: ''
 					idCard: ''
 				},
 				},
-				apiUrl: 'http://192.168.66.208:8082' //https://qlaiapi.raycos.com.cn'https://doc.shqlsy.com',https://ylaiapi.raycos.com.cn
+				apiUrl: 'https://ylaiapi.raycos.com.cn' //https://qlaiapi.raycos.com.cn'https://doc.shqlsy.com',https://ylaiapi.raycos.com.cn
 
 
 			}
 			}
 		},
 		},