hmp 4 ani în urmă
părinte
comite
c43543d15a
4 a modificat fișierele cu 345 adăugiri și 37 ștergeri
  1. 8 1
      assets/http/api.js
  2. 9 0
      assets/http/global.js
  3. 39 36
      pages.json
  4. 289 0
      pages/checkstand/pay-qrcode1.vue

+ 8 - 1
assets/http/api.js

@@ -88,6 +88,12 @@ const account = {
 	remainList:p => http.get('cyzh-ldt/loginuser/remaining/list',{params:p}),
 }
 
+//webSocket
+const webSocket={
+	sendInfo:p => http.post('cyzh-ldt/webSocket/sendInfo',p),
+}
+
+
 export const api={
 	wxApp,
 	dict,
@@ -102,5 +108,6 @@ export const api={
 	pay,
 	billRecord,
 	setting,
-	account
+	account,
+	webSocket
 }

+ 9 - 0
assets/http/global.js

@@ -3,6 +3,10 @@ let global = {}
 // global.baseUrl='http://192.168.1.244:1888/api/'
 global.baseUrl='https://ldt.guosen-fumao.cn/api/'
 
+// global.baseUrl='http://localhost:2539/'
+
+global.WebSocketUrl='ws://ldt.guosen-fumao.cn/websocket/'
+
 global.tokenUrl=global.baseUrl+ 'blade-auth/oauth/token?tenantId=000000&password=f67e0b29283bb804f96e28f43ddce79f&username=admin'
 
 global.agenterTypeId='1423464045809364994'
@@ -28,6 +32,11 @@ global.APPID={
 	didi:'wxaf35009675aa0b2a',//滴滴出行
 }
 
+//webSocket 收到服务端的信息
+global.socketMessage={
+	payForPaymentCode:'用户通过付款码付款',//商家扫描用户的付款码支付
+}
+
 
 global.TRANSFORM_PARAMS='95963'
 

+ 39 - 36
pages.json

@@ -80,7 +80,7 @@
 		}, {
 			"path": "pages/checkstand/index",
 			"style": {
-				"navigationStyle":"custom",
+				"navigationStyle": "custom",
 				"navigationBarTitleText": "收银台",
 				"enablePullDownRefresh": false
 			}
@@ -190,44 +190,47 @@
 				"navigationBarTitleText": "问题反馈",
 				"enablePullDownRefresh": false
 			}
-		}
-        ,{
-            "path" : "pages/consume/detail/shop-detail",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "商户详情",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/gain/test",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "test",
-                "enablePullDownRefresh": false
-            }
-            
-        },
+		}, {
+			"path": "pages/consume/detail/shop-detail",
+			"style": {
+				"navigationBarTitleText": "商户详情",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/gain/test",
+			"style": {
+				"navigationBarTitleText": "test",
+				"enablePullDownRefresh": false
+			}
+
+		},
 		{
-		    "path" : "pages/activity/activity",
-		    "style" :                                                                                    
-		    {
-		        "navigationBarTitleText": "活动列表",
-		        "enablePullDownRefresh": false
-		    }
-		    
-		},{
-		    "path" : "pages/activity/detail",
-		    "style" :                                                                                    
-		    {
-		        "navigationBarTitleText": "活动详情",
-		        "enablePullDownRefresh": false,
+			"path": "pages/activity/activity",
+			"style": {
+				"navigationBarTitleText": "活动列表",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/activity/detail",
+			"style": {
+				"navigationBarTitleText": "活动详情",
+				"enablePullDownRefresh": false,
 				"navigationStyle": "custom"
-		    }
-		    
+			}
+
+		}, {
+			"path": "pages/checkstand/pay-qrcode1",
+			"style": {
+				"navigationBarTitleText": "付款码",
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#18b566",
+				"enablePullDownRefresh": false
+			}
+
 		}
-    ],
+	],
 	"tabBar": {
 		"color": "#555555",
 		"backgroundColor": "#FFFFFF",

+ 289 - 0
pages/checkstand/pay-qrcode1.vue

@@ -0,0 +1,289 @@
+<template>
+	<view class="code-container">
+		<view class="title center">{{isPayment? "向商家付款":"扫一扫,向我付款"}}</view>
+		<view class="main-content">
+			<view v-if="isPayment">
+				<!-- 占位 -->
+				<view style="height: 50rpx;"></view>
+				<!-- 条形码 -->
+				<view class="bar-code center">
+					<tki-barcode ref="barcode" :val="content" onval=true :opations="barOption" />
+				</view>
+				<!-- 付款码 -->
+				<view class="qr-code center">
+					<tki-qrcode cid="2" ref="qrcode" :val="content" size="300" :onval="true" :loadMake="true"
+						:usingComponents="true" />
+				</view>
+			</view>
+			<!-- 收款码 -->
+			<view v-else class="charge-code center">
+				<tki-qrcode cid="1" ref="qrcode-charge" :val="id" :icon="avatar" size="440" :onval="true"
+					:loadMake="true" :usingComponents="true" />
+			</view>
+		</view>
+		<view class="footer center">
+			<text class="text-xl text-bold">{{nickName}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import tkiQrcode from "tki-qrcode"
+	import tkiBarcode from "@/components/tki-barcode/tki-barcode.vue"
+	import totp from "@/utils/totp.js"
+	export default {
+		components: {
+			tkiBarcode,
+			tkiQrcode
+		},
+		computed: {
+			content() {
+				let transformStr = this.id
+				return transformStr + this.secret
+			}
+		},
+		data() {
+			return {
+				id: '',
+				avatar: "",
+				nickName:'',
+				secret: '000000',
+				isPayment: true,
+				timer: '',
+				timerBillRecords:null,
+				barOption: {
+					width: 3,
+					height: 130,
+					displayValue: false
+				},
+				
+				//webSocket
+				connected: false,
+				connecting: false,
+				socketTask: false,
+				msg: false,
+			}
+		},
+		async onLoad(options) {
+			let res = await this.$api.loginUser.detail({
+				id: this.vuex_userId
+			})
+			this.nickName=res.data.nickName
+			// this.avatar =(await  this.initAvatat(res.data.avatar)).tempFilePath;
+			//清除缓存
+			await this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
+			//连接websocket
+			this.connect()
+		},
+		async mounted() {
+			//获取用户ID
+			this.id = this.vuex_userId
+			//生成动态密码
+			this.refreshCode();
+		},
+		onUnload() {
+		    uni.hideLoading()
+			if (this.socketTask && this.socketTask.close) {
+				this.socketTask.close()
+			}
+		},
+		beforeDestroy() {
+			clearInterval(this.timer);
+			clearInterval(this.timerBillRecords);
+			uni.hideLoading()
+		},
+		methods: {
+			refreshCode() {
+				this.timer = setInterval(() => {
+					this.secret = totp.getSecret(this.id);
+				}, 1000)
+			},
+			async initAvatat(url) {
+				return new Promise((reslove, reject) => {
+					uni.downloadFile({
+						url,
+						success: (res) => {
+							reslove(res);
+						},
+						fail: (err) => {
+							reject(err)
+						}
+					})
+				})
+			},
+			async queryBillRecords(){
+				let resp=await this.$api.loginUser.getBillrecordFromRedis({userId:this.vuex_userId})
+				if (this.$isEmpty(resp.data)) {
+					return
+				}
+				if (resp.data.realPayAmount>0) {
+					//清除轮询
+					clearInterval(this.timerBillRecords)
+					//关闭通讯
+					this.close()
+					//去支付
+					let params={
+						orderType:this.$global.orderType.USER_PAY,
+						orderId:resp.data.id,
+						payStatus:this.$global.payStatus.IS_WAIT
+					}
+					let res=await this.$api.pay.payOrder(params)
+					if (!this.$isEmpty(res.data.prePayTn)) {
+						let prePayTn= JSON.parse(res.data.prePayTn)
+						this.$mpi.requestPayment(prePayTn).then(()=>{
+							//通知商户端付款成功
+							this.sendInfo(resp.data)
+							this.$dialog.showModal('支付成功',false).then(()=>{
+								this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
+								uni.navigateBack({
+									delta:1
+								})
+							})
+						}).catch(err=>{
+							this.$dialog.showModal('支付失败',false).then(()=>{
+								this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
+								uni.navigateBack({
+									delta:1
+								})
+							})
+						})
+						return
+					}
+					this.$dialog.showModal('支付失败',false).then(()=>{
+						this.$api.loginUser.clearBillRecordCache({userId:this.vuex_userId})
+						uni.navigateBack({
+							delta:1
+						})
+					})
+				}
+			},
+			connect() {
+				if (this.connected || this.connecting) {
+					return false
+				}
+				this.connecting = true
+				this.socketTask = uni.connectSocket({
+					url: this.$global.WebSocketUrl+this.vuex_userId,
+					// #ifdef MP
+					header: {
+						'content-type': 'application/json'
+					},
+					// #endif
+					// #ifdef MP-WEIXIN
+					method: 'GET',
+					// #endif
+					success(res) {
+						console.log(res);
+					},
+					fail(err) {
+						console.log(err);
+					}
+				})
+				this.socketTask.onOpen((res) => {
+					this.connecting = false
+					this.connected = true
+					console.log('onOpen', res);
+					//连接成功,清除轮询
+					clearInterval(this.timerBillRecords)
+				})
+				this.socketTask.onError((err) => {
+					this.connecting = false
+					this.connected = false
+					//连接失败就轮询查询订单
+					 this.timerBillRecords =  setInterval(this.queryBillRecords,5000);
+				})
+				this.socketTask.onMessage((res) => {
+					this.msg= JSON.parse(res.data)
+					if (this.msg.content==this.$global.socketMessage.payForPaymentCode) {
+						this.queryBillRecords()
+					}
+				})
+				this.socketTask.onClose((res) => {
+					this.connected = false
+					this.socketTask = false
+					this.msg = false
+					console.log('onClose', res)
+				})
+			},
+			send(data) {
+				this.socketTask.send({
+					data: JSON.stringify(data),
+					success(res) {
+						console.log(res);
+					},
+					fail(err) {
+						console.log(err);
+					}
+				})
+			},
+			close() {
+				if (this.socketTask && this.socketTask.close) {
+					this.socketTask.close()
+				}
+			},
+			sendInfo(data){
+				let msg={
+					sid:data.shopId,
+					content:"账户到账"+data.payAmount,
+				}
+				this.$api.webSocket.sendInfo(msg)
+			},
+		},
+	}
+</script>
+
+<style>
+	page {
+		background-color: #18b566;
+	}
+</style>
+<style lang="scss" scoped>
+	.code-container {
+		background-color: #FFFFFF;
+		border-radius: 16rpx;
+		min-height: 800rpx;
+		margin: 60rpx 20rpx;
+
+		.title {
+			border-radius: 25rpx 25rpx 0 0;
+			height: 100rpx;
+			width: 100%;
+			font-size: 35rpx;
+			color: #18b566;
+			background-color: #F7F7F7;
+			font-weight: 600;
+			letter-spacing: 3rpx;
+		}
+
+		.footer {
+			width: 90%;
+			height: 160rpx;
+			margin-left: 5%;
+			border-top: 1rpx dashed #dddddd;
+		}
+
+		.main-content {
+			width: 100%;
+			height: 600rpx;
+			scroll-margin-top: 600rpx;
+
+			// overflow: hidden;
+			.bar-code {
+				margin-left: 5%;
+				width: 90%;
+				height: 150rpx;
+			}
+
+			.qr-code {
+				width: 100%;
+				height: 450rpx;
+			}
+
+			.charge-code {
+				width: 100%;
+				height: 600rpx;
+				transition: transform 1s ease-in-out;
+			}
+		}
+	}
+</style>