电子合同签名

小程序 uniapp 实现电子合同签名

签名部分引用的组件    ambler-wxcanvas

签名的放大缩小和旋转引用组件    canvas-drag

实现流程

  1. 将后端返回的imge图片暂时
  2. 点击签名用户输入签名
  3. 将签名返回的图片位置设置完成
  4. 利用canvas将两张图片合成一张图

html部分

    <view class="page-container">
        <NavBar center-title="待签署合同"></NavBar>
        <view class="body-box">
            <view class="header-title">
                {{richData.temTitle}}
            </view>
            <view class="rich-box">
                <image id="HTimageInfo" :style="{width:'690rpx',height:(HTimgIngo.height/HTimgIngo.width)*690+'rpx'}"
                    :src="richData.contractImg">
                </image>
            </view>
        </view>
        <canvas canvas-id="shareCanvas" class="canvas" bindlongpress="saveImg" catchtouchmove="true"
            :style="{width:HTimgIngo.width+'px',height:HTimgIngo.height+'px',position:'fixed',left:'-9999px'}">
        </canvas>
        <canvas-drag @clear="getCanvasInfoClear" ref="canvasRef" id="canvas-drag" :graph="graph" :width="690"
            :height="(HTimgIngo.height/HTimgIngo.width)*690"
            :style="{position:'fixed',left:'30rpx',top:(totalHeight*2+HTImgeTop*2)-20+'rpx'}"
            enableUndo="true"></canvas-drag>

        <view class="bottom-box">
            <view class="bottom-left-box">
                <view class="btn-box" @click="toSign">
                    <view class="btn-box-img">
                        <text class="iconfont icon-a-Group58197"></text>
                    </view>
                    <view class="btn-text">
                        签字
                    </view>
                </view>
            </view>
            <view class="bottom-right-box">
                <view class="btn-box" v-if="!QMImage">
                    <view class="btn-text">
                        请先签字
                    </view>
                </view>
                <view class="btn-box-select" v-else @click="exportPost">
                    <view class="btn-text">
                        确定签署
                    </view>
                </view>

            </view>

        </view>
    </view>

js部分

<script>
    import canvasDrag from "@/components/canvas-drag/index";
    export default {
        components: {
            canvasDrag
        },
        data() {
            return {
                statusBarHeight: 0, //状态栏的高度
                navigatorHeight: 0, //导航栏高度
                totalHeight: 0, //总高度
                HTImgeTop: 0,


                fromType: 1,
                richData: null,
                QMImage: '',
                HTimgIngo: {

                },
                ctx: null,
                currentSinImgPost: {
                    x: 10,
                    y: 10
                },
                finalImg: ''
            }
        },
        onReady() {
            this.ctx = wx.createCanvasContext('shareCanvas')
        },
        onLoad(params) {
            //获取系统信息
            uni.getSystemInfo({
                success: res => {
                    this.system = res
                }
            })
            //获取胶囊信息
            this.menu = uni.getMenuButtonBoundingClientRect()
            //计算组件高度
            this.statusBarHeight = this.system.statusBarHeight //状态栏高度
            this.navigatorHeight = (this.menu.top - this.system.statusBarHeight) * 2 + this.menu.height //导航栏高度
            this.totalHeight = this.statusBarHeight + this.navigatorHeight //总高度
            //获取图片距离顶部的距离
            let that = this;
            const query = uni.createSelectorQuery();
            query.select('#HTimageInfo').boundingClientRect();
            query.exec(res => {
                that.HTImgeTop = res[0].top;
            });

            uni.$on('QMdata', (res) => {
                this.QMImage = res
                this.onAddTest()
            })
            let curtoken = uni.getStorageSync('token')

            if (curtoken) {
                this.selectHtSignDetail(params.contractId)
            } else {
                uni.showToast({
                    title: '请先登录',
                    icon: 'none'
                })
                uni.switchTab({
                    url: '/pages/home/person'
                })
            }
            // params.isShare==1是分享的页面params.isShare==0不是分享的页面
            this.isFromShare = params.isShare
            if (params.isShare == 1) {
                this.$api.updateHtSignStatus({
                    contractId: params.contractId,
                    type: 1
                }).then((res) => {
                    if (res.code == 200) {

                    } else {
                        uni.showToast({
                            title: res.msg,
                            icon: 'none'
                        })
                    }
                })
            } else {

            }
        },
        components: {
            TimeFormat
        },
        methods: {

            /**
             * 添加签名图片图片
             */
            onAddTest() {
                this.setData({
                    graph: {
                        w: 120,
                        h: 50,
                        type: 'image',
                        url: this.QMImage
                    }
                });
            },
            //删除签名重新签字
            getCanvasInfoClear(data) {
                this.QMImage = ''
            },
            toSign() {
                //type==2为我的合同模板详情页面的签署------type==1为用户账号待我签署页面的签署
                uni.navigateTo({
                    url: '/pages/sign/sign?type=' + this.fromType
                })
            },
            //打开签名时间弹窗
            openSelectTimeFormat() {
                // this.$refs.timeFormat.openPopup()
            },
            //获取签署日期的格式
            getTimeFormat(data) {
                console.log(data, "获取日期")
            },
            selectHtSignDetail(contractId) {
                let that = this
                this.$api.selectHtSignDetail({
                    contractId
                }).then((res) => {
                    if (res.code == 200) {
                        this.richData = res.data
                        wx.getImageInfo({
                            src: res.data.contractImg,
                            success: (res) => {
                                that.HTimgIngo = res

                            }
                        })
                    }
                })
            },
            //获取图片的基本信息,即将网络图片转成本地图片,
            getImageInfo(src) {
                return new Promise((resolve, reject) => {
                    wx.getImageInfo({
                        src,
                        success: (res) => resolve(res),
                        fail: (res) => reject(res)
                    })
                });
            },
            //合成合同和签名图片
            exportPost() {
                /**
                 * 将签名导出
                 */
                let sinImage = ''
                this.$refs.canvasRef.exportFun().then(imgArr => {
                    console.log(JSON.stringify(imgArr), "生成的签名图片");
                    sinImage = imgArr
                    let that = this
                    uni.showLoading({
                        title: '生成中'
                    })
                    //image是画布的底图
                    let image = that.richData.contractImg
                    uni.getSystemInfo({
                        success: function(res) {
                            that.windowObj = res
                            that.windowObj.ratio = that.windowObj.windowWidth /
                                750 //因为小程序是用rpx单位,为了是后期合成的图片更好是适应各个手机屏幕的尺寸,这里先计算出一个比率,后面除以这个比率就可以对各个手机尺寸进行适配了
                            that.canvasWidth = that.windowObj.windowWidth / that.windowObj
                                .ratio //设置画布的宽高
                            that.canvasHeight = that.windowObj.windowHeight / that.windowObj.ratio
                            Promise.all([that.getImageInfo(image), that.getImageInfo(sinImage)])
                                .then(res => {
                                    that.ctx.drawImage(res[0].path, 0, 0, res[0].width, res[0]
                                        .height);
                                    that.ctx.drawImage(res[1].path, 0, 0, res[0].width, res[0]
                                        .height);
                                    that.ctx.draw(false, function() {
                                        wx.canvasToTempFilePath({
                                            x: 0,
                                            y: 0,
                                            width: res[0].width || that.windowObj
                                                .windowWidth,
                                            height: res[0].height || that.windowObj
                                                .windowHeight,
                                            destWidth: res[0].width * 2 || that
                                                .windowObj
                                                .windowWidth *
                                                2, //这里乘以2是为了保证合成图片的清晰度
                                            destHeight: res[0].height * 2 || that
                                                .windowObj
                                                .windowHeight * 2,
                                            canvasId: 'shareCanvas',
                                            fileType: 'png', //设置导出图片的后缀名
                                            quality: 1,
                                            success: function(res) {
                                                uni.hideLoading()
                                                //保存图片到本地
                                                that.finalImg = res
                                                    .tempFilePath
                                                console.log(that.finalImg,
                                                    "合成后的合同图");
                                                //调用签署接口
                                                that.updateHtSignF()

                                            }
                                        })
                                    });
                                })
                        }
                    })
                }).catch(e => {
                    console.error(e);
                    uni.showToast({
                        title: '签名生成失败',
                        icon: 'none'
                    })
                });
            },
            updateHtSignF() {
                console.log(this)
                let _that = this
                this.$api.uploadLgImg(this.finalImg).then(resImg => {
                    // form.value[text + "List"].push(JSON.parse(resImg).data.imgUrl)
                    this.$api.updateHtSign({
                        contractId: _that.richData.contractId,
                        contractImg: JSON.parse(resImg).data.url
                    }).then((res) => {
                        if (res.code == 200) {
                            uni.showToast({
                                title: '签约成功',
                                icon: 'none'
                            })
                        }
                    })

                })


            }
        }
    }
</script>

实现过程中借鉴了小程序 uniapp 实现pdf 电子合同签名 并导出功能_uniapp pdf转canvas-CSDN博客

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值