Ver Fonte

问答页面优化和增加上传报告功能

htc há 11 horas atrás
pai
commit
42b5663462
5 ficheiros alterados com 108 adições e 93 exclusões
  1. 2 2
      http/baseApi.js
  2. 1 1
      manifest.json
  3. 15 19
      pages/dialog.vue
  4. 86 67
      pages/reportAsk.vue
  5. 4 4
      pages/reportDetail.vue

+ 2 - 2
http/baseApi.js

@@ -1,5 +1,5 @@
-// const BaseApi = 'https://transcend.ringzle.com/chuangheng-app/app' //线上
-const BaseApi = 'https://wxapp.transcend-intl.cn/chuangheng-app/app' //生产
+const BaseApi = 'https://transcend.ringzle.com/chuangheng-app/app' //线上
+// const BaseApi = 'https://wxapp.transcend-intl.cn/chuangheng-app/app' //生产
 // const BaseApi = 'http://192.168.2.19:9023/chuangheng-app/app' //李勇
 // const BaseApi = 'http://192.168.2.19:9023/chuangheng-app/app' //李勇
 
 
 export {
 export {

+ 1 - 1
manifest.json

@@ -102,7 +102,7 @@
     "quickapp" : {},
     "quickapp" : {},
     /* 小程序特有相关 */
     /* 小程序特有相关 */
     "mp-weixin" : {
     "mp-weixin" : {
-        "appid" : "wxb0ecfcf0c3e50402",
+        "appid" : "wxe6afb089695f90e7",
         "setting" : {
         "setting" : {
             "urlCheck" : false,
             "urlCheck" : false,
             "es6" : false,
             "es6" : false,

+ 15 - 19
pages/dialog.vue

@@ -133,7 +133,7 @@
 					this.isRequesting = false;
 					this.isRequesting = false;
 				}
 				}
 			},
 			},
-			_executeRequest(){
+			_executeRequest2(){
 				return new Promise((resolve, reject) => {
 				return new Promise((resolve, reject) => {
 					this.$api.post('/core/chat/sendChatMessageStream',{query:this.question},false).then(res=>{
 					this.$api.post('/core/chat/sendChatMessageStream',{query:this.question},false).then(res=>{
 						if(res.data.code!==0) return this.$showToast(res.data.msg)
 						if(res.data.code!==0) return this.$showToast(res.data.msg)
@@ -148,7 +148,7 @@
 				})
 				})
 			},
 			},
 			// 实际执行请求的方法
 			// 实际执行请求的方法
-			_executeRequest2() {
+			_executeRequest() {
 				return new Promise((resolve, reject) => {
 				return new Promise((resolve, reject) => {
 					requestTask = uni.request({
 					requestTask = uni.request({
 						url: `${BaseApi}/core/chat/sendChatMessageStream`,
 						url: `${BaseApi}/core/chat/sendChatMessageStream`,
@@ -156,7 +156,7 @@
 						timeout: 10000,
 						timeout: 10000,
 						data:{ 
 						data:{ 
 							query: this.question,
 							query: this.question,
-							timestamp:Date.now()
+							identity:'被教练者',
 						},
 						},
 						header: {
 						header: {
 						  'Content-Type': 'application/json',
 						  'Content-Type': 'application/json',
@@ -186,24 +186,20 @@
 						const decodedString = decoder.decode(uint8Array);
 						const decodedString = decoder.decode(uint8Array);
 						try {
 						try {
 							let newtext = decodedString.replaceAll('data:','')
 							let newtext = decodedString.replaceAll('data:','')
-							let ntArr = newtext.split(/\s+/);
+							let ntArr = newtext.split('\n\n');
 							if(ntArr.length){
 							if(ntArr.length){
 								ntArr.forEach(n=>{
 								ntArr.forEach(n=>{
 									if(!n.trim()) return
 									if(!n.trim()) return
-									let answer = this.dialogList[this.dialogList.length-1].answer+n+'<br/>';
-									this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
-									this.$set(this.dialogList[this.dialogList.length-1],'think',false);
-									
-									// let nj = JSON.parse(n);
-									// if(nj.event=='agent_message'){
-									// 	let answer = this.dialogList[this.dialogList.length-1].answer+nj.answer;
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'id',nj.id);
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'task_id',nj.task_id);
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'message_id',nj.message_id);
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'conversation_id',nj.conversation_id);
-									// 	this.$set(this.dialogList[this.dialogList.length-1],'think',false);
-									// }
+									let nj = JSON.parse(n);
+									if(nj.event=='message'){
+										let answer = this.dialogList[this.dialogList.length-1].answer+nj.answer?.replace(/(\r\n|\n|\r)+/g, '<br>');
+										this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
+										this.$set(this.dialogList[this.dialogList.length-1],'id',nj.id);
+										this.$set(this.dialogList[this.dialogList.length-1],'task_id',nj.task_id);
+										this.$set(this.dialogList[this.dialogList.length-1],'message_id',nj.message_id);
+										this.$set(this.dialogList[this.dialogList.length-1],'conversation_id',nj.conversation_id);
+										this.$set(this.dialogList[this.dialogList.length-1],'think',false);
+									}
 								})
 								})
 								setTimeout(()=>{
 								setTimeout(()=>{
 									this.scrollToBottom();
 									this.scrollToBottom();
@@ -419,7 +415,7 @@
 					font-size: 30rpx;
 					font-size: 30rpx;
 					color: #FFFFFF;
 					color: #FFFFFF;
 					line-height: 48rpx;
 					line-height: 48rpx;
-					text-align: right;
+					// text-align: right;
 					padding: 26rpx 30rpx;
 					padding: 26rpx 30rpx;
 				}
 				}
 			}
 			}

+ 86 - 67
pages/reportAsk.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
 	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
 	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
-		<cus-header title='对报告提问' bgColor="transparent"></cus-header>
+		<cus-header title='对报告提问' bgColor="#FFFFFF"></cus-header>
 		<div class="dialogs container" ref="messageContainer">
 		<div class="dialogs container" ref="messageContainer">
 			<div class="d_pdf">
 			<div class="d_pdf">
 				<div class="dp_box">
 				<div class="dp_box">
@@ -21,7 +21,15 @@
 						<text>创衡正念企业教练</text>
 						<text>创衡正念企业教练</text>
 					</div>
 					</div>
 					<div class="da_content">
 					<div class="da_content">
-						<u-parse :content="item.answer"></u-parse>
+						<template v-if="item.think">
+							<view class="dac_think adfac">
+								<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/07/07/13c5dd16-2032-464a-8b1c-2722d201cfe2.gif"></image>
+								<text>正在思考中</text>
+							</view>
+						</template>
+						<template v-else>
+							<u-parse :content="item.answer"></u-parse>
+						</template>
 						<div class="dc_btns adfacjb" v-if="item.answer">
 						<div class="dc_btns adfacjb" v-if="item.answer">
 							<div class="db_l">
 							<div class="db_l">
 								<image :src="item.copy?require('@/static/copy_active.png'):require('@/static/copy.png')" @tap="toCopy(item,index)"></image>
 								<image :src="item.copy?require('@/static/copy_active.png'):require('@/static/copy.png')" @tap="toCopy(item,index)"></image>
@@ -29,32 +37,23 @@
 								<image :src="item.comment?require('@/static/comment_active.png'):require('@/static/comment.png')" @tap="toComment(item,index)"></image>
 								<image :src="item.comment?require('@/static/comment_active.png'):require('@/static/comment.png')" @tap="toComment(item,index)"></image>
 							</div>
 							</div>
 							<div class="db_r">
 							<div class="db_r">
-								<image :src="item.share?require('@/static/share_active.png'):require('@/static/share.png')" @tap="toShare(item,index)"></image>
+								<!-- <image :src="item.share?require('@/static/share_active.png'):require('@/static/share.png')" @tap="toShare(item,index)"></image> -->
 							</div>
 							</div>
 						</div>
 						</div>
 					</div>
 					</div>
 				</div>
 				</div>
 			</div>
 			</div>
 		</div>
 		</div>
-		<div class="ask">
-			<div class="a_inp">
-				<u-textarea v-model="question" placeholder="请输入您的问题" autoHeight @confirm="sendQuestion"></u-textarea>
-			</div>
-			<div class="a_btn adfacjb">
-				<div class="ab_l adfac">
-					<div class="al_pre adfacjc">
-						<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/451ac13c-5fdc-4d15-8f35-9f4d238e87c1.png"></image>
-						<text>创衡增强</text>
+		<div class="ask_box" :style="{'bottom':fixBottom+'px'}">
+			<div class="ask">
+				<div class="a_inp">
+					<div class="ai_l">
+						<u-textarea v-model="question" placeholder="请输入您的问题" autoHeight :showConfirmBar="false" :adjustPosition="false" maxlength="999999"></u-textarea>
 					</div>
 					</div>
-					<div class="al_pre adfacjc">
-						<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/d4668dcc-1d28-47ff-8bae-84dc6475794b.png"></image>
-						<text>联网搜索</text>
+					<div class="ai_r">
+						<image @tap="sendQuestion" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/2429556b-54b7-4878-97c0-6b440b546ee4.png"></image>
 					</div>
 					</div>
 				</div>
 				</div>
-				<div class="ab_r">
-					<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/caf6075c-0967-4c99-a269-ea453537075c.png"></image>
-					<image @tap="sendQuestion" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/2429556b-54b7-4878-97c0-6b440b546ee4.png"></image>
-				</div>
 			</div>
 			</div>
 		</div>
 		</div>
 		<u-modal :show="commentShow" title="评论" @confirm="commentConfirm" @cancel="commentCancel" @close="commentCancel" :showCancelButton="true">
 		<u-modal :show="commentShow" title="评论" @confirm="commentConfirm" @cancel="commentCancel" @close="commentCancel" :showCancelButton="true">
@@ -83,11 +82,21 @@
 				commentShow:false,
 				commentShow:false,
 				content:'',
 				content:'',
 				cindex:'',
 				cindex:'',
+				fixBottom: 0
 			}
 			}
 		},
 		},
 		onLoad(option) {
 		onLoad(option) {
 			this.pdfUrl = option.pdfUrl;
 			this.pdfUrl = option.pdfUrl;
 		},
 		},
+		onReady() {
+		    uni.onKeyboardHeightChange(res => {
+		      this.fixBottom = res.height||0;
+		    });
+		},
+		onUnload() {
+		    uni.offKeyboardHeightChange();
+			this.fixBottom = 0;
+		},
 		methods:{
 		methods:{
 			// 封装带重试机制的请求方法
 			// 封装带重试机制的请求方法
 			async sendRequestWithRetry() {
 			async sendRequestWithRetry() {
@@ -106,12 +115,13 @@
 			_executeRequest() {
 			_executeRequest() {
 				return new Promise((resolve, reject) => {
 				return new Promise((resolve, reject) => {
 					requestTask = uni.request({
 					requestTask = uni.request({
-						url: `${BaseApi}/core/chat/messages`,
+						url: `${BaseApi}/core/chat/sendChatMessageStream`,
 						method: 'POST',
 						method: 'POST',
 						timeout: 10000,
 						timeout: 10000,
 						data:{ 
 						data:{ 
 							query: this.question,
 							query: this.question,
-							timestamp:Date.now()
+							identity:'被教练者',
+							report:this.pdfUrl
 						},
 						},
 						header: {
 						header: {
 						  'Content-Type': 'application/json',
 						  'Content-Type': 'application/json',
@@ -141,21 +151,24 @@
 						const decodedString = decoder.decode(uint8Array);
 						const decodedString = decoder.decode(uint8Array);
 						try {
 						try {
 							let newtext = decodedString.replaceAll('data:','')
 							let newtext = decodedString.replaceAll('data:','')
-							let ntArr = newtext.split(/\s+/);
+							let ntArr = newtext.split('\n\n');
 							if(ntArr.length){
 							if(ntArr.length){
 								ntArr.forEach(n=>{
 								ntArr.forEach(n=>{
 									if(!n.trim()) return
 									if(!n.trim()) return
 									let nj = JSON.parse(n);
 									let nj = JSON.parse(n);
-									if(nj.event=='agent_message'){
-										let answer = this.dialogList[this.dialogList.length-1].answer+nj.answer;
+									if(nj.event=='message'){
+										let answer = this.dialogList[this.dialogList.length-1].answer+nj.answer?.replace(/(\r\n|\n|\r)+/g, '<br>');
 										this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
 										this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
 										this.$set(this.dialogList[this.dialogList.length-1],'id',nj.id);
 										this.$set(this.dialogList[this.dialogList.length-1],'id',nj.id);
 										this.$set(this.dialogList[this.dialogList.length-1],'task_id',nj.task_id);
 										this.$set(this.dialogList[this.dialogList.length-1],'task_id',nj.task_id);
 										this.$set(this.dialogList[this.dialogList.length-1],'message_id',nj.message_id);
 										this.$set(this.dialogList[this.dialogList.length-1],'message_id',nj.message_id);
 										this.$set(this.dialogList[this.dialogList.length-1],'conversation_id',nj.conversation_id);
 										this.$set(this.dialogList[this.dialogList.length-1],'conversation_id',nj.conversation_id);
-										uni.pageScrollTo({ scrollTop: 99999, duration: 300});
+										this.$set(this.dialogList[this.dialogList.length-1],'think',false);
 									}
 									}
 								})
 								})
+								setTimeout(()=>{
+									this.scrollToBottom();
+								},100)
 							}
 							}
 						} catch (e) {
 						} catch (e) {
 							console.error('解析失败', e, '原始数据:', decodedString);
 							console.error('解析失败', e, '原始数据:', decodedString);
@@ -203,14 +216,26 @@
 					upvote:false,
 					upvote:false,
 					comment:'',
 					comment:'',
 					share:false,
 					share:false,
+					think:true
 				}
 				}
 				this.dialogList = [...this.dialogList,...[qa]];
 				this.dialogList = [...this.dialogList,...[qa]];
 				this.$nextTick(()=>{
 				this.$nextTick(()=>{
-					uni.pageScrollTo({ scrollTop: 99999, duration: 300});
+					this.scrollToBottom();
 					this.sendRequestWithRetry();
 					this.sendRequestWithRetry();
 					this.question = '';
 					this.question = '';
 				})
 				})
 			},
 			},
+			// 滚动到底部
+			scrollToBottom() {
+				this.$nextTick(()=>{
+					this.$nextTick(()=>{
+						uni.pageScrollTo({
+							scrollTop:99999,
+							duration:300
+						})
+					})
+				})
+			},
 			toCopy(item,index){
 			toCopy(item,index){
 				uni.setClipboardData({
 				uni.setClipboardData({
 					data:item.answer,
 					data:item.answer,
@@ -250,12 +275,12 @@
 		padding: 0 !important;
 		padding: 0 !important;
 	}
 	}
 	::v-deep .u-textarea textarea{
 	::v-deep .u-textarea textarea{
-		min-height: 96rpx !important;
+		min-height: 64rpx !important;
 	}
 	}
 	
 	
 	.page{
 	.page{
 		background: linear-gradient( 227deg, #EEEFF8 0%, #F6ECF4 100%, #F6ECF4 100%);
 		background: linear-gradient( 227deg, #EEEFF8 0%, #F6ECF4 100%, #F6ECF4 100%);
-		padding: 0 30rpx 302rpx;
+		padding: 0 30rpx 200rpx;
 		box-sizing: border-box;
 		box-sizing: border-box;
 		
 		
 		.welcome{
 		.welcome{
@@ -286,7 +311,6 @@
 	
 	
 		.dialogs{
 		.dialogs{
 			width: 100%;
 			width: 100%;
-			height: calc(100vh - 282rpx);
 			padding-top: 34rpx;
 			padding-top: 34rpx;
 			box-sizing: border-box;
 			box-sizing: border-box;
 			overflow-y: auto;
 			overflow-y: auto;
@@ -314,6 +338,16 @@
 					margin-top: 20rpx;
 					margin-top: 20rpx;
 					background: #FFFFFF;
 					background: #FFFFFF;
 					border-radius: 4rpx 24rpx 24rpx 24rpx;
 					border-radius: 4rpx 24rpx 24rpx 24rpx;
+					.dac_think{
+						image{
+							width: 40rpx;
+							height: 40rpx;
+						}
+						text{
+							font-size: 30rpx;
+							margin-left: 10rpx;
+						}
+					}
 					.dc_btns{
 					.dc_btns{
 						margin-top: 44rpx;
 						margin-top: 44rpx;
 						image{
 						image{
@@ -340,7 +374,7 @@
 					font-size: 30rpx;
 					font-size: 30rpx;
 					color: #FFFFFF;
 					color: #FFFFFF;
 					line-height: 48rpx;
 					line-height: 48rpx;
-					text-align: right;
+					// text-align: right;
 					padding: 26rpx 30rpx;
 					padding: 26rpx 30rpx;
 				}
 				}
 			}
 			}
@@ -382,53 +416,38 @@
 			}
 			}
 		}
 		}
 	
 	
+		.ask_box{
+			width: 100%;
+			min-height: 176rpx;
+			background: linear-gradient( 227deg, #EEEFF8 0%, #F6ECF4 100%, #F6ECF4 100%);
+			padding: 0 30rpx 60rpx;
+			position: fixed;
+			left: 0;
+			box-sizing: border-box;
+		}
+	
 		.ask{
 		.ask{
-			width: calc(100% - 60rpx);
-			height: 210rpx;
+			min-height: 116rpx;
 			background: #FFFFFF;
 			background: #FFFFFF;
 			border-radius: 24rpx;
 			border-radius: 24rpx;
 			border: 2rpx solid #F0F2F8;
 			border: 2rpx solid #F0F2F8;
-			position: fixed;
-			left: 30rpx;
-			bottom: 72rpx;
-			display: flex;
-			flex-direction: column;
 			padding: 24rpx;
 			padding: 24rpx;
 			box-sizing: border-box;
 			box-sizing: border-box;
 			.a_inp{
 			.a_inp{
-				flex: 1;
+				display: flex;
+				align-items: flex-end;
+				max-height: 300rpx;
 				overflow-y: auto;
 				overflow-y: auto;
-			}
-			.a_btn{
-				padding-top: 20rpx;
-				height: 54rpx;
-				.ab_l{
-					.al_pre{
-						width: 162rpx;
-						height: 54rpx;
-						background: #FFFFFF;
-						border-radius: 27rpx;
-						border: 1rpx solid #E0E0E0;
-						margin-right: 24rpx;
-						image{
-							width: 24rpx;
-							height: 24rpx;
-						}
-						text{
-							font-family: PingFangSC, PingFang SC;
-							font-weight: 400;
-							font-size: 22rpx;
-							color: #393939;
-							line-height: 22rpx;
-							margin-left: 10rpx;
-						}
-					}
+				.ai_l{
+					width: calc(100% - 64rpx);
+					padding-right: 20rpx;
+					box-sizing: border-box;
 				}
 				}
-				.ab_r{
+				.ai_r{
+					width: 64rpx;
 					image{
 					image{
-						width: 48rpx;
-						height: 48rpx;
-						margin-left: 30rpx;
+						width: 64rpx;
+						height: 64rpx;
 					}
 					}
 				}
 				}
 			}
 			}

+ 4 - 4
pages/reportDetail.vue

@@ -9,9 +9,9 @@
 				</div>
 				</div>
 			</div>
 			</div>
 		</div>
 		</div>
-		<!-- <div class="bottom">
+		<div class="bottom">
 			<div class="zt_btn" @tap="askReport">对报告提问</div>
 			<div class="zt_btn" @tap="askReport">对报告提问</div>
-		</div> -->
+		</div>
 	</view>
 	</view>
 </template>
 </template>
 
 
@@ -43,7 +43,7 @@
 			},
 			},
 			askReport(){
 			askReport(){
 				uni.navigateTo({
 				uni.navigateTo({
-					url:`/pages/reportAsk?pdf=${this.pdfUrl}`
+					url:`/pages/reportAsk?pdfUrl=${this.pdfUrl}`
 				})
 				})
 			},
 			},
 			touchStart(event) {
 			touchStart(event) {
@@ -82,7 +82,7 @@
 
 
 <style scoped lang="less">
 <style scoped lang="less">
 	.page{
 	.page{
-		padding: 0 24px 20rpx;
+		padding: 0 24px 192rpx;
 		box-sizing: border-box;
 		box-sizing: border-box;
 		background: #FFFFFF;
 		background: #FFFFFF;