Przeglądaj źródła

优化;报告详情

htc 10 godzin temu
rodzic
commit
c9146d18c4
10 zmienionych plików z 360 dodań i 191 usunięć
  1. 1 9
      App.vue
  2. 12 0
      pages.json
  3. 1 1
      pages/dialog.vue
  4. 9 3
      pages/home.vue
  5. 11 0
      pages/login.vue
  6. 2 2
      pages/questionnaire.vue
  7. 7 1
      pages/report.vue
  8. 199 175
      pages/dialog - 副本.vue
  9. 118 0
      pages/reportDetail.vue
  10. BIN
      static/pdf.png

+ 1 - 9
App.vue

@@ -12,15 +12,7 @@
 			
 		},
 		onShow: function() {
-			if(uni.getStorageSync('userInfo')){
-				uni.reLaunch({
-					url:'/pages/home'
-				})
-			}else{
-				uni.reLaunch({
-					url:'/pages/login'
-				})
-			}
+			
 		},
 		onHide: function() {
 			

+ 12 - 0
pages.json

@@ -42,6 +42,18 @@
 				"navigationStyle": "custom"
 			}
 		},
+		{
+			"path": "pages/reportDetail",
+			"style": {
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/reportAsk",
+			"style": {
+				"navigationStyle": "custom"
+			}
+		},
 		{
 			"path": "pages/my",
 			"style": {

+ 1 - 1
pages/dialog.vue

@@ -126,7 +126,7 @@
 			_executeRequest() {
 				return new Promise((resolve, reject) => {
 					requestTask = uni.request({
-						url: `${BaseApi}/core/chat/streamingMessage`,
+						url: `${BaseApi}/core/chat/messages`,
 						method: 'POST',
 						timeout: 10000,
 						data:{ 

+ 9 - 3
pages/home.vue

@@ -72,6 +72,7 @@
 		},
 		onLoad() {
 			this.getWjList();
+			this.getReportList2();
 			this.getReportList();
 		},
 		methods:{
@@ -89,10 +90,15 @@
 				})
 			},
 			getReportList(){
-				this.$api.get('/core/report/member/personalReportList/'+'1').then(res=>{
+				this.$api.get('/core/report/member/personalReportList/2').then(res=>{
 					if(res.data.code!==0) return this.$showToast(res.data.msg)
-					this.bgGr = res.data.data.filter(d=>d.type===2).length;
-					this.bgTd = res.data.data.filter(d=>d.type===1).length;
+					this.bgGr = res.data.data.filter(d=>d.type==2).length;
+				})
+			},
+			getReportList2(){
+				this.$api.get('/core/report/member/personalReportList/1').then(res=>{
+					if(res.data.code!==0) return this.$showToast(res.data.msg)
+					this.bgTd = res.data.data.filter(d=>d.type==1).length;
 				})
 			}
 		}

+ 11 - 0
pages/login.vue

@@ -32,6 +32,17 @@
 				
 			}
 		},
+		onShow: function() {
+			if(uni.getStorageSync('userInfo')){
+				uni.reLaunch({
+					url:'/pages/home'
+				})
+			}else{
+				uni.reLaunch({
+					url:'/pages/login'
+				})
+			}
+		},
 		methods:{
 			decryptPhoneNumber(e){
 				if(uni.getStorageSync('token')){

+ 2 - 2
pages/questionnaire.vue

@@ -22,7 +22,7 @@
 						<div class="lb_l adfac">
 							<u-icon name="clock" color="#FD4F66" size="32"></u-icon>
 							<span v-if="item.status===0">截止时间:{{ item.endTime||''}}</span>
-							<span v-else-if="item.status===1">完成时间:{{ item.submitTime||''}}</span>
+							<span v-else-if="item.status===1">完成时间:{{ item.updateDate||''}}</span>
 						</div>
 						<div class="lb_r">
 							<div class="lr_btn" v-if="item.status===0" @tap="toFill(item)">立即作答</div>
@@ -69,7 +69,7 @@
 				})
 			},
 			toRepoer(item){
-				
+				if(!item.fileUrl) return this.$showToast('报告为空,请联系教练。')
 			},
 		}
 	}

+ 7 - 1
pages/report.vue

@@ -18,7 +18,7 @@
 						</div>
 						<div class="lj_r">进度<span>{{item.answerNum||0}}/{{item.finishNum||0}}</span></div>
 					</div>
-					<div class="li_view">查看</div>
+					<div class="li_view" @tap="viewReport(item)">查看</div>
 				</div>
 			</div>
 		</template>
@@ -51,6 +51,12 @@
 					if(res.data.code!==0) return this.$showToast(res.data.msg)
 					this.list = res.data.data;
 				})
+			},
+			viewReport(item){
+				if(!item.fileUrl) return this.$showToast('报告pdf为空,请联系教练。')
+				uni.navigateTo({
+					url:`/pages/reportDetail?pdfUrl=${item.fileUrl}&reportId=${item.reportId}`
+				})
 			}
 		}
 	}

+ 199 - 175
pages/dialog - 副本.vue

@@ -1,19 +1,14 @@
 <template>
-	<view class="tabPage" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
-		<u-navbar title="创衡正念企业教练" bgColor="#FFFFFF" :titleStyle="{'font-size':'32rpx','font-weight':'bold'}">
-			<view class="u-nav-slot" slot="left" style="display: flex;background-color: transparent;">
-				<image src="@/static/history_dialog.png" style="width: 42rpx;height: 42rpx;" @tap="reviewHistory"></image>
-				<image src="@/static/new_dialog.png" style="width: 42rpx;height: 42rpx;margin-left: 40rpx;" @tap="startNewDialog"></image>
-			</view>
-		</u-navbar>
+	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
+		<cus-header title='对报告提问' bgColor="transparent"></cus-header>
 		<div class="dialogs container" ref="messageContainer">
-			<div class="d_answer init">
-				<div class="da_top adfac">
-					<image src="@/static/logo.png"></image>
-					<text>创衡正念企业教练</text>
-				</div>
-				<div class="da_content">
-					Hi,我是企业教练,很高兴遇见你!我随时可以回答您的问题!
+			<div class="d_pdf">
+				<div class="dp_box">
+					<div class="dq_text">{{ '初始调查 - 甜梦巧克力市场部-首次团队测评' }}</div>
+					<div class="dp_type adfac">
+						<image src="@/static/pdf.png"></image>
+						<span>PDF</span>
+					</div>
 				</div>
 			</div>
 			<div v-for="(item,index) in dialogList" :key="index">
@@ -41,33 +36,30 @@
 				</div>
 			</div>
 		</div>
-		<div class="ask adfacjb">
-			<div class="a_l">
-				<input type="text" v-model="question" placeholder="请输入您的问题" @confirm="sendQuestion" ref="questionInp">
+		<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>
+					<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>
+				</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>
-			<image class="a_r" src="@/static/send.png" @tap="sendQuestion"></image>
 		</div>
 		<u-modal :show="commentShow" title="评论" @confirm="commentConfirm" @cancel="commentCancel" @close="commentCancel" :showCancelButton="true">
-			<u-textarea v-model="content" placeholder="对于我们的回答您是否不满意,您有更好的答案建议吗?"></u-textarea>
+			<u-textarea v-model="content" placeholder="对于我们的回答您是否不满意,您有更好的答案建议吗?请在此输入."></u-textarea>
 		</u-modal>
-		<u-popup :show="historyShow" mode="left"  @close="historyClose">
-			<view class="history" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
-				<u-navbar title="历史回答" bgColor="#FFFFFF" :titleStyle="{'font-size':'32rpx','font-weight':'bold'}" style="width: 672rpx;">
-					<view class="u-nav-slot" slot="left" style="display: flex;background-color: transparent;">
-						<image src="@/static/arrow_left_hei.png" style="width: 40rpx;height: 40rpx;" @tap="historyClose"></image>
-					</view>
-				</u-navbar>
-				<div class="h_list">
-					<div class="hl_item" v-for="(item,index) in historyList" :key="index">
-						<div class="hi_date">{{item.date}}</div>
-						<div class="hl_pre" v-for="(pre,idx) in item.list" :key="idx">
-							{{pre.name}}
-						</div>
-					</div>
-				</div>
-			</view>
-		</u-popup>
-		<Tabbar :tabbarIndex="0"></Tabbar>
 	</view>
 </template>
 
@@ -75,55 +67,28 @@
 	var timer = null;
 	let requestTask = null;
 	import { BaseApi } from '../http/baseApi.js'
-	import Tabbar from '@/components/CusTabbar/index.vue'
 	import * as TextEncoding from "text-encoding-shim";
 	export default {
-		components:{ Tabbar },
 		data(){
 			return {
+				pdfUrl:'',
 				retryCount: 3, // 最大重试次数
 				currentRetry: 0, // 当前重试次数
 				isRequesting: false, // 请求状态锁
 				question:'',
+				dialogList:[],
 				streamingResponse:'',
 				receivedData:'',
-				dialogList:[],
 				windex:0,
 				commentShow:false,
 				content:'',
 				cindex:'',
-				historyShow:false,
-				historyList:[
-					{
-						date:'今天',
-						list:[
-							{name:'教练的标准是什么'},
-							{name:'教练的标准是什么?'},
-						]
-					},
-					{
-						date:'2025-05-12',
-						list:[
-							{name:'小众水果网名创意分享'},
-							{name:'教练的标准是什么?'},
-						]
-					},
-				]
 			}
 		},
+		onLoad(option) {
+			this.pdfUrl = option.pdfUrl;
+		},
 		methods:{
-			reviewHistory(){
-				this.historyShow = true;
-			},
-			startNewDialog(){
-				clearInterval(timer)
-				this.dialogList = [];
-				this.question = '';
-				this.streamingResponse = '';
-			},
-			historyClose(){
-				this.historyShow = false;
-			},
 			// 封装带重试机制的请求方法
 			async sendRequestWithRetry() {
 				if (this.isRequesting) return;
@@ -132,7 +97,6 @@
 				try {
 					await this._executeRequest();
 				} catch (error) {
-					  console.error('最终请求失败:', error);
 					  this.$showToast('请求失败,请稍后重试')
 				} finally {
 					this.isRequesting = false;
@@ -140,11 +104,11 @@
 			},
 			// 实际执行请求的方法
 			_executeRequest() {
-			    return new Promise((resolve, reject) => {
+				return new Promise((resolve, reject) => {
 					requestTask = uni.request({
-						url: `${BaseApi}/core/chat/streamingMessage`,
+						url: `${BaseApi}/core/chat/messages`,
 						method: 'POST',
-						timeout: 100000,
+						timeout: 10000,
 						data:{ 
 							query: this.question,
 							timestamp:Date.now()
@@ -172,56 +136,66 @@
 					});
 					
 					requestTask.onChunkReceived(async (res) => {
-							console.log('res',res)
 						const uint8Array = new Uint8Array(res.data);
-						// const decoder = new TextDecoder("utf-8");
 						const decoder = new TextEncoding.TextDecoder("utf-8");
 						const decodedString = decoder.decode(uint8Array);
-						let newtext = decodedString.replaceAll('data:','')
-						newtext = newtext.replace(/\s+/g,'');
-						if(newtext){
-							let answer = this.dialogList[this.dialogList.length-1].answer+newtext;
-							this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
-							uni.pageScrollTo({ scrollTop: 99999, duration: 300});
+						try {
+							let newtext = decodedString.replaceAll('data:','')
+							let ntArr = newtext.split(/\s+/);
+							if(ntArr.length){
+								ntArr.forEach(n=>{
+									if(!n.trim()) return
+									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);
+										uni.pageScrollTo({ scrollTop: 99999, duration: 300});
+									}
+								})
+							}
+						} catch (e) {
+							console.error('解析失败', e, '原始数据:', decodedString);
 						}
 					});
-			    });
+				});
 			},
 			// 成功处理
 			_handleSuccess(data) {
-			    if (data) {
-			      this.streamingResponse += data;
-				  console.log(this.streamingResponse,'streamingResponse');
-			    }
-			    this.currentRetry = 0; // 重置重试计数器
+				if (data) {
+				  this.streamingResponse += data;
+				}
+				this.currentRetry = 0; // 重置重试计数器
 			},
 			// 错误处理
 			_handleError(errorMsg, resolve, reject) {
-			    console.error(`请求失败 (${this.currentRetry}/${this.retryCount}):`, errorMsg);
-			    if (this._shouldRetry(errorMsg)) {
+				if (this._shouldRetry(errorMsg)) {
 					this.currentRetry++;
 					setTimeout(() => {
 						this._executeRequest().then(resolve).catch(reject);
 					}, this._getRetryDelay());
-			    } else {
+				} else {
 					reject(errorMsg);
-			    }
+				}
 			},
 			// 判断是否需要重试
 			_shouldRetry(errorMsg) {
-			    const retryableErrors = [
+				const retryableErrors = [
 					'timeout', 
 					'request:fail', 
 					'Network Error'
-			    ];
-			    return this.currentRetry < this.retryCount && retryableErrors.some(e => errorMsg.includes(e));
+				];
+				return this.currentRetry < this.retryCount && retryableErrors.some(e => errorMsg.includes(e));
 			},
 			// 获取指数退避延迟时间
 			_getRetryDelay() {
-			    return Math.min(1000 * Math.pow(2, this.currentRetry), 10000);
+				return Math.min(1000 * Math.pow(2, this.currentRetry), 10000);
 			},
 			sendQuestion(){
-				if(!this.question) return this.$showToast('请输入问题');
+				if(!this.question) return this.$showToast('请输入您的问题');
 				let qa = {
 					question:JSON.parse(JSON.stringify(this.question)),
 					answer:'',
@@ -238,7 +212,15 @@
 				})
 			},
 			toCopy(item,index){
-				this.$set(this.dialogList[index],'copy',!this.dialogList[index].copy);
+				uni.setClipboardData({
+					data:item.answer,
+					success: (res) => {
+						this.$showToast('复制成功');
+					},
+					fail: (err) => {
+						this.$showToast('复制失败');
+					}
+				})
 			},
 			toUpvote(item,index){
 				this.$set(this.dialogList[index],'upvote',!this.dialogList[index].upvote);
@@ -262,60 +244,50 @@
 	}
 </script>
 
-<style>
-	.history .u-navbar .u-status-bar,.history .u-navbar .u-navbar__content{
-		width: 672rpx !important;
-	}
-</style>
 <style scoped lang="scss">
-	.tabPage{
-		position: relative;
-		background: #F7F2F6;
-		display: flex;
-		flex-direction: column;
+	::v-deep .u-textarea{
+		border: none !important;
+		padding: 0 !important;
+	}
+	::v-deep .u-textarea textarea{
+		min-height: 96rpx !important;
+	}
+	
+	.page{
+		background: linear-gradient( 227deg, #EEEFF8 0%, #F6ECF4 100%, #F6ECF4 100%);
+		padding: 0 30rpx 302rpx;
+		box-sizing: border-box;
 		
-		.history{
-			width: 672rpx;
-			height: 100vh;
-			background: #FFFFFF;
-			box-sizing: border-box;
-			display: flex;
-			flex-direction: column;
-			.h_list{
-				flex: 1;
-				width: 100%;
-				padding: 0 64rpx;
-				box-sizing: border-box;
-				margin-top: 20rpx;
-				overflow-y: auto;
-				.hl_item{
-					margin-top: 64rpx;
-					&:first-child{
-						margin-top: 0;
-					}
-					.hi_date{
-						font-family: PingFangSC, PingFang SC;
-						font-weight: 400;
-						font-size: 30rpx;
-						color: #A4A4A4;
-						line-height: 42rpx;
-					}
-					.hl_pre{
-						font-family: PingFangSC, PingFang SC;
-						font-weight: 400;
-						font-size: 30rpx;
-						color: #000000;
-						line-height: 42rpx;
-						margin-top: 48rpx;
-					}
+		.welcome{
+			margin-top: 259rpx;
+			padding: 0 34rpx;
+			image{
+				width: 88rpx;
+				height: 87rpx;
+				margin-left: 20rpx;
+			}
+			p{
+				font-family: PingFang-SC, PingFang-SC;
+				font-weight: bold;
+				font-size: 36rpx;
+				color: #252525;
+				line-height: 36rpx;
+				margin-top: 36rpx;
+				&.tip{
+					font-family: PingFangSC, PingFang SC;
+					font-weight: 400;
+					font-size: 26rpx;
+					color: #646464;
+					line-height: 40rpx;
+					margin-top: 20rpx;
 				}
 			}
 		}
-		
+	
 		.dialogs{
 			width: 100%;
-			padding: 34rpx 36rpx 164rpx;
-			flex: 1;
+			height: calc(100vh - 282rpx);
+			padding-top: 34rpx;
 			box-sizing: border-box;
 			overflow-y: auto;
 			.d_answer{
@@ -333,7 +305,7 @@
 						font-weight: bold;
 						font-size: 30rpx;
 						color: #505050;
-						line-height: 42rpx;
+						line-height: 48rpx;
 						margin-left: 20rpx;
 					}
 				}
@@ -367,46 +339,98 @@
 					font-weight: 400;
 					font-size: 30rpx;
 					color: #FFFFFF;
-					line-height: 42rpx;
+					line-height: 48rpx;
 					text-align: right;
 					padding: 26rpx 30rpx;
 				}
 			}
+			
+			.d_pdf{
+				margin-top: 20rpx;
+				display: flex;
+				justify-content: flex-end;
+				.dp_box{
+					width: 364rpx;
+					background: #FFFFFF;
+					border-radius: 16rpx;
+					border: 1rpx solid #F0F2F8;
+					padding: 27rpx 21rpx;
+					.dq_text{
+						background: #FFFFFF;
+						font-family: PingFang-SC, PingFang-SC;
+						font-weight: bold;
+						font-size: 26rpx;
+						color: #252525;
+						line-height: 37rpx;
+					}
+					.dp_type{
+						margin-top: 15rpx;
+						image{
+							width: 25rpx;
+							height: 30rpx;
+						}
+						span{
+							font-family: PingFang-SC, PingFang-SC;
+							font-weight: bold;
+							font-size: 24rpx;
+							color: #999999;
+							line-height: 33rpx;
+							margin-left: 5rpx;
+						}
+					}
+				}
+			}
 		}
-		
+	
 		.ask{
-			width: 100%;
-			height: 130rpx;
+			width: calc(100% - 60rpx);
+			height: 210rpx;
 			background: #FFFFFF;
-			padding: 21rpx 30rpx;
-			box-sizing: border-box;
+			border-radius: 24rpx;
+			border: 2rpx solid #F0F2F8;
 			position: fixed;
-			left: 0;
-			bottom: 172rpx;
-			z-index: 2;
-			.a_l{
-				width: calc(100% - 102rpx);
-				height: 88rpx;
-				padding: 20rpx 30rpx;
-				box-sizing: border-box;
-				border-radius: 44rpx;
-				border: 2rpx solid rgba(131,52,120,0.74);
-				input{
-					border: none;
-					font-family: PingFangSC, PingFang SC;
-					font-weight: 400;
-					font-size: 28rpx;
-					color: #252525;
-					line-height: 48rpx;
-					&::placeholder{
-						color: #808080;
+			left: 30rpx;
+			bottom: 72rpx;
+			display: flex;
+			flex-direction: column;
+			padding: 24rpx;
+			box-sizing: border-box;
+			.a_inp{
+				flex: 1;
+				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;
+						}
+					}
+				}
+				.ab_r{
+					image{
+						width: 48rpx;
+						height: 48rpx;
+						margin-left: 30rpx;
 					}
 				}
-			}
-			.a_r{
-				width: 72rpx;
-				height: 72rpx;
-				border-radius: 36rpx;
 			}
 		}
 	}

+ 118 - 0
pages/reportDetail.vue

@@ -0,0 +1,118 @@
+<template>
+	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
+		<cus-header title='报告详情'></cus-header>
+		<div class="pdf" :style="{'height':'calc(100vh - '+(mt+100)+'px)'}"
+			@touchstart.prevent="touchStart" @touchmove.prevent="touchMove" @touchend.prevent="touchEnd">
+			<div class="items" :style="{'transform':`translateX(${-(currentIndex * bl)}%)`,'transition':moveDistance !== 0 ? 'none' : 'transform 0.3s ease'}">
+				<div class="item" v-for="(item,index) in slides" :key="index">
+					<image :src="item" mode="widthFix" @touchstart="e=>touchStart2(e,item)" @touchend="touchEnd2"></image>
+				</div>
+			</div>
+		</div>
+		<div class="bottom">
+			<div class="zt_btn" @tap="askReport">对报告提问</div>
+		</div>
+	</view>
+</template>
+
+<script>
+	export default {
+		data(){
+			return {
+				pdfUrl:'',
+				slides:[],
+				startX: 0,
+				currentIndex: 0,
+				moveDistance: 0,
+				bl:0,
+				touchStartTime: 0,
+				longPressTimeout: null
+			}
+		},
+		onLoad(option) {
+			this.pdfUrl = option.pdfUrl;
+			this.getDetail(option.reportId);
+		},
+		methods:{
+			getDetail(reportId){
+				this.$api.get('/core/report/member/viewReport/'+reportId).then(res=>{
+					if(res.data.code!==0) return this.$showToast(res.data.msg)
+					this.slides = res.data.data;
+					this.bl = 100/res.data.data.length;
+				})
+			},
+			askReport(){
+				uni.navigateTo({
+					url:`/pages/reportAsk?pdf=${this.pdfUrl}`
+				})
+			},
+			touchStart(event) {
+			  this.startX = event.touches[0].clientX;
+			  this.moveDistance = 0;
+			},
+			touchMove(event) {
+			  const currentX = event.touches[0].clientX;
+			  this.moveDistance = currentX - this.startX;
+			},
+			touchEnd() {
+			  if (this.moveDistance > 50 && this.currentIndex > 0) {
+			    this.currentIndex--;
+			  } else if (this.moveDistance < -50 && this.currentIndex < this.slides.length - 1) {
+			    this.currentIndex++;
+			  }
+			  this.moveDistance = 0; // 重置移动距离
+			},
+			touchStart2(e,img) {
+			    this.touchStartTime = Date.now();
+			    this.longPressTimeout = setTimeout(() => {
+			        this.previewImage(img);
+			    }, 1000);
+			},
+			touchEnd2() {
+				clearTimeout(this.longPressTimeout);
+			},
+			previewImage(img) {
+				uni.previewImage({
+					urls: [img]
+				});
+			}
+		}
+	}
+</script>
+
+<style scoped lang="less">
+	.page{
+		padding: 0 24px 192rpx;
+		box-sizing: border-box;
+		background: #FFFFFF;
+		
+		.pdf{
+			width: 100%;
+			overflow-x: hidden;
+			position: relative;
+			.items{
+				display: flex;
+				width: fit-content; 
+				.item{
+					width: 702rpx;
+					flex: 1;
+					image{
+						width: 100%;
+					}
+				}
+			}
+		}
+		
+		.bottom{
+			width: 100%;
+			height: 172rpx;
+			background: #FFFFFF;
+			box-shadow: 0rpx -2rpx 8rpx 0rpx rgba(0,0,0,0.06);
+			padding: 34rpx 40rpx;
+			box-sizing: border-box;
+			position: fixed;
+			left: 0;
+			bottom: 0;
+		}
+	}
+</style>

BIN
static/pdf.png