同步数据

This commit is contained in:
2022-06-12 13:09:03 +08:00
parent b8c986c0d8
commit 238db66375
15 changed files with 2380 additions and 1238 deletions

View File

@@ -24,11 +24,21 @@ const alPAY = (orderNo) => {
}
})
}
const dtPAY = (orderNo) => {
const payIndex =()=>{
return request({
url: 'mall/pay/index'
})
}
const dtPAY = (orderNo,password) => {
return request({
url: 'mall/pay/' + orderNo + '/account',
method:'post',
data: {
type: 'app'
type: 'app',
transfer_password:password
}
})
}
@@ -37,5 +47,6 @@ const dtPAY = (orderNo) => {
export {
wxPAY,
alPAY,
dtPAY
dtPAY,
payIndex,
}

View File

@@ -0,0 +1,307 @@
<template>
<view class="keyboard-content">
<view class="content_">
<view class="title">请输入支付密码</view>
<view class="password-error">
<text v-if="passwordError">对不起您的支付密码不正确请重新输入</text>
</view>
<view class="input-content">
<view class="input_">
<view v-for="item in inputArr">
<view v-if="item === '·'" class="dot"></view>
<text v-else></text>
</view>
</view>
</view>
<!-- <view class="forget" @tap="forgetPass">忘记密码</view> -->
<view class="board-content">
<view class="title_">
<image src="https://z3.ax1x.com/2021/03/31/cApnN4.png" mode=""></image>
<text> DTX 安全键盘 </text>
</view>
<view class="board">
<view class="key" hover-class="hoverStyle" @tap="inputNum(item.id)" :class="{small: item.id === 'cancel' || item.id === 'del'}" v-for="item in boardArr">
<image class="backspace" v-if="item.id === 'del'" src="https://z3.ax1x.com/2021/03/31/cAp1jx.png" mode=""></image>
<text v-else>{{item.text}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '安全键盘',
}
},
data() {
return {
inputArr: ['','','','','',''],
passwordInput: '',
passwordError: false,
boardArr: [
{
id: '1',
text: '1'
},{
id: '2',
text: '2'
},{
id: '3',
text: '3'
},{
id: '4',
text: '4'
},{
id: '5',
text: '5'
},{
id: '6',
text: '6'
},{
id: '7',
text: '7'
},{
id: '8',
text: '8'
},{
id: '9',
text: '9'
},{
id: 'cancel',
text: '取消'
},{
id: '0',
text: '0'
},{
id: 'del',
text: 'del'
},
],
};
},
methods: {
// 输入密码
inputNum(id) {
if(id === 'del'){ // 点击[删除]按钮
this.del()
return
}
if(id === 'cancel'){ // 点击[取消]按钮
this.cancel()
return
}
if(this.passwordInput.length > 11){ // 6位密码输入完毕
return
}
let passwordInput = this.passwordInput
this.passwordInput = passwordInput + id + '|'
console.log(this.passwordInput);
this.initPass()
if(this.passwordInput.length === 12){ // 输入完毕
console.log(this.passwordInput);
this.testPassword()
}
},
// 删除一位
del() {
this.passwordInput = this.passwordInput.substring(0, this.passwordInput.length - 2)
this.initPass()
},
// 取消 可退出输入
cancel() {
this.inputArr = ['','','','','','']
this.passwordInput = ''
this.$emit('close')
},
initPass() {
let arr = this.passwordInput.split('|');
arr.pop()
console.log(arr);
let arr_ = []
for(let i = 0; i< 6; i++){
if(i < arr.length){
arr_.push('·')
}else{
arr_.push('')
}
}
this.inputArr = arr_
},
// 输入完毕之后 验证密码是否正确
testPassword() {
let arr = this.passwordInput.split('|')
arr.pop()
let passStr = arr.join('')
// 测试数据 在此处可添加个人的业务代码
var isTrue = true
if(isTrue) {
this.$emit('success', passStr)
this.passwordError = false
// uni.showToast({
// title: '密码: '+passStr
// })
this.inputArr = ['','','','','','']
this.passwordInput = ''
}else{
this.passwordError = true
this.inputArr = ['','','','','','']
this.passwordInput = ''
}
},
// 点击忘记密码 可跳转页面或自定义业务
forgetPass() {
this.cancel()
uni.showToast({
title: '忘记密码'
})
},
}
}
</script>
<style lang="scss" scoped>
.hoverStyle{
background: #e5e5e5;
}
.keyboard-content{
background: rgba($color: #000000, $alpha: .7);
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: column;
.content_{
background: #FFFFFF;
width: 100%;
.title{
text-align: center;
padding: 20rpx 0;
font-weight: bold;
border-bottom: 1px solid #dddddd;
background: #f7f7f7;
color: #1F2324;
font-size: 30rpx;
letter-spacing: 1rpx;
}
.password-error{
background: #f7f7f7;
padding: 10rpx 0;
display: flex;
justify-content: center;
align-items: center;
color: #F00;
font-size: 12rpx;
}
.input-content{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: #f7f7f7;
.input_{
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #D9D9D9;
background: #ffffff;
>view{
width: 90rpx;
height: 90rpx;
border-right: 1px solid #dddddd;
display: flex;
justify-content: center;
align-items: center;
&:last-child{
border-right: none;
}
.dot{
width: 20rpx;
height: 20rpx;
background: #000000;
border-radius: 50%;
}
}
}
}
.forget{
color: #666;
font-size: 24rpx;
background: #f7f7f7;
padding: 20rpx 40rpx;
display: flex;
justify-content: flex-end;
align-items: center;
}
.board-content{
.title_{
display: flex;
justify-content: center;
align-items: center;
color: #222;
font-size: 20rpx;
padding: 10rpx 0;
>image{
width: 22rpx;
height: 26rpx;
margin-right: 8rpx;
}
}
.board{
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
border-top: 1px solid #f2f2f2;
.key{
height: 110rpx;
flex: 33%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #f2f2f2;
color: #222;
font-size: 50rpx;
border-left: none;
border-top: none;
}
.small{
font-size: 34rpx;
letter-spacing: 2rpx;
background-color: #f7f7f7;
color: #686868;
}
}
}
.backspace{
width: 45rpx;
height: 33rpx;
}
}
}
</style>

75
components/readme.md Normal file
View File

@@ -0,0 +1,75 @@
# 使用方法
```
<x-pay-pwd
ref="xPayPwd"
:type="1"
:maskClick="true"
top="unset"
bottom="0rpx"
:showClose="false"
@change="change"
:showHead="true"
headText="请输入支付密码"
>
<template #center>
<button @click="clear">插槽</button>
</template>
</x-pay-pwd>
```
```
export default {
methods: {
// 监听输入框内容变化
change({password}){
console.log(password)
},
// 清空输入框内容,一般用于密码输错手动清空
clear(){
this.$refs.xPayPwd._clearKey();
}
}
}
```
# 属性
| 字段 | 类型 | 默认 | 描述 |
| --------- | ------- | -------------- | ---------------------------------------- |
| type | Number | 1 | 0原生键盘 1自定义键盘 |
| maskClick | Boolean | true | 是否允许点击蒙版 |
| top | String | 20vh | 中间内容的top值为absolute的top值 |
| bottom | String | 0rpx | 中间内容的bottom值为absolute的bottom值 |
| showClose | Boolean | true | 是否显示关闭按钮 |
| showHead | Boolean | true | 是否显示标题 |
| headText | String | 请输入支付密码 | 标题文本 |
# 事件
| 事件名 | 默认参数 | 描述 |
| ------ | ---------- | -------------------------------- |
| change | {password} | 监听内容输入,参数返回输入的内容 |
# 组件方法
| 方法名 | 描述 |
| ------ | -------------------------------- |
| _open | 打开弹窗 |
| _close | 关闭弹窗 |
| _clearnKey | 请空输入内容 |
# 注意
```
ios下输入框不会自动获取焦点需要手动点击输入区域
```
# 参与贡献
+ xueshuai(xueshuai_12@163.com)
+ Emailxueshuai_12@163.com
+ GitHubGitHub地址
+ QQ交流群1063233592
+ 个人博客:(薛小帅)[http://blog.xueshuai.top]
+ 个人公众号叮当Ding
![叮当Ding](https://img-blog.csdnimg.cn/20210202143040150.png)

View File

@@ -0,0 +1,157 @@
<template>
<view class="content" :class="{show:open}">
<view class="mask" @click="handleMaskClick"></view>
<view class="wrap native" v-if="type === 0" :style="{top:top,bottom:bottom}">
<view class="head" v-if="showHead">{{headText}}<text class="close" v-if="showClose" @click="_close">x</text></view>
<view ref="pwdTxt" class="input" @click="_focusIpt">
<input ref="pwdIpt" class="hide_ipt" type="tel" maxlength="6" v-model="passwordStr" focus @input="_input"/>
<view class="pwd_i" v-for="(item,index) in password" :key="index"><text class="pwd" v-if="item"></text></view>
</view>
<slot name="center"/>
</view>
<view class="wrap custom" v-if="type === 1" :style="{top:top,bottom:bottom}">
<view class="head" v-if="showHead">{{headText}}<text class="close" v-if="showClose" @click="_close">x</text></view>
<view class="input">
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[0]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[1]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[2]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[3]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[4]" disabled />
<input class="pwd_i" type="password" maxlength="1" v-model="pwdArr[5]" disabled />
</view>
<slot name="center"/>
<view class="key">
<view class="key_i" v-for="(key,index) in keys" :key="index" :class="{nobg:key == '' || key == 'del',del:key == 'del'}" @click="inputKey(key)">
<text v-if="key != 'del'">{{key}}</text>
<text v-else class="text">x</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
props:{
maskClick:{//是否允许点击蒙版
type:Boolean,
default:true
},
top:{//absoute的top值
type:String,
default:'20vh'
},
bottom:{//absoulute的bottom值
type:String,
default:'0rpx'
},
showClose:{//是否显示关闭按钮
type:Boolean,
default:true
},
type:{//密码支付类型 0原生输入框 1自定义输入框
type:Number,
default:1
},
showHead:{//是否显示头部信息
type:Boolean,
default:true
},
headText:{//头部信息文字
type:String,
default:'请输入支付密码'
}
},
data(){
return{
passwordStr:'',//原生需要的字符串密码
password:['','','','','',''],//原生键盘输入的密码
open:false,//是否展示
pwdArr:[],//自定义支付输入的密码
keys:['1','2','3','4','5','6','7','8','9','','0','del'],//键盘
}
},
methods:{
_input(){// 监听输入
const pwdArr = this.passwordStr.split('');
for(let i = 0;i<6;i++){
this.password[i] = pwdArr[i];
}
if(this.password.length == 6){
this.$emit('change',{password:this.password.join('')})
}
},
_focusIpt(){// 监听点击按钮使输入框获得焦点
this.$refs.pwdIpt._focus();
},
_open(){// 打开弹窗
this.open = true;
},
_close(){// 关闭弹窗
this.open = false;
},
_clearKey(){// 清空输入
this.passwordStr = '';
this.pwdArr = [];
for(let i = 0;i<6;i++){
this.password[i] = '';
}
},
handleMaskClick(){//点击蒙版
if(!this.maskClick) return;
this._close();
},
inputKey(k){// 监听自定义输入
if(k == '') return;
if(k != 'del'){
if(this.pwdArr.length == 6) return;
this.pwdArr.push(k);
}else{
if(this.pwdArr.length == 0) return;
this.pwdArr.splice(this.pwdArr.length-1,1)
}
this.$emit('change',{password:this.pwdArr.join('')})
},
}
}
</script>
<style lang="scss" scoped>
.content{position: fixed;top: 0rpx;right: 0rpx;bottom: 0rpx;left: 0rpx; justify-content: center;display: flex;transition:.3s;transform: scale3d(0, 0, 0);
&.show{transform: scale3d(1,1,1);}
.mask{position: absolute;top: 0;right: 0;bottom: 0;left: 0;background-color: rgba($color: #000000, $alpha: 0.6);z-index:1;}
.wrap{background-color: #fff;border-radius: 16rpx;padding: 40rpx;height: max-content;z-index: 2;position: absolute;width: 70%;
.head{text-align: center;font-size: 36rpx;color: #2B2B2B;font-weight: 500;margin-bottom: 36rpx;position: relative;
.close{position: absolute;right: 0rpx;top: 0rpx;width: 40rpx;height: 40rpx;font-size: 32rpx;color: #646464;display: inline-block;}
}
.input{display: flex;margin: 0rpx 0rpx 16rpx;border: 2rpx solid #F1F1F1;border-radius: 16rpx;justify-content: center;position: relative;
.pwd_i{width: 88rpx;height: 88rpx;border-right:2rpx solid #F1F1F1;text-align: center;font-size: 50rpx;display: flex;align-items: center;justify-content: center;
&:last-of-type{border-right:none;}
.pwd{display: inline-block;width: 18rpx;height: 18rpx;background-color: #000;border-radius: 50%;}
}
.hide_ipt{position: absolute;top: 0rpx;right: 0rpx;bottom: 0rpx;left: -100%;height: auto;color: transparent;z-index: -99;}
}
}
.custom{width: 100%;border-radius: 16rpx 16rpx 0rpx 0rpx;padding: 40rpx 0rpx 0rpx;
.head>.close{right: 20rpx;}
.input{display: flex;margin: 0rpx 41rpx 16rpx;border: 2rpx solid #F1F1F1;border-radius: 16rpx;justify-content: center;
.pwd_i{width: 108rpx;height: 108rpx;border-right:2rpx solid #F1F1F1;text-align: center;font-size: 50rpx;
&:last-of-type{border-right:none;}
}
}
.key{padding: 14rpx 12rpx 0rpx;background-color: #D2D5DB;display: flex;flex-wrap: wrap;
.key_i{width: 234rpx;height: 92rpx;margin-right: 12rpx;text-align: center;line-height: 92rpx;background-color: #fff;margin-bottom: 14rpx;
border-radius: 10rpx;box-shadow: 0px 2px 0px 0px rgba(132,134,136,1);font-size: 50rpx;color: #000000;font-weight: 500;
&:nth-of-type(3n){margin-right: 0rpx;}
&.nobg{background-color: transparent;box-shadow: none;}
&.del{display: flex;justify-content: center;align-items: center;
.text{color: #3F434A;}
}
&:active{box-shadow: 4rpx 4rpx 5rpx #444;background-color: rgba($color: #000000, $alpha: 0.2);}
}
}
}
}
</style>

View File

@@ -1,21 +1,13 @@
{
"name": "dtx_store",
"version": "1.0.0",
"description": "共力生态",
"main": "main.js",
"dependencies": {
"moment": "^2.29.1",
"uni-read-pages": "^1.0.5",
"uni-simple-router": "^2.0.7",
"uview-ui": "^2.0.27"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://git.yuzhankeji.cn/TmOct5/ZhHealth.git"
},
"author": "唐明明",
"license": "ISC"
"id": "mi-payKeyboard",
"name": "支付密码输入安全模拟键盘",
"version": "1.1.0",
"description": "支付密码输入模拟键盘,代码简单,拿来即用。可以作为一个弹出层在任何需要输入密码的页面进行使用。",
"keywords": [
"支付",
"密码输入",
"模拟键盘",
"6位数字密码",
"安全键盘"
]
}

View File

@@ -2,17 +2,21 @@
<view>
<oct-pay :price="price" :coins="coins" :payNo="payNo" color="#34CE98" price-color="#e6576b"
:payPlatform="platform" @onPay="pay" />
<payKeyboard v-if="showKeyBoard" title="Mi安全键盘" @success="enterSuccess" @close="close"></payKeyboard>
</view>
</template>
<script>
import payKeyboard from '@/components/mi-payKeyboard/mi-payKeyboard.vue'
import eventBus from '../../utils/eventBus.js';
import {
wxPAY,
alPAY,
dtPAY
dtPAY,
payIndex
} from '@/apis/interfaces/pay'
export default {
components: { payKeyboard },
data() {
return {
payNo: "",
@@ -20,20 +24,26 @@
coins: "",
platform: ['dtpay'],
oepnType: '',
canpay:true,
canpay: true,
has_transfer_password: true,
password: '',
showKeyBoard: false,
}
},
mounted() {
this.payNo = this.$Route.query.orderNo
this.price = Number(this.$Route.query.price).toFixed(2)
this.coins = this.$Route.query.coins
if (this.$Route.query.oepnType === 'order') {
this.oepnType = this.$Route.query.oepnType
}
},
onShow() {
this.payIndex();
},
methods: {
pay(e) {
if (e.platform === 'dtpay') return this.getDTPAY(e.platform);
if (e.platform === 'dtpay') return this.inputPassword();
uni.getProvider({
service: 'payment',
success: res => {
@@ -59,11 +69,67 @@
}
})
},
//获取支付
payIndex() {
payIndex().then(res => {
console.log(res);
this.has_transfer_password = res.has_transfer_password;
this.coins = res.score
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
mask: true,
})
})
},
// 输入支付密码
inputPassword() {
if (!this.has_transfer_password) {
uni.showModal({
title: '温馨提示',
content: '是否现在就去设置支付密码',
confirmText: '立即设置',
confirmColor: "#34CE98",
cancelText: '再想想',
cancelColor: "#666666",
success: (res) => {
if (res.confirm) {
this.$Router.push({
name: "AccountResetPassword"
})
}
this.canpay = true
}
})
} else {
this.showKeyBoard = true
}
},
// 输入正确的回调
enterSuccess(password) {
console.log(password) // 输入的密码
this.password = password
this.showKeyBoard = false
this.getDTPAY();
},
// 点击[取消] 关闭输入框 的回调
close(){
this.showKeyBoard = false;
this.canpay = true;
},
// 调用 dt 支付
getDTPAY() {
console.log('dt 支付。。。')
if(this.canpay){
if (this.canpay) {
this.canpay = false
dtPAY(this.payNo).then(res => {
console.log(this.password,this.payNo,'//////////')
dtPAY(this.payNo, this.password).then(res => {
if (res.state === 'warning') {
uni.showModal({
title: '当前DT积分不足',
@@ -118,7 +184,7 @@
} else {
uni.navigateBack();
}
this.canpay = true
this.canpay = true
}
})
}
@@ -132,7 +198,6 @@
})
this.canpay = true
})
}
},
getALPAY(payType) {

BIN
static/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
static/img/code_back1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@@ -9,7 +9,7 @@
<view class="price" :style="{color: color}">{{item.price.price_min || '0'}}
<view class="price-type">
<text> DT积分</text>
<text class="kucun" v-if="showSalce"> 库存量:1222</text>
<text class="kucun" v-if="showSalce"> 库存量:{{item.stock || '0'}}</text>
</view>
</view>
</view>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB