|
|
@@ -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;
|