|
|
<template>
|
|
|
<div class="page">
|
|
|
<div class="box" ref="box">
|
|
|
<div class="container" ref="container" :style="transform">
|
|
|
<div class="no">
|
|
|
序列号:{{ info.shouquanshubianhao }}
|
|
|
</div>
|
|
|
<div class="qrcode">
|
|
|
<div ref="qrcode"></div>
|
|
|
<div style="padding-top: 2px;text-shadow: 1px 1px #ddd;">扫码核验</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="title">
|
|
|
<span style="padding-right: 20px;">证</span><span>明</span>
|
|
|
</div>
|
|
|
|
|
|
<div class="text">
|
|
|
兹有<span>{{ info.name }}</span>(身份证号:<span>{{ info.idcard }}</span>)经苏州市总工会审核评定为{{ new Date().getFullYear() }}年度苏州市总工会<span>{{ info.kunnanleixing }}</span> 。
|
|
|
<template v-if="showChild">
|
|
|
<span>{{ printChild.name }}</span>(身份证号码:<span>{{ printChild.idcard }}</span>)系其家庭成员。
|
|
|
</template>
|
|
|
<br>
|
|
|
<p>特此证明!</p>
|
|
|
|
|
|
<div class="stay">
|
|
|
<p>苏州市总工会权益保障部</p>
|
|
|
<p>{{ $moment(new Date()).format('YYYY年M月DD日') }}</p>
|
|
|
</div>
|
|
|
|
|
|
<img class="seal" :src="require('@/assets/seal.gif')" alt="">
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<Button v-show="isReduction" class="reduction" size="small" type="info" @click="reduction">还原</Button>
|
|
|
|
|
|
<div class="bottom-panel">
|
|
|
<Button type="info" icon="md-download" @click="download">下载</Button>
|
|
|
<Button type="info" icon="md-print" @click="print">打印</Button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import "jspdf/dist/polyfills.es"
|
|
|
import QRCode from 'qrcodejs2';
|
|
|
import html2canvas from "html2canvas";
|
|
|
import Jspdf from "jspdf";
|
|
|
import printJS from "print-js";
|
|
|
import { saveAs } from 'file-saver';
|
|
|
|
|
|
import { updateLog, userInfo } from "@/api/h5";
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
info: {},
|
|
|
printChild: {},
|
|
|
container: {
|
|
|
w: 0,
|
|
|
h: 0,
|
|
|
offsetX: 0,
|
|
|
offsetY: 0,
|
|
|
lastX: 0,
|
|
|
lastY: 0,
|
|
|
scale: 1
|
|
|
},
|
|
|
isToImg: false,
|
|
|
type: new Map([
|
|
|
[1,'特别困难'],
|
|
|
[2,'深度困难'],
|
|
|
[3,'相对困难'],
|
|
|
[4,'意外至困']
|
|
|
])
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
reduction () {
|
|
|
this.container.offsetY = 0;
|
|
|
this.container.offsetX = 0;
|
|
|
this.container.scale = 1;
|
|
|
},
|
|
|
|
|
|
creatQrCode() {
|
|
|
let { href } = this.$router.resolve({
|
|
|
path: this.$route.fullPath,
|
|
|
query: {
|
|
|
isQr: 1
|
|
|
}
|
|
|
});
|
|
|
let w = this.$refs['box']?.getBoundingClientRect()?.width;
|
|
|
new QRCode(this.$refs.qrcode, {
|
|
|
text: `${window.location.origin}${window.location.pathname}${href}`, // 二维码的内容
|
|
|
width: (w * 0.14) || 74,
|
|
|
height: (w * 0.14) || 74,
|
|
|
colorDark: '#000',
|
|
|
colorLight: '#fff',
|
|
|
correctLevel: QRCode.CorrectLevel.H
|
|
|
});
|
|
|
},
|
|
|
|
|
|
setFontSize () {
|
|
|
const box = this.$refs['box'];
|
|
|
const container = this.$refs['container'];
|
|
|
|
|
|
const baseSize = 15;
|
|
|
const scale = box.getBoundingClientRect().width / 600;
|
|
|
container.style.fontSize = baseSize * Math.min(scale, 2) + "px";
|
|
|
},
|
|
|
init () {
|
|
|
const box = this.$refs['box'];
|
|
|
const container = this.$refs['container'];
|
|
|
const { width,height } = box.getBoundingClientRect();
|
|
|
this.container.w = width;
|
|
|
this.container.h = height;
|
|
|
this.setFontSize();
|
|
|
//
|
|
|
box.ontouchstart = box.onmousedown = event => {
|
|
|
event.preventDefault();
|
|
|
if (event.type === 'touchstart') {
|
|
|
let touch = event.touches[0];
|
|
|
this.container.lastX = touch.clientX;
|
|
|
this.container.lastY = touch.clientY;
|
|
|
} else {
|
|
|
this.container.lastX = event.clientX;
|
|
|
this.container.lastY = event.clientY;
|
|
|
}
|
|
|
box.ontouchmove = box.onmousemove = e => {
|
|
|
let currentX,currentY;
|
|
|
if (e.type === 'touchmove') {
|
|
|
let touch = e.touches[0];
|
|
|
currentX = touch.clientX;
|
|
|
currentY = touch.clientY;
|
|
|
} else {
|
|
|
currentX = e.clientX;
|
|
|
currentY = e.clientY;
|
|
|
}
|
|
|
this.container.offsetX += currentX - this.container.lastX;
|
|
|
this.container.offsetY += currentY - this.container.lastY;
|
|
|
this.container.lastX = currentX;
|
|
|
this.container.lastY = currentY;
|
|
|
}
|
|
|
}
|
|
|
box.ontouchend = box.onmouseup = e => {
|
|
|
box.ontouchmove = box.onmousemove = null;
|
|
|
}
|
|
|
box.onwheel = e => {
|
|
|
e.preventDefault();
|
|
|
this.container.scale *= Math.exp(e.deltaY / -100);
|
|
|
}
|
|
|
},
|
|
|
|
|
|
download () {
|
|
|
this.isToImg = true;
|
|
|
html2canvas(this.$refs['container'],{
|
|
|
backgroundColor: '#ffffff',
|
|
|
allowTaint: false,
|
|
|
taintTest: false,
|
|
|
logging: false,
|
|
|
useCORS: true,
|
|
|
dpi: window.devicePixelRatio || 1,
|
|
|
scale: 3 // 按比例增加分辨率
|
|
|
}).then(cnv => {
|
|
|
this.isToImg = false;
|
|
|
|
|
|
const pdf = new Jspdf('p','mm','a4');
|
|
|
const ctx = cnv.getContext('2d');
|
|
|
let a4w = 190;
|
|
|
let a4h = 277; // A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
|
|
|
let imgHeight = Math.floor(a4h * cnv.width / a4w); // 按A4显示比例换算一页图像的像素高度
|
|
|
let renderedHeight = 0;
|
|
|
while (renderedHeight < cnv.height) {
|
|
|
let page = document.createElement('canvas');
|
|
|
page.width = cnv.width;
|
|
|
page.height = Math.min(imgHeight, cnv.height - renderedHeight);// 可能内容不足一页
|
|
|
|
|
|
// 用getImageData剪裁指定区域,并画到前面创建的canvas对象中
|
|
|
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, cnv.width, Math.min(imgHeight, cnv.height - renderedHeight)), 0, 0);
|
|
|
pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); // 添加图像到页面,保留10mm边距
|
|
|
|
|
|
renderedHeight += imgHeight;
|
|
|
if (renderedHeight < cnv.height) {
|
|
|
pdf.addPage();// 如果后面还有内容,添加一个空页
|
|
|
}
|
|
|
// delete page;
|
|
|
}
|
|
|
// 保存文件
|
|
|
//pdf.save(`困难职工证明-${this.info.name}.pdf`);
|
|
|
let file = pdf.output('blob',{
|
|
|
filename: `困难职工证明-${this.info.name}.pdf`,
|
|
|
type: 'application/pdf;charset=utf-8'
|
|
|
})
|
|
|
let blob = new Blob([file], {type: 'application/pdf'});
|
|
|
let reader = new FileReader();
|
|
|
let filename = `困难职工证明-${this.info.name}.pdf`
|
|
|
reader.onloadend = function() {
|
|
|
let a = document.createElement('a');
|
|
|
a.href = reader.result;
|
|
|
a.download = filename;
|
|
|
a.click();
|
|
|
}
|
|
|
reader.readAsDataURL(blob);
|
|
|
// console.log(file)
|
|
|
// saveAs(file,`困难职工证明-${this.info.name}.pdf`)
|
|
|
// let a = document.createElement('a');
|
|
|
// a.href = window.URL.createObjectURL(file);
|
|
|
// a.download = `困难职工证明-${this.info.name}.pdf`;
|
|
|
// a.click();
|
|
|
}).catch(err => {
|
|
|
this.isToImg = false;
|
|
|
})
|
|
|
},
|
|
|
print () {
|
|
|
this.isToImg = true;
|
|
|
html2canvas(this.$refs['container'],{
|
|
|
backgroundColor: null,
|
|
|
allowTaint: false,
|
|
|
taintTest: false,
|
|
|
logging: false,
|
|
|
useCORS: true,
|
|
|
dpi: window.devicePixelRatio || 1,
|
|
|
scale: 3 // 按比例增加分辨率
|
|
|
}).then(cnv => {
|
|
|
this.isToImg = false;
|
|
|
printJS({
|
|
|
printable: cnv.toDataURL(),
|
|
|
type: 'image',
|
|
|
documentTitle: `困难职工证明-${this.info.name}`,
|
|
|
style: '@page{margin: 0 10mm;}'
|
|
|
})
|
|
|
updateLog({
|
|
|
bianma: window.atob(this.$route.query.bm),
|
|
|
type: window.atob(this.$route.query.isChild) == 0 ? 1 : 2
|
|
|
})
|
|
|
}).catch(err => this.isToImg = true)
|
|
|
},
|
|
|
|
|
|
getPrintChild (childrens) {
|
|
|
const childId = window.atob(this.$route.query.isChild);
|
|
|
this.printChild = childrens.find(i => i.id == childId);
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
transform () {
|
|
|
if (this.isToImg) return {};
|
|
|
return { 'transform': `translate(${this.container.offsetX}px,${this.container.offsetY}px) scale(${this.container.scale},${this.container.scale})` }
|
|
|
},
|
|
|
isReduction () {
|
|
|
return this.container.offsetX !== 0 || this.container.offsetY !== 0 || this.container.scale !== 1
|
|
|
},
|
|
|
showChild () {
|
|
|
return window.atob(this.$route.query.isChild) != 0
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
if (this.$route.query.isQr && this.$route.query.bm) {
|
|
|
updateLog({
|
|
|
bianma: window.atob(this.$route.query.bm),
|
|
|
type: 3
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
if (this.$route.query.bm) {
|
|
|
userInfo({
|
|
|
bianma: window.atob(this.$route.query.bm)
|
|
|
}).then(res => {
|
|
|
console.log(res)
|
|
|
this.info = res.user;
|
|
|
|
|
|
this.getPrintChild(res.childrens);
|
|
|
this.init();
|
|
|
this.creatQrCode();
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
.page {
|
|
|
height: 100%;
|
|
|
width: 100%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
background: rgb(80,80,80);
|
|
|
}
|
|
|
.box {
|
|
|
width: 100vw;
|
|
|
height: 100vh;
|
|
|
max-width: 600px;
|
|
|
max-height: 800px;
|
|
|
background: #eee;
|
|
|
overflow: hidden;
|
|
|
|
|
|
margin: auto;
|
|
|
|
|
|
.container {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background: #fff;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
&-border {
|
|
|
border: .5px solid #333;
|
|
|
}
|
|
|
@mixin h1 {
|
|
|
font-weight: 900;
|
|
|
font-size: 2em;
|
|
|
text-align: center;
|
|
|
text-shadow: 1px 1px #ddd;
|
|
|
}
|
|
|
@mixin h2 {
|
|
|
font-weight: 500;
|
|
|
font-size: 1.2em;
|
|
|
text-align: center;
|
|
|
text-shadow: 1px 1px #ddd;
|
|
|
}
|
|
|
@mixin text {
|
|
|
text-shadow: 1px 1px #ddd;
|
|
|
font-size: 1.1em;
|
|
|
}
|
|
|
& > div {
|
|
|
position: absolute;
|
|
|
}
|
|
|
.no {
|
|
|
@include h2;
|
|
|
transform: translate(20px,20px);
|
|
|
}
|
|
|
.qrcode {
|
|
|
transform: translate(0px,20px);
|
|
|
right: 20px;
|
|
|
text-align: center;
|
|
|
}
|
|
|
.title {
|
|
|
@include h1;
|
|
|
transform: translate(-50%,0);
|
|
|
left: 50%;
|
|
|
top: 22.5%;
|
|
|
}
|
|
|
.text {
|
|
|
@include text;
|
|
|
word-spacing: 4px;
|
|
|
letter-spacing: 1px;
|
|
|
top: 35%;
|
|
|
padding: 0 5em;
|
|
|
text-indent: 2em;
|
|
|
line-height: 2.6;
|
|
|
word-break: break-all;
|
|
|
|
|
|
& > span {
|
|
|
text-decoration: underline;
|
|
|
}
|
|
|
}
|
|
|
.stay {
|
|
|
@include text;
|
|
|
line-height: 1.8;
|
|
|
text-align: right;
|
|
|
|
|
|
padding-top: 1em;
|
|
|
padding-right: 1em;
|
|
|
position: relative;
|
|
|
z-index: 1;
|
|
|
}
|
|
|
.seal {
|
|
|
right: 14%;
|
|
|
width: 7vw;
|
|
|
min-width: 50px;
|
|
|
object-fit: cover;
|
|
|
filter: saturate(1);
|
|
|
transform: translate(-1em,-4em);
|
|
|
|
|
|
z-index: 0;
|
|
|
position: absolute;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.reduction {
|
|
|
transform: translateX(-50%);
|
|
|
position: fixed;
|
|
|
left: 50%;
|
|
|
bottom: 60px;
|
|
|
}
|
|
|
.bottom-panel {
|
|
|
height: 50px;
|
|
|
background: rgba(55,55,55,.6);
|
|
|
display: flex;
|
|
|
justify-content: space-evenly;
|
|
|
align-items: center;
|
|
|
transition: all .2s;
|
|
|
|
|
|
position: fixed;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
|
|
|
& > Button {
|
|
|
min-width: 90px;
|
|
|
max-width: 150px;
|
|
|
width: 16%;
|
|
|
}
|
|
|
}
|
|
|
</style>
|