Browse Source

扫码付款

shish 2 weeks ago
parent
commit
c3b7b183df
2 changed files with 192 additions and 23 deletions
  1. 60 18
      ghsPad/src/pages/home/components/toPay.vue
  2. 132 5
      hdPad/src/pages/home/components/toPay.vue

+ 60 - 18
ghsPad/src/pages/home/components/toPay.vue

@@ -23,13 +23,13 @@
                         v-model="manualAuthCode"
                         type="number"
                         maxlength="32"
-                        placeholder="请输入付款码"
+                        placeholder="请输入或扫描付款码"
                         :focus="manualInputFocus"
                         @confirm="submitManualCode"
                     />
                     <view class="manual-code-actions">
-                        <view class="btn-default" @click="closeManualInput">返回</view>
-                        <view class="btn-default btn-primary" @click="submitManualCode">确认支付</view>
+                        <view class="manual-btn" @click="closeManualInput">返回</view>
+                        <view class="manual-btn manual-btn-primary" @click="submitManualCode">确认支付</view>
                     </view>
                 </view>
                 <view class="paying" v-if="goPay == 1">请求中</view>
@@ -82,7 +82,7 @@
 <script>
 /**
  * 扫码支付组件(供货商收银机端)
- * 支持扫码与手动输入付款码,解决客户扫码后转圈状态被卡住、钱未到账的问题,支持网络异常降级和自动后台复查
+ * 支持手动输入与扫码填入付款码后确认提交,解决客户扫码后转圈状态被卡住、钱未到账的问题,支持网络异常降级和自动后台复查
  */
 import { codePay,codePayCheck,codePayVerify,cancelOrderFn,getDetail} from "@/api/order";
 export default {
@@ -130,7 +130,7 @@ export default {
 		//避免重复,每次进来先移除全局自定义事件监听器
         uni.$off('listenGetScanCode')
         uni.$on('listenGetScanCode',function(data){
-			that.requestCodePay(data.code)
+			that.fillAuthCodeFromScan(data.code)
         })
 	},
     beforeDestroy(){
@@ -144,7 +144,7 @@ export default {
             uni.scanCode({
                 onlyFromCamera: true,
                 success: function (res) {
-                    that.requestCodePay(res.result)
+                    that.fillAuthCodeFromScan(res.result)
                 }
             })
         },
@@ -168,7 +168,7 @@ export default {
             })
         },
         /**
-         * 关闭手动输入付款码区域
+         * 关闭付款码输入区域
          */
         closeManualInput(){
             this.showManualInput = false
@@ -176,7 +176,35 @@ export default {
             this.manualInputFocus = false
         },
         /**
-         * 提交手动输入的付款码
+         * 处理扫码:未展开输入框时自动提交,已展开时仅填入等待确认
+         * @param {string} rawCode - 扫码原始内容
+         */
+        fillAuthCodeFromScan(rawCode){
+            if(this.isCancelDialogOpen || this.isCloseDialogOpen){
+                this.$msg('请先完成当前操作')
+                return
+            }
+            if(this.isPaymentProcessing){
+                this.$msg('支付处理中,请稍候')
+                return
+            }
+            const authCode = String(rawCode || '').replace(/\s+/g, '')
+            if(!authCode){
+                return
+            }
+            if(this.showManualInput){
+                this.clearPolling()
+                this.remindText = ''
+                this.returnCode = ''
+                this.goPay = 0
+                this.manualAuthCode = authCode
+                this.manualInputFocus = false
+                return
+            }
+            this.requestCodePay(authCode)
+        },
+        /**
+         * 确认提交输入框中的付款码
          */
         submitManualCode(){
             const authCode = String(this.manualAuthCode || '').replace(/\s+/g, '')
@@ -236,6 +264,7 @@ export default {
                 if(res.code == 1){
                     if(res.data.returnStatus == 'SUCCESS'){
                         that.isPaymentProcessing = false
+                        that.closeManualInput()
                         that.showSuccess = true
                         setTimeout(function(){
                             that.payFinish()
@@ -435,13 +464,16 @@ export default {
             color: #3385ff;
         }
         & .manual-code-box{
-            width: 90%;
+            width: 100%;
             margin: 10upx auto 0 auto;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
         }
         & .manual-code-input{
-            width: 100%;
-            height: 60upx;
-            line-height: 60upx;
+            width: 50%;
+            height: 40upx;
+            line-height: 40upx;
             border: 1upx solid #cccccc;
             border-radius: 8upx;
             font-size: 20upx;
@@ -451,18 +483,28 @@ export default {
             box-sizing: border-box;
         }
         & .manual-code-actions{
-            margin-top: 15upx;
+            margin-top: 12upx;
             display: flex;
             justify-content: center;
             align-items: center;
         }
-        & .manual-code-actions .btn-default{
-            margin-left: 0;
+        & .manual-btn{
+            height: 44upx;
+            min-width: 88upx;
+            padding: 0 16upx;
+            text-align: center;
+            line-height: 44upx;
+            border: 1upx solid #dddddd;
+            border-radius: 22upx;
+            font-size: 14upx;
+            color: #666666;
+            background-color: #ffffff;
+            box-sizing: border-box;
         }
-        & .manual-code-actions .btn-default + .btn-default{
-            margin-left: 20upx;
+        & .manual-btn + .manual-btn{
+            margin-left: 16upx;
         }
-        & .btn-primary{
+        & .manual-btn-primary{
             background-color: #3385ff;
             color: #ffffff;
             border-color: #3385ff;

+ 132 - 5
hdPad/src/pages/home/components/toPay.vue

@@ -5,7 +5,22 @@
             <view class="collect-code_box">
                 <image class="img" :src="`${constant.imgUrl}/icon/scan/scan.png`" mode="scaleToFill" @click="beginScan()" />
                 <view style="margin-top:20upx;font-weight:bold;font-size:35upx;color:black;">¥{{price}}</view>
-                <view class="show-code" v-if="goPay == 0">请出示付款码</view>
+                <view class="show-code" v-if="goPay == 0 && !showManualInput" @click="openManualInput">请出示付款码</view>
+                <view class="manual-code-box" v-if="goPay == 0 && showManualInput">
+                    <input
+                        class="manual-code-input"
+                        v-model="manualAuthCode"
+                        type="number"
+                        maxlength="32"
+                        placeholder="请输入或扫描付款码"
+                        :focus="manualInputFocus"
+                        @confirm="submitManualCode"
+                    />
+                    <view class="manual-code-actions">
+                        <view class="manual-btn" @click="closeManualInput">返回</view>
+                        <view class="manual-btn manual-btn-primary" @click="submitManualCode">确认支付</view>
+                    </view>
+                </view>
                 <view class="paying" v-if="goPay == 1">请求中</view>
                 <view style="font-size:18upx;margin:8upx auto;color:red;font-weight:bold;text-align:center;" v-if="goPay == 2">
                     <view style="font-size:16upx;line-height:1.3;max-width:90%;margin:0 auto;">{{ remindText }}</view>
@@ -56,7 +71,7 @@
 <script>
 /**
  * 扫码支付组件(零售花店收银机端)
- * 解决扫码时转圈状态被卡住、钱未到账的问题,支持网络异常降级和后台复查
+ * 支持手动输入与扫码填入付款码后确认提交,解决扫码时转圈状态被卡住、钱未到账的问题
  */
 import { codePay,codePayCheck,codePayVerify,cancelOrderFn,getDetail} from "@/api/order";
 export default {
@@ -75,7 +90,10 @@ export default {
             isCloseDialogOpen:false, // 关闭确认弹框是否打开
             isPaymentProcessing:false, // 标志位:防重复扫码
             pollingTimer:null, // 后台轮询复查定时器
-            pollingCount:0 // 轮询计数器
+            pollingCount:0, // 轮询计数器
+            showManualInput:false, // 是否展示付款码输入区域
+            manualAuthCode:'', // 手动输入或扫码填入的付款码
+            manualInputFocus:false // 控制输入框自动聚焦
         }
     },
 	props: {
@@ -93,7 +111,7 @@ export default {
 		//避免重复,每次进来先移除全局自定义事件监听器
         uni.$off('listenGetScanCode')
         uni.$on('listenGetScanCode',function(data){
-			that.requestCodePay(data.code)
+			that.fillAuthCodeFromScan(data.code)
         })
 	},
     beforeDestroy(){
@@ -107,7 +125,7 @@ export default {
             uni.scanCode({
                 onlyFromCamera: true,
                 success: function (res) {
-                    that.requestCodePay(res.result)
+                    that.fillAuthCodeFromScan(res.result)
                 }
             })
         },
@@ -117,6 +135,66 @@ export default {
             this.goPay = 0
             this.returnCode = ''
             this.isPaymentProcessing = false
+            this.closeManualInput()
+        },
+        /**
+         * 点击「请出示付款码」后展开输入区域
+         */
+        openManualInput(){
+            this.showManualInput = true
+            this.manualAuthCode = ''
+            this.manualInputFocus = false
+            this.$nextTick(() => {
+                this.manualInputFocus = true
+            })
+        },
+        /**
+         * 关闭付款码输入区域
+         */
+        closeManualInput(){
+            this.showManualInput = false
+            this.manualAuthCode = ''
+            this.manualInputFocus = false
+        },
+        /**
+         * 处理扫码:未展开输入框时自动提交,已展开时仅填入等待确认
+         * @param {string} rawCode - 扫码原始内容
+         */
+        fillAuthCodeFromScan(rawCode){
+            if(this.isCancelDialogOpen || this.isCloseDialogOpen){
+                this.$msg('请先完成当前操作')
+                return
+            }
+            if(this.isPaymentProcessing){
+                this.$msg('支付处理中,请稍候')
+                return
+            }
+            const authCode = String(rawCode || '').replace(/\s+/g, '')
+            if(!authCode){
+                return
+            }
+            if(this.showManualInput){
+                this.clearPolling()
+                this.remindText = ''
+                this.returnCode = ''
+                this.goPay = 0
+                this.manualAuthCode = authCode
+                this.manualInputFocus = false
+                return
+            }
+            this.requestCodePay(authCode)
+        },
+        /**
+         * 确认提交输入框中的付款码
+         */
+        submitManualCode(){
+            const authCode = String(this.manualAuthCode || '').replace(/\s+/g, '')
+            if (!authCode) {
+                this.$msg('请输入付款码')
+                return
+            }
+            this.closeManualInput()
+            this.requestCodePay(authCode)
         },
         checkOrder(){
             let that = this
@@ -167,6 +245,7 @@ export default {
                 if(res.code == 1){
                     if(res.data.returnStatus == 'SUCCESS'){
                         that.isPaymentProcessing = false
+                        that.closeManualInput()
                         that.showSuccess = true
                         setTimeout(function(){
                             that.payFinish()
@@ -269,6 +348,7 @@ export default {
             this.clearPolling()
             this.isPaymentProcessing = false
             this.isCancelDialogOpen = false
+            this.closeManualInput()
             if (this.showSuccess) {
                 this.payFinish()
                 return
@@ -365,6 +445,53 @@ export default {
             font-size: 19upx;
             margin: 15upx 0 10upx 0;
             font-weight:bold;
+            color: #3385ff;
+        }
+        & .manual-code-box{
+            width: 100%;
+            margin: 10upx auto 0 auto;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+        & .manual-code-input{
+            width: 50%;
+            height: 40upx;
+            line-height: 40upx;
+            border: 1upx solid #cccccc;
+            border-radius: 8upx;
+            font-size: 20upx;
+            text-align: center;
+            color: #333333;
+            background-color: #fafafa;
+            box-sizing: border-box;
+        }
+        & .manual-code-actions{
+            margin-top: 12upx;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+        }
+        & .manual-btn{
+            height: 44upx;
+            min-width: 88upx;
+            padding: 0 16upx;
+            text-align: center;
+            line-height: 44upx;
+            border: 1upx solid #dddddd;
+            border-radius: 22upx;
+            font-size: 14upx;
+            color: #666666;
+            background-color: #ffffff;
+            box-sizing: border-box;
+        }
+        & .manual-btn + .manual-btn{
+            margin-left: 16upx;
+        }
+        & .manual-btn-primary{
+            background-color: #3385ff;
+            color: #ffffff;
+            border-color: #3385ff;
         }
         & .paying{
             font-size: 19upx;