前端常见业务功能实现

117 阅读4分钟

前端生成二维码

原生 js 实现点击按钮复制文本

前端加密

利用Blob实现前端导出Excel,Doc等文件

Vuex实现数据持久化,解决浏览器刷新数据丢失问题

H5移动端调试神器 - vconsole.js

香蕉云编

香蕉云编申请证书

滑块验证

高性能渲染十万条数据

滑块验证vue3

npm上传

pinia 持久化

  1. 安装 pinia-plugin-unistorage

image.png

获取微信头像

  1. 微信小程序
                    <button
                        class="avatar-wrapper"
                        open-type="chooseAvatar"
                        @chooseavatar="onChooseAvatar">
                        <u-avatar :src="info.avatar" size="30"></u-avatar>
                    </button>
  1. APP
// APP 获取微信头像
const wxAppLogin = () => {
    uni.getProvider({
        service: 'oauth',
        success: function (res) {
            uni.login({
                provider: 'weixin',
                success: function (loginRes) {
                    console.log(loginRes, '----')
                    // 获取用户信息
                    uni.getUserInfo({
                        provider: 'weixin',
                        success: async (infoRes) => {
                            console.log(infoRes, 'getUserInfo')
                            info.avatar = infoRes.userInfo.avatarUrl
                        }
                    })
                }
            })
        }
    })
}

支付

1. 支付宝APP支付

   async goPayNativeAppAlipay() {
            const { pay_money, pay_type, order_source } = this
            const res = await postTopUpOrderApi({ pay_money, pay_type, order_source })
            if (res.success) {
                console.log(res)
                uni.requestPayment({
                    provider: 'alipay',
                    orderInfo: res.data.alipay, //微信、支付宝订单数据
                    success: (res) => {
                        this.payStatus()
                    },
                    fail: (err) => {
                        this.payStatus()
                        console.log(err, '微信公众号内jsapi支付error')
                    }
                })
            } else {
                uni.showToast({
                    title: '获取失败',
                    icon: 'none'
                })
                this.loading = false
            }
        },

2.支付宝web支付

        async goPayH5AppAlipay() {
            const { pay_money, pay_type, order_source } = this
            const res = await postTopUpOrderApi({ pay_money, pay_type, order_source })
            if (res.success) {
                console.log(res)
                const div = document.createElement('div')
                /* 此处form就是后台返回接收到的数据 */
                div.innerHTML = res.data.alipay
                console.log(res, 'res.data.alipy')
                document.body.appendChild(div)
                console.log(document.forms, ' document.forms')
                document.forms[0].submit()
                document.body.removeChild(div)
            } else {
                uni.showToast({
                    title: '获取失败',
                    icon: 'none'
                })
                this.loading = false
            }
        },

3. 微信公众号支付

  1. 安装 jweixin-module
  2. 获取code
getWeChatCode() {
            let local = encodeURIComponent(window.location.href) //获取当前页面地址作为回调地址
            let appid = '' // 微信公众号appid

            //通过微信官方接口获取code之后,会重新刷新设置的回调地址【redirect_uri】
            window.location.href =
                'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
                appid +
                '&redirect_uri=' +
                local +
                '&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect'
        },
  1. 获取openid,并通过openid完成支付
async goUserWxOpenGzhid(code) {
            const res = await getOrderOpenidGzhApi({ code, source: this.order_source })
            console.log(res.data.openid, 'openid')
            if (res.success) {
                return res.data.openid
            } else {
                uni.showToast({
                    title: '获取openId失败',
                    icon: 'none'
                })
            }
        }
 async goPayJSAPIWeiXin(openid) {
            uni.showToast({
                title: '微信H5支付申请中',
                icon: 'none'
            })
            var that = this
            const { pay_money, pay_type, order_source } = this
            const res = await postTopUpOrderApi({ pay_money, pay_type, order_source, openid })
            uni.hideLoading()
            if (res.success) {
                var weixin = res.data.wxpay.weixin
                // 微信公众号内jsapi支付
                var jweixin = require('jweixin-module')
                jweixin.config({
                    debug: false,
                    appId: weixin.appId,
                    timestamp: weixin.timeStamp,
                    nonceStr: weixin.nonceStr,
                    signature: weixin.sign,
                    jsApiList: ['chooseWXPay']
                })
                jweixin.ready(function () {
                    jweixin.checkJsApi({
                        jsApiList: ['chooseWXPay'],
                        success: function (res) {
                            console.log('checkjsapi Success')
                            console.log(res)
                        },
                        fail: function (res) {
                            console.log(res)
                        }
                    })
                    jweixin.chooseWXPay({
                        appId: weixin.appId,
                        timestamp: weixin.timeStamp,
                        nonceStr: weixin.nonceStr,
                        package: weixin.package,
                        signType: 'MD5',
                        paySign: weixin.sign,
                        success: function (res) {
                            that.payStatus()
                        },
                        cancel: function (r) {
                            uni.showToast({
                                title: '支付取消!',
                                icon: 'none'
                            })
                            return
                        },
                        fail: function (error) {
                            that.payStatus()
                            console.log(error, '微信公众号内jsapi支付error')
                        }
                    })
                })
                jweixin.error(function (res) {
                    console.log('error')
                    console.log(res)
                    uni.showToast({
                        icon: 'none',
                        title: '支付失败了',
                        duration: 4000
                    })
                })
            } else {
                uni.showToast({
                    title: '获取失败',
                    icon: 'none'
                })
            }
        },

4.微信小程序支付

  1. 获取code,并将code给到后端获取openid
uni.login({
                success: async ({ code }) => {
                    console.log(code, '---')
                    try {
                        const openid = await this.goUserWxOpenMpid(code)
                    } catch {
                        uni.hideLoading()
                    }
                },
                fail: function () {
                    uni.hideLoading()
                    uni.showToast({
                        title: '获取用户信息失败',
                        icon: 'none'
                    })
                    this.onClick = 0
                }
            })
  1. 通过 requestPayment 完成支付
 //微信小程序支付
        async goPayWXappStepTwo(openid) {
            try {
                const { pay_money, pay_type, order_source } = this
                const res = await postTopUpOrderApi({ pay_money, pay_type, order_source, openid })
                uni.hideLoading()
                if (res.success) {
                    uni.requestPayment({
                        timeStamp: res.data.wxpay.weixin.timeStamp,
                        nonceStr: res.data.wxpay.weixin.nonceStr,
                        package: res.data.wxpay.weixin.package,
                        signType: 'MD5',
                        paySign: res.data.wxpay.weixin.sign,
                        provider: 'wxpay',
                        success: (res) => {
                            this.payStatus()
                        },
                        fail: (res) => {
                            console.log(res, '微信小程序支付error')
                            this.payError()
                            this.loading = false
                        }
                    })
                } else {
                    uni.showToast({
                        title: res.data.msg,
                        icon: 'none'
                    })
                    this.loading = false
                }
            } catch (error) {
                this.loading = false
            }
        },

5. 微信APP支付

 //微信App支付
        async goPayNativeAppWeiXin() {
            uni.hideLoading()
            const { pay_money, pay_type, order_source } = this
            const res = await postTopUpOrderApi({ pay_money, pay_type, order_source })
            if (res.success) {
                uni.requestPayment({
                    provider: 'wxpay',
                    orderInfo: res.data.wxpay.weixin, //微信、支付宝订单数据
                    success: (res) => {
                        this.payStatus()
                    },
                    fail: (err) => {
                        let msg = err.errMsg.toString()
                        let errorRes = msg.split(',')
                        // console.log();
                        if (errorRes[0] == 'requestPayment:fail:客户端未安装') {
                            uni.showToast({
                                title: '检测到未安装微信',
                                icon: 'none'
                            })
                        } else {
                            this.payStatus()
                        }
                        console.log(error, '微信App支付error')
                    }
                })
            } else {
                uni.showToast({
                    title: '获取失败',
                    icon: 'none'
                })
            }
        },

websocket封装

class socketIO {
    constructor(time) {
        this.socketTask = null
        this.is_open_socket = false //避免重复连接
        this.url = process.uniEnv.BASE_SOCKET_URL //连接地址
        this.data = {}
        this.userTokenMap = {}
        this.connectNum = 1 // 重连次数
        this.is_hand_socket = false //是否为手动断开
        //心跳检测
        this.timeout = time ? time : 50000 //多少秒执行检测
        this.heartbeatInterval = null //检测服务器端是否还活着
        this.reconnectTimeOut = null //重连之后多久再次重连
    }
    // 进入这个页面的时候创建websocket连接【整个页面随时使用】
    connectSocketInit(data) {
        
        this.userTokenMap = data
        this.socketTask = uni.connectSocket({
            url: this.url,
            success: () => {
                console.log('正准备建立websocket中...')
                // 返回实例
                return this.socketTask
            }
        })
        this.socketTask.onOpen((res) => {
            this.connectNum = 1
            console.log('WebSocket连接正常!')
            this.send(data)
            clearInterval(this.reconnectTimeOut)
            clearInterval(this.heartbeatInterval)
            this.is_open_socket = true
            this.start()
            // 注:只有连接正常打开中 ,才能正常收到消息
            this.socketTask.onMessage((e) => {
                // 字符串转json
                let res = JSON.parse(e.data)
                console.log('res---------->', res) // 这里 查看 推送过来的消息
                uni.$emit(`getPositonsOrder`, res)
            })
        })
        // 监听连接失败
        uni.onSocketError((res) => {
            console.log('WebSocket连接打开失败,请检查!')
        })
        // 这里仅是事件监听【如果socket关闭了会执行】
        // 经实测 发现在初次建立链接失败时,error与close事件监听都会触发,而在链接期间因异常情况断开时只会触发close,故将异常事件处理方法放在close中
        this.socketTask.onClose(() => {
            console.log('已经被关闭了-------')
            clearInterval(this.heartbeatInterval)
            clearInterval(this.reconnectTimeOut)
            uni.$off(`getPositonsOrder`)
            uni.$off(`connectError`)
            if (!this.is_hand_socket) {
                this.socketTask = null
                this.is_open_socket = false
                if (this.connectNum < 6) {
                    console.log(`连接失败,正尝试第${this.connectNum}次连接`);
                    // uni.showToast({
                    //     title: `连接失败,正尝试第${this.connectNum}次连接`,
                    //     icon: 'none'
                    // })
                    this.reconnect(true)
                    this.connectNum += 1
                } else {
                    console.log(`尝试连接失败,请在网络健康情况下重试`);
                    // uni.showToast({
                    //     title: `尝试连接失败,请在网络健康情况下重试`,
                    //     icon: 'none'
                    // })
                    uni.$emit(`connectError`)
                    this.connectNum = 1
                }
            }
        })
    }
    // 主动关闭socket连接
    Close() {
        if (!this.is_open_socket) {
            return
        }
        this.is_hand_socket = true
        this.socketTask.close({
            success() {
                uni.showToast({
                    title: 'SocketTask 关闭成功',
                    icon: 'none'
                })
            }
        })
    }
    //发送消息
    send(contentData, isNoData = false) {
        const data = isNoData ? contentData : { ...contentData, ...this.data }
        console.log(data, 'send----')
        // 注:只有连接正常打开中 ,才能正常成功发送消息
        if (this.socketTask) {
            this.socketTask.send({
                data: JSON.stringify(data),
                async success() {
                    console.log('消息发送成功')
                }
            })
        }
    }
    //开启心跳检测
    start() {
        this.heartbeatInterval = setInterval(() => {
            this.send(
                {
                    type: 'ping'
                },
                true
            )
        }, this.timeout)
    }
    //重新连接
    reconnect(isError) {
        //停止发送心跳
        clearInterval(this.heartbeatInterval)
        console.log(this.is_open_socket, isError, '----')
        //如果不是人为关闭的话,进行重连
        if (!this.is_open_socket && isError) {
            this.reconnectTimeOut = setTimeout(() => {
                this.connectSocketInit(this.userTokenMap)
            }, 5000)
        }
    }
    //设置data
    setdata(data) {
        this.data = data
    }
}
module.exports = socketIO