shish 1 mesiac pred
rodič
commit
a10cb3f142
1 zmenil súbory, kde vykonal 303 pridanie a 292 odobranie
  1. 303 292
      hdApp/src/admin/ghs/pay.vue

+ 303 - 292
hdApp/src/admin/ghs/pay.vue

@@ -1,56 +1,68 @@
 <template>
-	<div class="app-content pay-wrap">
-		<div class="delivery-wrap">
-			<div class="shop-logo-wrap">
-				<div class="logo-img">
-					<image class="logo" :src="`${constant.imgUrl}/logo4.png`" alt mode="widthFix" ></image>
-					<div class="title">{{ ghsInfo.name?ghsInfo.name:'' }}</div>
-				</div>
-				<button class="admin-button-com middle" @click="goGathering">待结明细</button>
-			</div>
-			<div style="padding:10upx 0 25upx 10upx;font-size:30upx;">
-				{{ customInfo.name?customInfo.name:'' }},
-				<text v-if="customerOutstandingAmount(customInfo)>0">您待结款<text style="color:red;font-weight:bold;">{{ customerOutstandingAmount(customInfo) }}元</text>,这里付款结账</text>
+	<view class="app-content pay-wrap">
+		<view class="delivery-wrap">
+			<view class="shop-logo-wrap">
+				<view class="logo-img">
+					<image class="logo" :src="`${constant.imgUrl}/logo4.png`" mode="widthFix" />
+					<view class="title">{{ ghsName }}</view>
+				</view>
+				<button
+					v-if="id"
+					class="admin-button-com middle"
+					:disabled="ghsDataLoading"
+					@click="goGathering">
+					待结明细
+				</button>
+			</view>
+
+			<view v-if="ghsDataLoading" class="pay-tip pay-tip--loading">加载中...</view>
+			<view v-else-if="loadError" class="pay-tip pay-tip--error">{{ loadError }}</view>
+			<view v-else class="pay-tip">
+				{{ customName }},
+				<text v-if="hasOutstanding">
+					您待结款<text class="pay-tip__amount">{{ outstandingAmount }}元</text>,这里付款结账
+				</text>
 				<text v-else>您好,输入金额充值</text>
-			</div>
-			<div class="module-com pay-input-wrap">
-				<pay-input-module :focus="inpFocus" :num="amount" @focusFn="focusFn" @blurFn="blurFn" @clickKey="clickKeyFn" />
-			</div>
-			<div class="btn-wrap">
+			</view>
+
+			<view class="module-com pay-input-wrap">
+				<pay-input-module
+					:focus="inpFocus"
+					:num="amount"
+					@focusFn="focusFn"
+					@blurFn="blurFn"
+					@clickKey="clickKeyFn" />
+			</view>
+
+			<view class="btn-wrap">
 				<!-- #ifdef MP-WEIXIN -->
-				<button class="button-com green" @click="wexinPayFn">微信支付</button>
-				<div style="text-align:center;margin-top:10upx;">
-					<image :src="imgUrl" mode="widthFix" style="width:230upx;height:230upx;margin:0 auto;"></image>
-					<view style="margin-top:10upx;margin-bottom:10upx;font-size:32upx;">支付宝扫此二维码付款</view>
-					<button @click="downloadImg()" class="button-com blue" style="margin:0 auto;width:380upx;">保存二维码</button>
-					<div style="margin-top:58upx;font-size:30upx;text-decoration: underline;" @click="teachPayFn()">不会用支付宝付款?点这里教您</div>
-				</div>
+				<button class="button-com green" :disabled="ghsDataLoading || !!loadError" @click="wexinPayFn">微信支付</button>
+				<view class="ali-qrcode-wrap" v-if="imgUrl">
+					<image class="ali-qrcode-img" :src="imgUrl" mode="widthFix" />
+					<view class="ali-qrcode-tip">支付宝扫此二维码付款</view>
+					<button @click="downloadImg" class="button-com blue ali-qrcode-save">保存二维码</button>
+					<view class="ali-qrcode-teach" @click="teachPayFn">不会用支付宝付款?点这里教您</view>
+				</view>
 				<!-- #endif -->
 				<!-- #ifdef H5 -->
-				<button class="button-com red" @click="aliPayFn">支付宝支付</button>
+				<button class="button-com red" :disabled="ghsDataLoading || !!loadError" @click="aliPayFn">支付宝支付</button>
 				<!-- #endif -->
-			</div>
-		</div>
-	</div>
+			</view>
+		</view>
+	</view>
 </template>
 <script>
-	import { mapGetters } from 'vuex'
 	import PayInputModule from './components/pay-input'
 	import wexinPay from '@/utils/pay/wxPay'
-	import ModalModule from '@/components/plugin/modal'
-	import AppCouponSel from '@/components/app-coupon-sel'
 	import { share } from '@/mixins'
 	import { rechargeFn } from '@/api/custom-recharge'
 	import { getGhsData } from '@/api/ghs'
-	import { recharge } from '@/api/member'
-	import { getOrderShop } from '@/utils/config'
 	import { postWxCode } from '@/api/mini'
+
 	export default {
 		name: 'pay',
 		components: {
-			PayInputModule,
-			ModalModule,
-			AppCouponSel
+			PayInputModule
 		},
 		mixins: [share],
 		data() {
@@ -60,30 +72,27 @@
 				amount: '',
 				payWay: 0,
 				payCallData: null,
-				id:0,
-				salt:'',
-				ghsInfo:[],
-				customInfo:[],
-				imgUrl:'',
+				id: 0,
+				salt: '',
+				ghsInfo: {},
+				customInfo: {},
+				imgUrl: '',
 				ghsDataLoading: false,
-				ghsDataLoadedKey: ''
+				ghsDataLoadedKey: '',
+				loadError: '',
+				pageShowCount: 0
 			}
 		},
 		computed: {
-			...mapGetters({ orderShop: 'getOrderShop' }),
-			...mapGetters({ shopUser: 'getShopUser' })
-		},
-		onLoad() {
-			// H5 扫码付款页可能无门店登录态,globalMixins 不会调 init,此处补一次
-			// #ifdef H5
-			if (this.$util.isEmpty(this.getLoginInfo)) {
-				this.init()
-			}
-			// #endif
-		},
-		methods: {
-			// 客户待结金额:合并后净 balance 为负取绝对值(appVersion>=3)
-			customerOutstandingAmount(info) {
+			ghsName() {
+				return this.ghsInfo.name || ''
+			},
+			customName() {
+				return this.customInfo.name || ''
+			},
+			// 待结金额:净 balance 为负取绝对值(appVersion>=3)
+			outstandingAmount() {
+				const info = this.customInfo
 				if (!info || this.$util.isEmpty(info)) {
 					return 0
 				}
@@ -94,44 +103,37 @@
 				const remain = parseFloat(info.remainDebtAmount || 0)
 				return remain > 0 ? remain : 0
 			},
-			teachPayFn() {
-				this.pageTo({ url: "/admin/ghs/teachPay"})
-			},
-			// 跳转该供货商待结订单列表
-			goGathering() {
-				if (!this.id) {
-					this.$msg('供货商信息加载中,请稍后再试')
-					return
-				}
-				this.pageTo({ url: `/pagesPurchase/gathering?id=${this.id}` ,type:2})
-			},
-			downloadImg(){
-				let that = this
-				uni.downloadFile({
-					url:that.imgUrl,
-					success: (res) => {
-						if (res.statusCode === 200) {
-							uni.saveImageToPhotosAlbum({
-							filePath: res.tempFilePath,
-							success: function (data) {
-								uni.showToast({title:'下载成功'})
-							}
-							});
-						}
-					}
-				});
-			},
+			hasOutstanding() {
+				return this.outstandingAmount > 0
+			}
+		},
+		onLoad() {
+			// H5 扫码付款页可能无门店登录态,globalMixins 不会调 init,此处补一次
+			// #ifdef H5
+			if (this.$util.isEmpty(this.getLoginInfo)) {
+				this.init()
+			}
+			// #endif
+		},
+		onShow() {
+			this.pageShowCount += 1
+			// 从待结明细/教程等子页返回时刷新账户待结金额
+			if (this.pageShowCount > 1 && this.id && this.salt) {
+				this.loadGhsData(true)
+			}
+		},
+		methods: {
 			init() {
-				this.specialInit()
+				this.loadGhsData(false)
 			},
-			// 解析路由参数(id/salt/amount),供 init 与分享配置使用
+			// 解析路由参数 id/salt
 			parsePayPageParams() {
 				let id = 0
 				let salt = ''
 				const option = this.option || {}
 				if (option.id && option.salt) {
-					id = option.id ? option.id : 0
-					salt = option.salt ? option.salt : ''
+					id = option.id || 0
+					salt = option.salt || ''
 				} else if (option.q) {
 					const currentUrl = decodeURIComponent(option.q)
 					const str = currentUrl.substring(currentUrl.lastIndexOf('?') + 1)
@@ -150,85 +152,103 @@
 				}
 				return { id, salt }
 			},
-			specialInit() {
-				const that = this
+			/**
+			 * 拉取供货商/客户待结信息
+			 * @param {boolean} force 是否强制刷新(跳过已加载缓存)
+			 */
+			loadGhsData(force) {
 				const { id, salt } = this.parsePayPageParams()
 				this.id = id
 				this.salt = salt
 				if (!id || !salt) {
+					this.loadError = '付款链接无效,请重新扫码'
 					return
 				}
 				if (this.option.amount && Number(this.option.amount) > 0) {
-					that.amount = parseFloat(Number(this.option.amount).toFixed(2))
+					this.amount = parseFloat(Number(this.option.amount).toFixed(2))
 				}
+
 				const reqKey = `${id}_${salt}`
-				// 防止 onShow + globalMixins.init 等重复触发同一请求
 				if (this.ghsDataLoading && this.ghsDataLoadedKey === reqKey) {
 					return
 				}
-				if (this.ghsDataLoadedKey === reqKey && !this.$util.isEmpty(this.ghsInfo)) {
+				if (!force && this.ghsDataLoadedKey === reqKey && !this.$util.isEmpty(this.ghsInfo)) {
 					this.setupPayPageUi()
 					return
 				}
+
 				this.ghsDataLoading = true
 				this.ghsDataLoadedKey = reqKey
+				this.loadError = ''
 				getGhsData({ id, salt }).then(res => {
-					if (res.code == 1) {
-						if (res.data && res.data.ghs && !this.$util.isEmpty(res.data.ghs)) {
-							that.ghsInfo = res.data.ghs
-							that.customInfo = res.data.custom ? res.data.custom : []
-							if (!(that.option.amount && Number(that.option.amount) > 0)) {
-								const outstanding = that.customerOutstandingAmount(that.customInfo)
-								if (outstanding > 0) {
-									that.amount = parseFloat(outstanding.toFixed(2))
-								}
-							}
-							that.imgUrl = res.data.imgUrl ? res.data.imgUrl : ''
-						}
+					if (res.code !== 1 || !res.data || !res.data.ghs || this.$util.isEmpty(res.data.ghs)) {
+						this.loadError = res.msg || '加载供货商信息失败'
+						return
 					}
+					this.ghsInfo = res.data.ghs
+					this.customInfo = res.data.custom || {}
+					this.imgUrl = res.data.imgUrl || ''
+					if (!(this.option.amount && Number(this.option.amount) > 0) && this.hasOutstanding) {
+						this.amount = parseFloat(this.outstandingAmount.toFixed(2))
+					}
+				}).catch(() => {
+					this.loadError = '网络异常,请稍后重试'
 				}).finally(() => {
-					that.ghsDataLoading = false
+					this.ghsDataLoading = false
+					this.setupPayPageUi()
 				})
-
-				this.setupPayPageUi()
 			},
 			setupPayPageUi() {
+				if (this.loadError) {
+					return
+				}
 				this.inpFocus = true
 				// #ifdef MP-WEIXIN
-				const shareParams = {
+				this.jweixinFn({
 					title: '点击结账付款',
 					desc: '',
 					imgUrl: '',
 					pagePath: `/admin/ghs/pay?id=${this.id}&salt=${this.salt}`
-				}
-				this.jweixinFn(shareParams)
+				})
 				// #endif
 			},
+			validatePayAmount() {
+				const amount = parseFloat(this.amount)
+				if (!this.amount || isNaN(amount) || amount <= 0) {
+					this.$msg('请输入大于 0 的金额')
+					return false
+				}
+				if (amount > 9999999) {
+					this.$msg('金额过大,请重新输入')
+					return false
+				}
+				return true
+			},
 			toPay() {
-				if (!this.amount) {
-					this.$msg('请先输入金额!')
+				if (!this.validatePayAmount()) {
+					return false
+				}
+				if (this.loadError || this.ghsDataLoading) {
+					this.$msg('页面信息加载中,请稍后再试')
 					return false
 				}
-				let params = {}
-				params = {
+				const params = {
 					actPrice: this.amount,
 					payWay: this.payWay,
+					currentMiniOpenId: uni.getStorageSync('currentMiniOpenId'),
+					ghsId: this.id,
+					salt: this.salt
 				}
-				let currentMiniOpenId = uni.getStorageSync('currentMiniOpenId')
-				params.currentMiniOpenId = currentMiniOpenId
-				params.ghsId = this.id
-				params.salt = this.salt
 				rechargeFn(params).then(res => {
 					this.payCallData = res.data
-					//错误返回判断
-					if(res.code == 0){
+					if (res.code === 0) {
 						this.$msg(res.msg)
 						return false
 					}
-					if (this.payWay == 0) {
+					if (this.payWay === 0) {
 						wexinPay(res.data, this.paySuccess, this.payFail)
-					} else if (this.payWay == 1) {
-						window.location.href = res.data.url;
+					} else if (this.payWay === 1) {
+						window.location.href = res.data.url
 					} else {
 						this.paySuccess()
 					}
@@ -237,49 +257,87 @@
 			focusFn() {
 				this.inpFocus = true
 			},
-			// 失焦
 			blurFn() {
 				this.inpFocus = false
 			},
-			// 点击键盘
 			clickKeyFn(val) {
 				this.amount = val
 			},
-			// 支付宝支付
 			aliPayFn() {
 				this.payWay = 1
 				this.toPay()
 			},
-			// 微信支付
 			wexinPayFn() {
-
-				let platformType = uni.getSystemInfoSync().platform
-				if(platformType == 'windows'){
+				const platformType = uni.getSystemInfoSync().platform
+				if (platformType === 'windows') {
 					this.$msg('请使用手机小程序付款')
 					return false
 				}
-
 				this.payWay = 0
-				let that = this
-				let currentMiniOpenId = uni.getStorageSync('currentMiniOpenId')
-				if (this.$util.isEmpty(currentMiniOpenId)){
-					uni.showLoading({mask:true})
+				const currentMiniOpenId = uni.getStorageSync('currentMiniOpenId')
+				if (this.$util.isEmpty(currentMiniOpenId)) {
+					uni.showLoading({ mask: true })
 					uni.login({
 						provider: 'weixin',
 						success: res => {
-						postWxCode({ code: res.code }).then(subRes => {
+							postWxCode({ code: res.code }).then(subRes => {
+								uni.hideLoading()
+								if (subRes.data && subRes.data.currentMiniOpenId) {
+									uni.setStorageSync('currentMiniOpenId', subRes.data.currentMiniOpenId)
+									this.toPay()
+								} else {
+									this.$msg('微信授权失败,请重试')
+								}
+							}).catch(() => {
+								uni.hideLoading()
+								this.$msg('微信授权失败,请重试')
+							})
+						},
+						fail: () => {
 							uni.hideLoading()
-							if(subRes.data.currentMiniOpenId){
-								let thisMiniOpenId = subRes.data.currentMiniOpenId
-								uni.setStorageSync('currentMiniOpenId',thisMiniOpenId)
-								that.toPay()
-							}
-						})
+							this.$msg('微信登录失败,请重试')
 						}
 					})
-				}else{
-					that.toPay()
-				}				
+					return
+				}
+				this.toPay()
+			},
+			teachPayFn() {
+				this.pageTo({ url: '/admin/ghs/teachPay' })
+			},
+			goGathering() {
+				if (!this.id) {
+					this.$msg('供货商信息加载中,请稍后再试')
+					return
+				}
+				this.pageTo({ url: `/pagesPurchase/gathering?id=${this.id}`, type: 2 })
+			},
+			downloadImg() {
+				if (!this.imgUrl) {
+					this.$msg('二维码加载中,请稍后再试')
+					return
+				}
+				uni.downloadFile({
+					url: this.imgUrl,
+					success: res => {
+						if (res.statusCode !== 200) {
+							this.$msg('下载失败,请重试')
+							return
+						}
+						uni.saveImageToPhotosAlbum({
+							filePath: res.tempFilePath,
+							success: () => {
+								uni.showToast({ title: '下载成功' })
+							},
+							fail: () => {
+								this.$msg('保存失败,请检查相册权限')
+							}
+						})
+					},
+					fail: () => {
+						this.$msg('下载失败,请检查网络')
+					}
+				})
 			},
 			paySuccess() {
 				if (this.option.from === 'wechatPay' && this.option.purchaseId) {
@@ -287,10 +345,13 @@
 					uni.navigateBack({ delta: 1 })
 					return
 				}
-				this.$util.pageTo({url: '/admin/ghs/result?id='+this.id+'&salt='+this.salt,type: 2})
+				this.$util.pageTo({
+					url: `/admin/ghs/result?id=${this.id}&salt=${this.salt}`,
+					type: 2
+				})
 			},
 			payFail() {
-			
+				this.$msg('支付未完成,请重试')
 			}
 		}
 	}
@@ -301,169 +362,119 @@
 		min-height: calc(100vh - 20upx);
 		padding-top: 20upx;
 	}
-	.tabs-wrap {
-		position: fixed;
-		top: 0;
-		width: 100%;
-		height: 80upx;
-		line-height: 80upx;
-		text-align: center;
-		background-color: #fff;
-		font-size: 30upx;
-		box-shadow: 4upx 4upx 10upx #eee;
-	}
-	.pay-wrap {
-		.pay-input-wrap {
-			background-color: #fff;
-			border-top-left-radius: 20upx;
-			border-top-right-radius: 20upx;
-			padding: 50upx 80upx 28upx;
-			margin-bottom: 0 !important;
-			.balance {
-				margin-top: 30upx;
-				color: $fontColor2;
-			}
-			.btn-wrap {
-				width: 100%;
-				margin-top: 64upx;
-				.button-com {
-					display: block;
-					margin-bottom: 20upx;
-					padding-top: 30upx;
-					padding-bottom: 30upx;
-				}
-			}
-		}
-	}
 
-	// 我要配送
-	.delivery-wrap {
-		.module-com {
-			margin-bottom: 20upx;
-			background-color: #fff;
-			.module-tit {
-				padding: 20upx 18upx;
-				font-size: 28upx;
-				font-weight: 600;
-				border-bottom: 1upx solid $borderColor;
-			}
-			.module-det {
-				padding: 0 30upx;
-			}
-		}
-		// 金额
-		.pay-input-wrap {
-			padding: 50upx 36upx 38upx;
-			.balance {
-				margin-top: 30upx;
-				color: $fontColor2;
-			}
-		}
-		.shop-logo-wrap {
-			padding: 10upx 20upx 20upx;
-			display: flex;
-			flex-direction: row;
-			align-items: center;
-			justify-content: space-between;
-			.logo-img {
-				flex: 1;
-				min-width: 0;
+	.pay-wrap {
+		.delivery-wrap {
+			.shop-logo-wrap {
+				padding: 10upx 20upx 20upx;
 				display: flex;
 				flex-direction: row;
 				align-items: center;
-				.logo {
-					width: 50upx;
-					height: 50upx;
-					border-radius: 5upx;
-					flex-shrink: 0;
+				justify-content: space-between;
+
+				.logo-img {
+					flex: 1;
+					min-width: 0;
+					display: flex;
+					flex-direction: row;
+					align-items: center;
+
+					.logo {
+						width: 50upx;
+						height: 50upx;
+						border-radius: 5upx;
+						flex-shrink: 0;
+					}
+
+					.title {
+						margin-left: 20upx;
+						height: 50upx;
+						line-height: 50upx;
+						font-size: 38upx;
+						font-weight: bold;
+						overflow: hidden;
+						text-overflow: ellipsis;
+						white-space: nowrap;
+					}
 				}
-				.title {
+
+				.admin-button-com {
+					flex-shrink: 0;
 					margin-left: 20upx;
-					height: 50upx;
-					line-height: 50upx;
-					font-size: 38upx;
+				}
+			}
+
+			.pay-tip {
+				padding: 10upx 0 25upx 10upx;
+				font-size: 30upx;
+
+				&--loading {
+					color: $fontColor2;
+				}
+
+				&--error {
+					color: #e64340;
+				}
+
+				&__amount {
+					color: red;
 					font-weight: bold;
-					overflow: hidden;
-					text-overflow: ellipsis;
-					white-space: nowrap;
 				}
 			}
-			.admin-button-com {
-				flex-shrink: 0;
-				margin-left: 20upx;
+
+			.pay-input-wrap {
+				background-color: #fff;
+				border-top-left-radius: 20upx;
+				border-top-right-radius: 20upx;
+				padding: 50upx 36upx 38upx;
+				margin-bottom: 0;
 			}
-		}
-		// 可选优惠
-		.discount-wrap {
-			.module-det {
-				padding-top: 20upx;
+
+			.btn-wrap {
+				width: calc(100% - 60upx);
+				margin: 64upx auto 0;
 				padding-bottom: 20upx;
-			}
-		}
-		// 匿名派送
-		.none-name-delivery {
-			// padding-left: 30upx;
-			padding: 26upx 30upx;
-			// margin-top: 40upx;
-			margin-bottom: 20upx;
-			background-color: #fff;
-			.none-name-text {
-				margin-left: 14upx;
-				color: $fontColor2;
-			}
-		}
-		// 按钮
-		.btn-wrap {
-			width: calc(100% - 60upx);
-			margin: 64upx auto 0;
-			padding-bottom: 20upx;
-			.button-com {
-				display: block;
-				margin-bottom: 20upx;
-				padding-top: 30upx;
-				padding-bottom: 30upx;
-				&:last-child {
-					margin-bottom: 0;
+
+				.button-com {
+					display: block;
+					margin-bottom: 20upx;
+					padding-top: 30upx;
+					padding-bottom: 30upx;
+
+					&:last-child {
+						margin-bottom: 0;
+					}
 				}
 			}
-		}
 
-		// 查看更多
-		.view-more {
-			width: auto;
-			padding-bottom: 20upx;
-			margin-bottom: 20upx;
-			font-size: 28upx;
-			@include disFlex(center, center);
-			background-color: #fff;
-			color: #666565;
-			justify-content: flex-start;
-			z-index:9999999;
-			.view-more-text {
-				margin-right: 14upx;
+			.ali-qrcode-wrap {
+				text-align: center;
+				margin-top: 10upx;
 			}
-			padding-left:40upx;
-			i {
-				font-size: 30upx;
-				font-weight: 600;
+
+			.ali-qrcode-img {
+				width: 230upx;
+				height: 230upx;
+				margin: 0 auto;
+				display: block;
 			}
-			.fill-get-man{
-				color:red;
-				margin-left:10upx;
-				font-weight:600;
-				text-decoration:underline;
+
+			.ali-qrcode-tip {
+				margin-top: 10upx;
+				margin-bottom: 10upx;
+				font-size: 32upx;
 			}
-			.pack-up{
-				margin-left:20upx;
-				font-weight:600;
-				color:red;
-				text-decoration:underline;
+
+			.ali-qrcode-save {
+				margin: 0 auto;
+				width: 380upx;
 			}
-			&.open {
-				i {
-					transform: rotate(180deg);
-				}
+
+			.ali-qrcode-teach {
+				margin-top: 58upx;
+				font-size: 30upx;
+				text-decoration: underline;
 			}
 		}
 	}
-</style>
+</style>