@@ -31,7 +31,8 @@ | |||||
"vue": "^2.5.2", | "vue": "^2.5.2", | ||||
"vue-baidu-map": "^0.21.22", | "vue-baidu-map": "^0.21.22", | ||||
"vue-cookies": "^1.7.4", | "vue-cookies": "^1.7.4", | ||||
"vue-esign": "^1.0.5", | |||||
"vue-cropper": "^0.5.8", | |||||
"vue-esign": "^1.1.4", | |||||
"vue-pdf": "^4.3.0", | "vue-pdf": "^4.3.0", | ||||
"vue-qrcode-reader": "^3.1.0", | "vue-qrcode-reader": "^3.1.0", | ||||
"vue-quill-editor": "^3.0.6", | "vue-quill-editor": "^3.0.6", | ||||
@@ -889,3 +889,12 @@ export function casePointList(query) { | |||||
}) | }) | ||||
} | } | ||||
// 用户上传签字 | |||||
export function electronicSignature(data) { | |||||
return request({ | |||||
url: '/system/user/profile/electronicSignature', | |||||
method: 'post', | |||||
data: data | |||||
}) | |||||
} | |||||
@@ -1824,6 +1824,15 @@ export const constantRoutes = [ | |||||
hidden: true, | hidden: true, | ||||
}, | }, | ||||
component: (resolve) => require(['@/views/yinnong/password'], resolve) | component: (resolve) => require(['@/views/yinnong/password'], resolve) | ||||
} , | |||||
{ | |||||
path: '/yinnong/signature', | |||||
name: 'yinnongSignature', | |||||
meta: { | |||||
title: '电子签名', | |||||
hidden: true, | |||||
}, | |||||
component: (resolve) => require(['@/views/yinnong/signature'], resolve) | |||||
}, | }, | ||||
{ | { | ||||
path: '/yinnong/livePay', | path: '/yinnong/livePay', | ||||
@@ -79,6 +79,17 @@ | |||||
/> | /> | ||||
</template> | </template> | ||||
</van-cell> | </van-cell> | ||||
<van-cell title="电子签名" is-link to="signature"> | |||||
<template #icon> | |||||
<van-image | |||||
fit="contain" | |||||
height="22" | |||||
style="margin-right: 15px" | |||||
src="../../../static/images/onlineHome/myIcon7.png" | |||||
/> | |||||
</template> | |||||
</van-cell> | |||||
<van-cell title="修改密码" is-link to="password"> | <van-cell title="修改密码" is-link to="password"> | ||||
<template #icon> | <template #icon> | ||||
<van-image | <van-image | ||||
@@ -0,0 +1,162 @@ | |||||
<template> | |||||
<div> | |||||
<van-nav-bar | |||||
title="电子签名" | |||||
left-arrow | |||||
@click-left="$router.back(-1)" | |||||
/> | |||||
<van-cell-group style="width: 96%;margin:2%;border-radius: 6px;overflow: hidden;padding-top: 10px;padding-bottom: 10px;box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.16);"> | |||||
<div class="signature-box"> | |||||
<vue-esign | |||||
ref="esign" | |||||
class="mySign" | |||||
:width="500" | |||||
:height="225" | |||||
:isCrop="signature.isCrop" | |||||
:lineWidth="signature.lineWidth" | |||||
:lineColor="signature.lineColor" | |||||
:bgColor.sync="signature.bgColor" | |||||
/> | |||||
</div> | |||||
<div class="signature-footer"> | |||||
<signatureUploadSignature @signaImg = "signaImgFun"/> | |||||
<van-button @click="handleGenerate" type="info" size="small"> 生成签字图片</van-button> | |||||
<van-button @click="handleReset" class="clearBtn" type="info" plain size="small">清空画板</van-button> | |||||
</div> | |||||
<div class="esigh-result"> | |||||
<img :src="signatureImg" class="imgs" v-if="signatureImg!=''"/> | |||||
</div> | |||||
</van-cell-group> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import vueEsign from 'vue-esign' | |||||
import {getToken} from "@/utils/auth"; | |||||
import axios from 'axios' | |||||
import { getUserProfile } from "@/api/lawEnforcement/index"; | |||||
import signatureUploadSignature from './signatureUploadSignature'; | |||||
export default { | |||||
name: "yinnongSignature", | |||||
components:{vueEsign,signatureUploadSignature}, | |||||
data() { | |||||
return { | |||||
signatureImg:'', | |||||
//上传图片 | |||||
uploadPictures:{ | |||||
action:process.env.VUE_APP_BASE_API+'/system/user/profile/electronicSignature', | |||||
headers: { Authorization: "Bearer " + getToken() }, | |||||
}, | |||||
//电子签名 | |||||
signature:{ | |||||
lineWidth: 6, // 画笔的线条粗细 | |||||
lineColor: "#000000", // 画笔的颜色 | |||||
bgColor: "", // 画布的背景颜色 | |||||
resultImg: "", // 最终画布生成的base64图片 | |||||
isCrop: false, // 是否裁剪,在画布设定尺寸基础上裁掉四周空白部分 | |||||
} | |||||
} | |||||
}, | |||||
mounted(){ | |||||
this.getUser(); | |||||
}, | |||||
methods:{ | |||||
getUser(){ | |||||
getUserProfile().then(response => { | |||||
const baseImgUrl = this.$store.getters.baseRoutingUrl; | |||||
this.signatureImg = baseImgUrl+response.data.electronicSignature | |||||
if(baseImgUrl==''){ | |||||
setTimeout(()=>{ | |||||
const baseImgUrl = this.$store.getters.baseRoutingUrl; | |||||
this.signatureImg = baseImgUrl+response.data.electronicSignature | |||||
},1000) | |||||
} | |||||
}); | |||||
}, | |||||
signaImgFun(url){ | |||||
this.signatureImg = url; | |||||
// console.log(url) | |||||
}, | |||||
// 清空画板 | |||||
handleReset() { | |||||
this.$refs.esign.reset(); | |||||
}, | |||||
// 生成签字图 | |||||
handleGenerate() { | |||||
this.$refs.esign | |||||
.generate() // 使用生成器调用把签字的图片转换成为base64图片格式 | |||||
.then((res) => { | |||||
console.log(res) | |||||
this.signature.resultImg = res; | |||||
let wj = this.dataURLtoBlob(res); | |||||
let param = new FormData() // 创建form对象 | |||||
param.append('electronicSignaturefile', wj) // 通过append向form对象添加数据 | |||||
let config = { | |||||
headers: this.uploadPictures.headers | |||||
} | |||||
// 添加请求头 | |||||
axios.post(this.uploadPictures.action, param, config) | |||||
.then(res => { | |||||
let content = res.data; | |||||
if(content.code == 200){ | |||||
const baseImgUrl = this.$store.getters.baseRoutingUrl; | |||||
this.signatureImg = baseImgUrl+content.esUrl; | |||||
} | |||||
}) | |||||
}) | |||||
.catch((err) => { | |||||
// 画布没有签字时会执行这里提示一下 | |||||
this.$toast.fail('请签名后再生成签字图片'); | |||||
}); | |||||
}, | |||||
dataURLtoBlob(dataurl) { | |||||
var arr = dataurl.split(','); | |||||
//注意base64的最后面中括号和引号是不转译的 | |||||
var _arr = arr[1].substring(0,arr[1].length-2); | |||||
var mime = arr[0].match(/:(.*?);/)[1], | |||||
bstr =atob(_arr), | |||||
n = bstr.length, | |||||
u8arr = new Uint8Array(n); | |||||
while (n--) { | |||||
u8arr[n] = bstr.charCodeAt(n); | |||||
} | |||||
return new Blob([u8arr], { | |||||
type: mime | |||||
}); | |||||
}, | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.signature-box{ | |||||
border:1px dashed #666; | |||||
margin:2px 20px; | |||||
} | |||||
.signature-footer{ | |||||
margin:15px 20px 0; | |||||
display: flex; | |||||
.clearBtn{ | |||||
margin-left: 15px; | |||||
} | |||||
} | |||||
.esigh-result{ | |||||
margin:15px 20px; | |||||
// height: 110px; | |||||
border:1px solid #666; | |||||
font-size: 0; | |||||
.imgs{ | |||||
width: 100%; | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,161 @@ | |||||
<template> | |||||
<div class="update_main"> | |||||
<van-button @click="editCropper" type="info" size="small">上传签字图片</van-button> | |||||
<van-popup v-model="open" position="bottom" :style="{ height: '60%' }"> | |||||
<div class="screenshots_main"> | |||||
<vue-cropper | |||||
ref="cropper" | |||||
:img="options.img" | |||||
:info="true" | |||||
:autoCrop="options.autoCrop" | |||||
:autoCropWidth="options.autoCropWidth" | |||||
:autoCropHeight="options.autoCropHeight" | |||||
:fixedBox="options.fixedBox" | |||||
@realTime="realTime" | |||||
v-if="visible" | |||||
/> | |||||
</div> | |||||
<div class="avatar-upload-main"> | |||||
<div class="avatar-upload-preview"> | |||||
<img :src="previews.url" :style="previews.img" /> | |||||
</div> | |||||
</div> | |||||
<div class="steup_main"> | |||||
<van-uploader :after-read="afterRead"> | |||||
<van-button icon="plus" type="primary" size="small">上传文件</van-button> | |||||
</van-uploader> | |||||
<van-button @click="changeScale(1)" icon="plus" size="small"></van-button> | |||||
<van-button @click="changeScale(-1)" icon="minus" size="small"></van-button> | |||||
<van-button @click="rotateLeft()" icon="replay" size="small" class="xzmt"></van-button> | |||||
<van-button @click="rotateRight()" icon="replay" size="small"></van-button> | |||||
<van-button @click="uploadImg" type="info" size="small">提交</van-button> | |||||
</div> | |||||
</van-popup> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { electronicSignature } from "@/api/lawEnforcement/index"; | |||||
import { VueCropper } from "vue-cropper"; | |||||
export default { | |||||
components: { VueCropper }, | |||||
data() { | |||||
return { | |||||
// 是否显示弹出层 | |||||
open: false, | |||||
// 是否显示cropper | |||||
visible: false, | |||||
// 弹出层标题 | |||||
title: "上传PNG签名图片", | |||||
options: { | |||||
img: '', //裁剪图片的地址 | |||||
autoCrop: true, // 是否默认生成截图框 | |||||
autoCropWidth: 244, // 默认生成截图框宽度 | |||||
autoCropHeight: 110, // 默认生成截图框高度 | |||||
fixedBox: true // 固定截图框大小 不允许改变 | |||||
}, | |||||
previews: {} | |||||
} | |||||
}, | |||||
created(){ | |||||
}, | |||||
methods:{ | |||||
// 编辑头像 | |||||
editCropper() { | |||||
this.open = true; | |||||
this.visible = true; | |||||
}, | |||||
// 实时预览 | |||||
realTime(data) { | |||||
this.previews = data; | |||||
}, | |||||
afterRead(file){ | |||||
this.options.img = file.content; | |||||
}, | |||||
// 图片缩放 | |||||
changeScale(num) { | |||||
num = num || 1; | |||||
this.$refs.cropper.changeScale(num); | |||||
}, | |||||
// 向左旋转 | |||||
rotateLeft() { | |||||
this.$refs.cropper.rotateLeft(); | |||||
}, | |||||
// 向右旋转 | |||||
rotateRight() { | |||||
this.$refs.cropper.rotateRight(); | |||||
}, | |||||
// 上传图片 | |||||
uploadImg() { | |||||
this.$refs.cropper.getCropBlob(data => { | |||||
let formData = new FormData(); | |||||
formData.append("electronicSignaturefile", data); | |||||
electronicSignature(formData).then(response => { | |||||
this.open = false; | |||||
this.options.img = this.$store.getters.baseRoutingUrl + response.esUrl; | |||||
this.$emit('signaImg', this.options.img) | |||||
// this.msgSuccess("修改成功"); | |||||
this.$toast.success('成功文案'); | |||||
this.visible = false; | |||||
}); | |||||
}); | |||||
}, | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.img-circle { | |||||
border-radius: 50%; | |||||
} | |||||
.img-lg { | |||||
width: 120px; | |||||
height: 120px; | |||||
} | |||||
.avatar-upload-main{ | |||||
position: relative; | |||||
width: 100%; | |||||
height: 160px; | |||||
} | |||||
.avatar-upload-preview { | |||||
position: absolute; | |||||
top: 50%; | |||||
transform: translate(50%, -50%); | |||||
width: 200px; | |||||
height: 200px; | |||||
border-radius: 50%; | |||||
box-shadow: 0 0 4px #ccc; | |||||
overflow: hidden; | |||||
} | |||||
.update_main{ | |||||
margin-right: 15px; | |||||
} | |||||
.screenshots_main{ | |||||
height: 350px; | |||||
padding:20px 20px 0; | |||||
} | |||||
.avatar-upload-preview{ | |||||
width: 244px; | |||||
height: 110px; | |||||
border-radius: 0; | |||||
left: 50%; | |||||
margin-left: -244px; | |||||
} | |||||
.steup_main{ | |||||
margin:0 20px; | |||||
text-align: center; | |||||
.xzmt{ | |||||
transform: rotate(180deg); | |||||
} | |||||
} | |||||
</style> |