个人名片+微信名片二维码 VUE

个人名片

功能:根据数据库查出个人数据,生成个人名片,名片中有个人二维码,微信扫描二维码可快速保存联系人信息到手机通讯录。

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,还请大家多多指点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简介:成都壹立科技有限公司(简称壹立科技)是一家人专注于人工智能和的互联网驱动型的技术公司,致力于帮助企业和个体品牌进行智能化升级和营销曝光。   壹立科技自主研发的FCRM-壹脉智能名片系统,即营销获客的CRM运营管理系统,将全方位提升企业销售及销售管理能力。   该系统以大数据和人工智能技术为驱动,以小程序为技术应用入口,包含六大核心产品:微官网、智能名片、分销商城、营销裂变系统、智能CRM管理系统、在线预约系统,围绕四大核心- 即:   企业如何流量。打通流量,真实流量智能分发;   数据智能预测。智能预测客户行为,优化蓄客与跟进;   营销传播裂变。分销、预约、激励客户参与卖货,人人销售;   成单达成。达成客户转化,实现客户私有化。   系统操作简单、使用方便,能快速为企业搭建起集销售、服务、品牌建设于一体的用户超级入口,帮助企业实现销售全流程与客户全生命周期的自动化、数字化管理。  壹脉智能销售系统具有人力成本低、效率高、信息全、模板丰富等特点,适用于几乎所有有销售需求的场景和企业,尤其是高客单、低频次消费群的商户,如房产、教育、金融、汽车、婚庆、医疗等。 名片小程序 · 1.【新】聊天功能开关判断,如果crm小程序没有设置开启,则不能进行聊天。 · 2.【优化】登录改版 · 2.1.用户中心添加登录操作,未登录时操作其他功能提示请登录。 · 2.2.搜索进入小程序,未登录返回默认名片,点击我的,到达个人中心进行登录; · 2.3.分享的名片进入,查看名片的信息,但是操作其他的提示到个人中心去登录; · 2.4.通过推送消息进入小程序,没有任何数据,提示需要达到个人中登录,点击我的到达个人中心进行登录。 · 2.5.聊天功能开关判断,如果crm小程序没有设置开启,则不能进行聊天。 · 3.【优化】编辑名片默认头像修改,圆形修改成方形 · 4.【优化】通过推送消息进入名片小程序消息模块,看不到数据,删除小程序,重新打开不再重现 · 5.【优化】错误文字修改: 我的卡卷 -> 我的卡券 · 6.【优化】用户端-商城页 商品描述文字用省略号表示后 文字还是溢出 之后 价格不展示了 并且代表价格的字符变小了 crm 小程序 · 1.【新】添加IM咨询开关功能 · 2.【优化】登录改版,默认进入雷达页面,获取数据时提示其登录,如果暂时不登录,则不返回数据,下次再获取时,又提示其登录 · 3.【优化】通过推送消息进入crm消息模块,看不到数据,删除小程序,重新打开不再重现 · 4.【优化】新用户创建名片后,CRM里“我的”中分享出来的名片是打开查看不了该名片信息。 · 5.【优化】修复新增客户的手机号不支持4,6,9这三种情况 · 6.【优化】修复添加商品介绍的字数不满足60个长度的问题 后端代码 · 1.【新增】不登录查看默认名片列表接口 · 2.【新增】不登录查看名片详情接口 · 3.【新增】企业模块配置功能 · 4.【优化】服务器内存占用过多 · 5.【优化】变更数据的操作,加上事务保证 · 6.【优化】修改可能存在并发的bug · 7.【优化】修改查询企业账号sql语句错误bug 适用范围: 销售行业、房产、教育、金融、汽车、婚庆、医疗等。 运行环境: JAVA+Spring Cloud +VUE+ MySql +Redis +OSS +小程序+PC

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值