477 lines
10 KiB
Vue
477 lines
10 KiB
Vue
<template>
|
||
<view class="container">
|
||
<view class="card">
|
||
<view class="info-wrap">
|
||
<image class="cover" :src="shopInfo.portrait" mode="aspectFill"></image>
|
||
<text class="t">{{ shopInfo.userName }}</text>
|
||
</view>
|
||
<view class="input-wrap">
|
||
<view class="input-cont">
|
||
<text class="i">¥</text>
|
||
<text class="num">{{ num }}</text>
|
||
</view>
|
||
<view class="tips"><input class="input" type="text" :maxlength="10" placeholder="添加付款备注(最多10个字)"
|
||
v-model="remark" /></view>
|
||
</view>
|
||
</view>
|
||
<view class="card">
|
||
<view class="title"><text>支付方式</text></view>
|
||
<view class="pay-list">
|
||
<view class="item">
|
||
<view class="label">
|
||
<image class="icon" src="@/static/4.png" mode="aspectFit"></image>
|
||
<text class="t">微信支付</text>
|
||
</view>
|
||
<uni-icons type="checkbox-filled" size="18" color="#54A347"></uni-icons>
|
||
</view>
|
||
</view>
|
||
<view class="num-wrap">
|
||
<text>实付:</text>
|
||
<text class="t b">¥{{ num || 0 }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="number-key-wrap">
|
||
<view class="number-key">
|
||
<view class="left">
|
||
<view class="num-list">
|
||
<view class="item" v-for="item in 9" :key="item" hover-class="active" hover-stay-time="50"
|
||
@click="numHandle(`${item + 1}`)">
|
||
<text>{{ item + 1 }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="num-foot">
|
||
<view class="item" hover-class="active" hover-stay-time="50" @click="numHandle('0')">
|
||
<text>0</text>
|
||
</view>
|
||
<view class="item" hover-class="active" hover-stay-time="50" @click="numHandle('.')">
|
||
<text>.</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="right">
|
||
<view class="item" hover-class="active" hover-stay-time="50" @click="delHandle" @longpress="longDel"
|
||
@touchend="endLongDel">
|
||
<uni-icons type="arrow-left" size="24"></uni-icons>
|
||
</view>
|
||
<view class="item confirm" hover-class="active" hover-stay-time="50" @click="submitHandle">
|
||
<text>付款</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
userAppId: '', // 用户id
|
||
shopInfo: '', // 商户信息
|
||
num: '', // 输入金额
|
||
// maxNum: 200,
|
||
remark: '', // 备注
|
||
timer: null,
|
||
orderNumber: '',
|
||
type: 1
|
||
};
|
||
},
|
||
onLoad(e) {
|
||
console.log(e, '111')
|
||
if (e.orderNumber) {
|
||
this.orderNumber = e.orderNumber;
|
||
}
|
||
|
||
if (e.q) {
|
||
let urlStr = decodeURIComponent(e.q);
|
||
if (this.getQueryString(urlStr, 'userAppId')) {
|
||
this.type = 1;
|
||
this.userAppId = this.getQueryString(urlStr, 'userAppId')
|
||
} else {
|
||
this.type = 2;
|
||
this.userAppId = urlStr.match('[^/]+(?!.*/)')[0]
|
||
}
|
||
console.log(this.userAppId, 'this.userAppId')
|
||
this.getShopInfo();
|
||
}
|
||
},
|
||
methods: {
|
||
// 付款
|
||
async submitHandle() {
|
||
try {
|
||
if (!this.num) {
|
||
uni.showToast({
|
||
title: '请输入支付金额',
|
||
icon: 'none'
|
||
});
|
||
} else {
|
||
uni.showLoading({
|
||
title: '支付中...',
|
||
mask: true
|
||
});
|
||
uni.login({
|
||
provider: 'weixin',
|
||
success: async (resdata) => {
|
||
let res = await this.requestHandle('/applet-pay/java-pay', {
|
||
store_id: this.shopInfo.store_id, // 商户id
|
||
pay_type: '1',
|
||
money: this.num, // 金额
|
||
remark: this.remark, // 备注
|
||
code: resdata.code
|
||
});
|
||
uni.requestPayment({
|
||
provider: 'wxpay',
|
||
timeStamp: res.data.payTimeStamp,
|
||
nonceStr: res.data.paynonceStr,
|
||
package: res.data.payPackage,
|
||
signType: res.data.paySignType,
|
||
paySign: res.data.paySign,
|
||
success: (res) => {
|
||
uni.hideLoading();
|
||
uni.showModal({
|
||
title: '注意',
|
||
content: `成功支付${this.num}元`,
|
||
showCancel: false,
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// uni.reLaunch({
|
||
// url: '/pages/index/index'
|
||
// });
|
||
uni.exitMiniProgram({
|
||
success: () => {
|
||
console.log('退出小程序成功');
|
||
},
|
||
fail: function(
|
||
err) {
|
||
console.log('退出小程序失败',err);
|
||
}
|
||
})
|
||
}
|
||
}
|
||
});
|
||
},
|
||
fail: (err) => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '支付失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
}
|
||
} catch (e) {
|
||
uni.showToast({
|
||
title: '支付失败:' + JSON.stringify(e),
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
// 删除
|
||
delHandle() {
|
||
uni.vibrateShort();
|
||
this.num = this.num.slice(0, -1);
|
||
},
|
||
// 长按删除
|
||
longDel() {
|
||
this.timer = setInterval(() => {
|
||
this.delHandle();
|
||
}, 100);
|
||
},
|
||
// 结束长按删除
|
||
endLongDel() {
|
||
clearInterval(this.timer);
|
||
this.timer = null;
|
||
},
|
||
// 输入
|
||
numHandle(num) {
|
||
uni.vibrateShort();
|
||
this.num = this.clearNoNum({
|
||
value: (this.num += num)
|
||
});
|
||
},
|
||
// 封装请求
|
||
requestHandle(url = '', data = {}, method = 'post') {
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: `${'https://kysh.sxczgkj.cn'}/javaApi${url}`,
|
||
method: method,
|
||
header: {
|
||
uniacid: '1',
|
||
module: 'yb_o2ov2',
|
||
appType: 'mini'
|
||
// userId:uni.getStorageSync('userId')
|
||
},
|
||
data: data,
|
||
success: (res) => {
|
||
if (res.data.code == 1) {
|
||
resolve(res.data);
|
||
} else {
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: res.data.msg
|
||
});
|
||
reject(res.data.msg);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(JSON.stringify(err));
|
||
}
|
||
});
|
||
});
|
||
},
|
||
// 获取商户信息
|
||
async getShopInfo() {
|
||
try {
|
||
const res = await this.requestHandle('/applet-pay/get-applet-store-info', {
|
||
code_id: this.userAppId,
|
||
type: this.type
|
||
});
|
||
this.shopInfo = res.data;
|
||
} catch (e) {}
|
||
},
|
||
// 获取url参数
|
||
getQueryString(url, name) {
|
||
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i');
|
||
var r = url.substr(1).match(reg);
|
||
if (r != null) {
|
||
return r[2];
|
||
}
|
||
return null;
|
||
},
|
||
/**
|
||
* 去除字符串中除了数字和点以外的其他字符
|
||
* @param {Object} obj
|
||
*/
|
||
clearNoNum(obj) {
|
||
//如果用户第一位输入的是小数点,则重置输入框内容
|
||
if (obj.value != '' && obj.value.substr(0, 1) == '.') {
|
||
obj.value = '';
|
||
}
|
||
obj.value = obj.value.replace(/^0*(0\.|[1-9])/, '$1'); //粘贴不生效
|
||
obj.value = obj.value.replace(/[^\d.]/g, ''); //清除“数字”和“.”以外的字符
|
||
obj.value = obj.value.replace(/\.{2,}/g, '.'); //只保留第一个. 清除多余的
|
||
obj.value = obj.value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
|
||
obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); //只能输入两个小数
|
||
if (obj.value.indexOf('.') < 0 && obj.value != '') {
|
||
//以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
|
||
if (obj.value.substr(0, 1) == '0' && obj.value.length == 2) {
|
||
obj.value = obj.value.substr(1, obj.value.length);
|
||
}
|
||
}
|
||
return obj.value;
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.container {
|
||
padding: 28upx;
|
||
padding-bottom: 640upx;
|
||
}
|
||
|
||
.card {
|
||
padding: 28upx;
|
||
border-radius: 28upx;
|
||
background-color: #fff;
|
||
margin-bottom: 28upx;
|
||
|
||
.title {
|
||
font-size: 32upx;
|
||
}
|
||
}
|
||
|
||
.info-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.cover {
|
||
$size: 80upx;
|
||
width: $size;
|
||
height: $size;
|
||
border-radius: 50%;
|
||
margin-right: 20upx;
|
||
background-color: #efefef;
|
||
}
|
||
|
||
.t {
|
||
font-size: 32upx;
|
||
}
|
||
}
|
||
|
||
.input-wrap {
|
||
padding: 28upx 0 0;
|
||
|
||
.input-cont {
|
||
display: flex;
|
||
align-items: center;
|
||
border-bottom: 1upx solid #ececec;
|
||
|
||
.i {
|
||
font-size: 42upx;
|
||
font-weight: bold;
|
||
margin-right: 12upx;
|
||
position: relative;
|
||
top: -4upx;
|
||
}
|
||
|
||
.num {
|
||
font-size: 48upx;
|
||
height: 80upx;
|
||
font-weight: bold;
|
||
position: relative;
|
||
padding-right: 14upx;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
|
||
&::after {
|
||
content: '';
|
||
width: 4upx;
|
||
height: 40upx;
|
||
background-color: #333;
|
||
position: absolute;
|
||
top: 50%;
|
||
margin-top: -24upx;
|
||
right: 0;
|
||
animation: ani 0.8s ease-in-out 1.4s infinite;
|
||
}
|
||
|
||
@keyframes ani {
|
||
0% {
|
||
opacity: 0;
|
||
}
|
||
|
||
100% {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.tips {
|
||
display: flex;
|
||
padding-top: 24upx;
|
||
|
||
.input {
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pay-list {
|
||
.item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 28upx 0;
|
||
|
||
.label {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.icon {
|
||
$size: 60upx;
|
||
width: $size;
|
||
height: $size;
|
||
margin-right: 20upx;
|
||
}
|
||
|
||
.t {
|
||
font-size: 28upx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.num-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
|
||
.t {
|
||
font-size: 32upx;
|
||
}
|
||
|
||
.b {
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.number-key-wrap {
|
||
width: 100%;
|
||
position: fixed;
|
||
left: 0;
|
||
bottom: 0;
|
||
background-color: #efefef;
|
||
z-index: 999;
|
||
padding: 28upx 28upx calc(env(safe-area-inset-bottom) + 28upx);
|
||
border-radius: 28upx 28upx 0 0;
|
||
$gap: 12upx;
|
||
$radius: 14upx;
|
||
$itemH: 120upx;
|
||
|
||
.number-key {
|
||
display: flex;
|
||
|
||
.item {
|
||
display: flex;
|
||
font-size: 48upx;
|
||
font-weight: bold;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: $radius;
|
||
background-color: #fff;
|
||
|
||
&.active {
|
||
background-color: #d9d9d9;
|
||
}
|
||
}
|
||
|
||
.left {
|
||
flex: 1;
|
||
|
||
.num-list {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
grid-template-rows: $itemH $itemH $itemH;
|
||
grid-gap: $gap;
|
||
}
|
||
|
||
.num-foot {
|
||
padding-top: $gap;
|
||
display: grid;
|
||
grid-gap: $gap;
|
||
grid-template-columns: 2fr 1fr;
|
||
grid-template-rows: $itemH;
|
||
}
|
||
}
|
||
|
||
.right {
|
||
width: 160upx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
margin-left: $gap;
|
||
|
||
.item {
|
||
flex: 1;
|
||
|
||
&:last-child {
|
||
margin-top: $gap;
|
||
font-size: 32upx;
|
||
}
|
||
|
||
&.confirm {
|
||
background-color: #ffcc17;
|
||
|
||
&.active {
|
||
background-color: #e1b516;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |