个人名片
功能:根据数据库查出个人数据,生成个人名片,名片中有个人二维码,微信扫描二维码可快速保存联系人信息到手机通讯录。
vue中引入html2canvas实现将整块dom进行图片化
- 引包
npm install --save html2canvas
- 引入相关文件(在我的资源中有)
<template>
<div class="container">
<!--v-loading.fullscreen.lock 加载动画-->
<div class="cardWrap" v-loading.fullscreen.lock="loading" element-loading-text="加载后,长按图片分享">
<div class="card" ref="cardCanvas">
<div class="card-info">
<div class="card-imgwrap">
<div class="card-empty" >
<img class="card-empty-img1" src="../assets/logo3.png" />
</div>
</div>
<div class="card-detail">
<!--姓名-->
<div class="name" v-model="user.ZUSERID">{
{user.ZUSERNAME}}</div>
<!--职位-->
<div class="position" v-if="this.user.ZGSDMB == ''" style="font-weight: bold;">{
{user.ZZHIWU}}</div>
<!--公司-->
<div class="companyName" >{
{user.ZGSMCA}}</div>
<!--公司-->
<div class="companyName" >{
{user.ZGSMCB}}</div>
<!--职位2-->
<!--<div class="position">职务2:{
{user.ZZHIWU2}}</div>-->
<div class="address" >地址:{
{user.ZGSDZA}}</div>
<div class="Tel" >电话:{
{user.ZTELE}}</div>
<div class="e-mail" >邮箱:{
{user.ZMAILBOX}}</div>
<div class="e-ZURL" >网址:{
{user.ZURL}}</div>
<!--二维码按钮,点击时生成二维码,在下面设置自动触发-->
<button id="btn" hidden="hidden">二维码</button>
</div>
<!--编辑页面-->
<!--
弹出dialog对话框,
:visible.sync="dialogVisible" 需要设置visible的sync属性,它接收Boolean,当为true时显示 Dialog。
:before-close 点击x号时,提示信息
slot="footer" 页脚信息
-->
<el-dialog title="编辑个人信息" :visible.sync="dialogFormVisible" width="90%" :fullscreen= "true"
:close-on-click-modal="false" :show-close = "false">
<el-form class="dialogfrom" >
<el-form-item label="姓名:":label-width="formLabelWidth">
<el-input v-model="user.ZUSERNAME" autocomplete="off" minlength="16" maxlength="19" ></el-input>
</el-form-item>
<el-form-item label="公司:" :label-width="formLabelWidth">
<el-select v-model="user.ZGSDMA"
placeholder="请输入公司"
style="width: 100%;">
<el-option v-for="(item,index) in companys" :key="index" :label="item.ZDESC" :value="item.ZVALUE">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="职位:" :label-width="formLabelWidth">
<el-input v-model="user.ZZHIWU" autocomplete="off" minlength="16" maxlength="19" ></el-input>
</el-form-item>
<el-form-item label="公司2:" :label-width="formLabelWidth">
<el-select v-model="user.ZGSDMB"
placeholder="请输入公司2"
style="width: 100%;">
<el-option v-for="(item,index) in companys" :key="index" :label="item.ZDESC" :value="item.ZVALUE">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="职位2:" :label-width="formLabelWidth">
<el-input v-model="user.ZZHIWU2" autocomplete="off" minlength="16" maxlength="19" ></el-input>
</el-form-item>
<el-form-item label="电话:" :label-width="formLabelWidth">
<el-input v-model="user.ZTELE" autocomplete="off" minlength="16" maxlength="19" ></el-input>
</el-form-item>
<el-form-item label="邮箱:" :label-width="formLabelWidth">
<el-input v-model="user.ZMAILBOX" autocomplete="off" minlength="16" maxlength="19" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveCard" size="small">确 定</el-button>
</div>
</el-dialog>
</div>
<!--jh静态图片-->
<div ref="jhImg">
<img src="../assets/jhImg.jpeg" style="width: 100%;margin-bottom: -6px;">
</div>
<!--二维码-->
<div class="card-code" v-if="cardSaveTxtStatus === 1">
<!--响应性式布局,两行四列-->
<!--第一行-->
<el-row :gutter="10">
<el-col :xs="3" :sm="3" :md="4" :lg="3" :xl="1">
<div class="grid-content"></div>
</el-col>
<el-col :xs="9" :sm="9" :md="8" :lg="9" :xl="11">
<div class="grid-content" id="qrcode">
<img id="qrCodeIco" src="../assets/logo8.jpg" style="position: absolute;width: 20px; height: 20px; margin: 25.5px;" />
</div>
</el-col>
<el-col :xs="9" :sm="9" :md="8" :lg="9" :xl="11">
<div class="grid-content">
<img class="officialWebsite" src="../assets/官网.png">
</div>
</el-col>
<el-col :xs="3" :sm="3" :md="4" :lg="3" :xl="1">
<div class="grid-content"></div>
</el-col>
</el-row>
<!--第二行-->
<el-row :gutter="10">
<el-col :xs="0" :sm="1" :md="4" :lg="3" :xl="1">
<div class="grid-content"></div>
</el-col>
<el-col :xs="12" :sm="11" :md="8" :lg="9" :xl="11">
<span class="grid-content">长按识别添加至通讯录</span>
</el-col>
<el-col :xs="9" :sm="9" :md="8" :lg="9" :xl="11">
<span class="grid-content">长按识别关注官微</span>
</el-col>
<el-col :xs="3" :sm="3" :md="4" :lg="3" :xl="1">
<div class="grid-content"></div>
</el-col>
</el-row>
<div ref="cloudImg">
<img src="../assets/云彩.png" style="width: 100%;margin-bottom: -6px;">
</div>
</div>
<!--ref='cardSave'获取这个dom元素,保存图片的时候,把该dom除外-->
<!--<div class="card-share" ref='cardShare'>
<div class="card-shareTxt" @click="saveImage">分享</div>
</div>-->
<div class="card-share" ref='cardShare'>
<div class="card-shareTxt" v-if="cardSaveTxtStatus === 1" @click="editCard">编辑</div>
<div class="card-shareTxt" v-if="cardSaveTxtStatus === 2" @click="saveCard">保存</div>
</div>
<div class="card-save" ref='cardSave'>
<!--<div class="card-saveTxt" v-if="cardSaveTxtStatus === 1" @click="editCard()">编辑</div>-->
<div class="card-saveTxt" @click="saveImage">分享</div>
</div>
</div>
</div>
</div>
</template>
<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/qrcode.js"></script>
<script src="../../static/js/kk-1.3.10.min.js"></script>
<script>
import html2canvas from 'html2canvas';
import axiosInstance from "../utils/request";
export default {
name: "MyCard",
inject: ['reload'],
data: function () {
return {
loading: false,
vision: "",
formLabelWidth: '60px', //form的宽度
dialogFormVisible: false, // 弹出框标记位
option: [{
ZVALUE: '', // 代码
ZDESC: '' // 名称
}],
QrImg: "", //二维码地址
position: "",
companyCode:'',
company_:'',
zgsdma:'',
//下拉数据
companys: [],//公司,jsonarray
user: {
},//用户信息,jsonobject
zhiwu:'',
selected:"",
dataURL: '',
cardUserName: '', // 当前商户的昵称
currentQrCode: '', // 当前名片的二维码数据
cardSaveTxtStatus: 1, // 名片右上角编辑按钮状态 1-不可编辑 2-可编辑
form: {
region: {
"re" : ["asdf"]
}
}
}
},
methods:{
/*一进个人名片发送查询请求*/
created(){
// 获取到员工号,存到浏览器的session
const customUser = sessionStorage.getItem('user');
axiosInstance.post("/mycard/select",
// kk员工号 100267
[{
ZFIELD: "ZUSERID",ZVALUE: "100942"}],
{
headers: {
'Content-Type': 'application/json'}}).then(result =>{
this.user = result.data.data.userList[0];
// jQuery生成二维码
var name, company, title, address, mobile, email, web, desc;
let u = this.user;
$("#btn").one("click",function() {
name = "FN:" + u.ZUSERNAME + "\n"; //姓名
company = "ORG:" + u.ZGSMCA + "\n"; //公司
title = "TITLE:" + u.ZZHIWU + "\n"; //职务
address = "ADR;WORK:" + u.ZGSDZA + "\n"; //地址
mobile = "TEL;TYPE=work:" + u.ZTELE + "\n"; //手机
email = "EMAIL;TYPE=pref:" + u.ZMAILBOX + "\n"; //邮箱
//web = "URL:" + u.ZURL + "\n"; //网址
var info = "BEGIN:VCARD\n" + name + company + title + email + mobile + address + "END:VCARD";
//生成二维码
var qrcode = new QRCode("qrcode");
qrcode.makeCode(info);
// var margin = ($("#qrcode").width() - $("#qrCodeIco").width()) / 2; //控制Logo图标的位置
// $("#qrCodeIco").css("margin", 25.5px);
//
$("#qrcode img:not('#qrCodeIco')").css("width","70px");
})
//id为btn的按钮,自动触发点击事件
$("#btn").trigger("click");
})
},
/* 保存图片的方法(即按钮点击触发的方法)
第一个参数为需要保存的div的id名
第二个参数为保存图片的名称 */
saveImage(){
this.loading = true;
// cardCanvas要生成图片的dom元素,cardSave要剔除的dom元素
let canvasID = this.$refs.cardCanvas
let removeDiv = this.$refs.cardSave
let removeDiv2 = this.$refs.cardShare
canvasID.removeChild(removeDiv);
canvasID.removeChild(removeDiv2);
/*把对应的dom生成图片*/
html2canvas(canvasID, {
backgroundColor: null // 解决生成的图片有白边
}).then(canvas => {
canvasID.appendChild(removeDiv)
canvasID.appendChild(removeDiv2)
// 返回图片的二进制数据
let dataURL = canvas.toDataURL('image/png');
this.dataURL = dataURL
//console.log(dataURL);
console.log(this.user.ZUSERID);
this.vision = Math.random().toString(12).substr(2);
console.log(this.vision);
// 把图片保存到服务器
axiosInstance.post("/mycard/getImg",
{
binaryImg:this.dataURL, userId:this.user.ZUSERID ,vision:this.vision},
{
headers: {
'Content-Type': 'application/json'}}).then(result =>{
//console.log('地址'+'http://zmsg.jangho.com:8085/image/'+this.user.ZUSERID+this.vision+'.jpg')
//this.vision = this.vision+1;
//console.log('地址'+'http://zmsg.jangho.com:8085/image/'+this.user.ZUSERID+this.vision+'.jpg')
this.loading = false;
// kk中分享图片
kk.media.previewImage({
paths: [
'http://zmsg.jangho.com:8085/image/'+this.user.ZUSERID+this.vision+'.jpg',
],
operations: true
}, function(code, msg){
this.vision = this.vision+1;
alert('错误信息:' + msg + ',错误代码:' + code);
});
this.vision = this.vision+1;
});
//保存到本地(手机上)
//this.saveFile(dataURL, 'wahaha')
})
},
editCard () {
// 点击编辑按钮
// 显示dialog
this.dialogFormVisible = true;
this.cardSaveTxtStatus = 2;
// 公司名称和公司代码查询
axiosInstance.post("/mycard/dropDown","",{
headers: {
'Content-Type': 'application/json'}}).then(result =>{
this.companys = result.data.data.company;
})
},
open(msg) {
this.$confirm('您暂未填写'+msg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success', message: '请再次填写!'});
})},
saveCard () {
// 点击保存按钮
this.cardSaveTxtStatus = 1;
let msg = "";
let flag = 0; //flag = 1 需要跳出提醒
if (this.user.ZGSDMB != "" && this.user.ZZHIWU2 == ""){
msg = msg.concat(" 职位2");
flag = 1;
}
if (this.user.ZGSDMB == "" && this.user.ZZHIWU2 != ""){
msg = msg.concat(" 公司2");
flag = 1;
}
if (this.user.ZUSERNAME == ""){
msg = msg.concat(" 姓名");
flag = 1;
};
if (this.user.ZGSDMA == ""){
msg = msg.concat(" 公司");
flag = 1;
};
if (this.user.ZZHIWU == ""){
msg = msg.concat(" 职务1");
flag = 1;
};
if (this.user.ZTELE == ""){
msg = msg.concat(" 电话");
flag = 1;
};
if (this.user.ZMAILBOX == ""){
msg = msg.concat(" 邮箱");
flag = 1;
};
if(flag == 1){
//开启消息提示框
//this.$toast.fail(msg+"不能为空!")
this.open(msg);
}else if(flag == 0){
//关闭消息提示框
axiosInstance.post("/mycard/update",
[this.user],
{
headers: {
'Content-Type': 'application/json'}}).then(result =>{
this.created();
this.dialogFormVisible = false;
// console.log(result.data.data.promptMsg[0].MSGTX);
});
}
},
saveFile (data, filename) {
let saveLink = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
saveLink.href = data
saveLink.download = filename
let event = document.createEvent('MouseEvents')
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
saveLink.dispatchEvent(event)
}
},
mounted() {
// 生命周期创建时
this.created();
}
}
</script>
<style scoped>
.container {
width: 100%;
height: calc((100vh - 40px));
background: #fff;
}
.container img[lazy=loading] {
padding: 40%;
}
/* .container img {
width: 100%;
}*/
.officialWebsite{
width: 70px;
}
.companyName{
font-weight: bold;
}
.cardImg{
}
#qrcode img{
display: block;
width: 70px;
}
#btn{
width:100px;
height:40px;
text-align: center;
line-height: 40px;
background: #6c0;
}
.cardWrap {
padding: 10px 6% 10px;
background: #fff;
}
.card {
position: relative;
}
.card-info {
background-color: #f7f5f6;
padding: 30px 0 30px 5px;
}
.card-bottom {
height: 46px;
padding: 5px 0;
background: linear-gradient(to right, #63a3d1, #c8e5f1);/*渐变色*/
color: #fff;
text-align: center;
font-size: 12px;
box-sizing: border-box;
}
.card-bottom .txt {
width: 200px;
line-height: 18px;
}
.card-save {
position: absolute;
right: 0;
top: 0px;
width: 0;
height: 0;
font-size: 10px;
color: #fff;
border-width: 0px 45px 45px 0;
border-style: solid;
border-color: transparent #009900;
}
.card-share {
position: absolute;
left: 0;
top: 0px;
width: 0;
height: 0;
font-size: 10px;
color: #fff;
border-width: 0px 0 45px 45px;
border-style: solid;
border-color: transparent #009900;
}
.card-saveTxt {
width: 45px;
height: 45px;
transform-origin: bottom center;
transform: rotate(45deg);
position: absolute;
display: inline-block;
width: 45px;
right: -37px;
top: 3px;
}
.card-shareTxt {
width: 45px;
height: 45px;
-webkit-transform-origin: bottom center;
transform-origin: bottom center;
-webkit-transform: rotate(
275deg
);
transform: rotate(
315deg
);
position: absolute;
display: inline-block;
width: 45px;
right: -25px;
top: -12px;
}
/*.cardWrap-txt {
margin-top: 8px;
font-size: 14px;
line-height: 20px;
color: #333333;
text-align: center;
}
.cardWrap-txt .grey {
margin: 5px 0 0 0;
color: #111111;
font-weight: bold;
}*/
.card-code {
background-color: #eeeced;
/*position: absolute;*/
right: 4%;
bottom: -12px;
/*color: #fff;*/
font-size: 12px;
text-align: center;
}
.qrcode {
display: inline-block;
height: 54px;
width: 54px;
line-height: 54px;
text-align: center;
background: #fff;
}
.qrcode img {
height: 48px;
width: 48px;
vertical-align: middle;
}
.grid-content {
font-size: 12px;
color: grey;
border-radius: 4px;
min-height: 36px;
}
.triangle-up {
display: inline-block;
margin-right: 4px;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid #fff;
}
.card-imgwrap{
width: 65px;
height: 86px;
float: left;
margin-right:10px;
}
.card-imgwrap>img{
width: 100%;
height: 100%;
}
.card-empty {
height: 100%;
background: #f7f5f6;
text-align: center;
color: #333;
font-size: 10px;
vertical-align: middle
}
.card-empty .card-empty-img1{
margin-top: 45px;
width: 99px;
}
.card-empty{
margin-top:10px;
width: 92px;
}
.card-detail{
color: #666;
font-size: 10px;
line-height: 19px;
padding-left: 32px;
overflow: hidden;
}
.card-detail img{
width: 12px;
vertical-align: middle;
}
.name{
font-size: 18px;
line-height: 26px;
font-weight: bold;
}
.card-detail .name .card-detail .tel{
color:#333
}
.card-detail .edit-name{
z-index:999;
}
.card-switch{
top: 15px;
line-height:13px;
font-size: 13px;
position: relative;
}
.address{
display: inline-block;
}
.el-input {
position: relative;
font-size: 14px;
width: 120px;
display: inline-block;
width: 70%;
height: 70%;
}
.el-input--suffix .el-input__inner {
padding-right: 13px;
height: 80%;
}
.el-dialog__headerbtn .el-dialog__close {
display: none;
}
.el-input__inner {
-webkit-appearance: none;
background-color: #FFF;
background-image: none;
border-radius: 4px;
border: 1px solid #DCDFE6;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #606266;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
outline: 0;
padding: 11px 15px;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
width: 135%;
}
</style>
<style>
.el-message-box {
width: 260px;
}
</style>
第一次写vue,还请大家多多指点。