You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

405 lines
11 KiB

2 years ago
<template>
<div class="page">
<div class="box" ref="box">
2 years ago
<div class="container" ref="container" :style="transform">
2 years ago
<div class="no">
2 years ago
序列号{{ info.shouquanshubianhao }}
2 years ago
</div>
<div class="qrcode">
<div ref="qrcode"></div>
2 years ago
<div style="padding-top: 2px;text-shadow: 1px 1px #ddd;">扫码核验</div>
2 years ago
</div>
<div class="title">
<span style="padding-right: 20px;"></span><span></span>
</div>
<div class="text">
2 years ago
兹有<span>{{ info.name }}</span>身份证号<span>{{ info.idcard }}</span>经苏州市总工会审核评定为{{ new Date().getFullYear() }}年度苏州市总工会<span>{{ info.kunnanleixing }}</span>
2 years ago
<template v-if="showChild">
<span>{{ printChild.name }}</span>身份证号码<span>{{ printChild.idcard }}</span>系其家庭成员
</template>
2 years ago
<br>
<p>特此证明</p>
<div class="stay">
<p>苏州市总工会权益保障部</p>
<p>{{ $moment(new Date()).format('YYYY年M月DD日') }}</p>
</div>
2 years ago
2 years ago
<img class="seal" :src="require('@/assets/seal.gif')" alt="">
2 years ago
</div>
</div>
</div>
2 years ago
<Button v-show="isReduction" class="reduction" size="small" type="info" @click="reduction"></Button>
2 years ago
<div class="bottom-panel">
2 years ago
<Button type="info" icon="md-download" @click="download"></Button>
<Button type="info" icon="md-print" @click="print"></Button>
2 years ago
</div>
</div>
</template>
<script>
2 years ago
import "jspdf/dist/polyfills.es"
2 years ago
import QRCode from 'qrcodejs2';
2 years ago
import html2canvas from "html2canvas";
import Jspdf from "jspdf";
import printJS from "print-js";
2 years ago
import { saveAs } from 'file-saver';
2 years ago
2 years ago
import { updateLog, userInfo } from "@/api/h5";
2 years ago
export default {
data() {
return {
info: {},
2 years ago
printChild: {},
2 years ago
container: {
w: 0,
h: 0,
offsetX: 0,
offsetY: 0,
lastX: 0,
lastY: 0,
scale: 1
2 years ago
},
isToImg: false,
type: new Map([
[1,'特别困难'],
[2,'深度困难'],
[3,'相对困难'],
[4,'意外至困']
])
2 years ago
}
},
methods: {
2 years ago
reduction () {
this.container.offsetY = 0;
this.container.offsetX = 0;
this.container.scale = 1;
},
2 years ago
creatQrCode() {
2 years ago
let { href } = this.$router.resolve({
path: this.$route.fullPath,
query: {
isQr: 1
}
});
2 years ago
let w = this.$refs['box']?.getBoundingClientRect()?.width;
2 years ago
new QRCode(this.$refs.qrcode, {
2 years ago
text: `${window.location.origin}${window.location.pathname}${href}`, // 二维码的内容
2 years ago
width: (w * 0.14) || 74,
height: (w * 0.14) || 74,
2 years ago
colorDark: '#000',
colorLight: '#fff',
correctLevel: QRCode.CorrectLevel.H
});
},
2 years ago
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";
},
2 years ago
init () {
const box = this.$refs['box'];
const container = this.$refs['container'];
const { width,height } = box.getBoundingClientRect();
this.container.w = width;
this.container.h = height;
2 years ago
this.setFontSize();
2 years ago
//
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);
}
},
2 years ago
download () {
this.isToImg = true;
html2canvas(this.$refs['container'],{
2 years ago
backgroundColor: '#ffffff',
2 years ago
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;
}
// 保存文件
2 years ago
//pdf.save(`困难职工证明-${this.info.name}.pdf`);
let file = pdf.output('blob',{
2 years ago
filename: `困难职工证明-${this.info.name}.pdf`,
type: 'application/pdf;charset=utf-8'
2 years ago
})
2 years ago
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();
2 years ago
}).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;}'
})
2 years ago
updateLog({
bianma: window.atob(this.$route.query.bm),
type: window.atob(this.$route.query.isChild) == 0 ? 1 : 2
})
2 years ago
}).catch(err => this.isToImg = true)
2 years ago
},
getPrintChild (childrens) {
const childId = window.atob(this.$route.query.isChild);
this.printChild = childrens.find(i => i.id == childId);
2 years ago
}
},
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
2 years ago
},
showChild () {
return window.atob(this.$route.query.isChild) != 0
2 years ago
}
2 years ago
},
created() {
2 years ago
if (this.$route.query.isQr && this.$route.query.bm) {
updateLog({
bianma: window.atob(this.$route.query.bm),
type: 3
})
}
2 years ago
},
mounted() {
if (this.$route.query.bm) {
userInfo({
bianma: window.atob(this.$route.query.bm)
2 years ago
}).then(res => {
console.log(res)
2 years ago
this.info = res.user;
2 years ago
2 years ago
this.getPrintChild(res.childrens);
2 years ago
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;
2 years ago
background: #eee;
2 years ago
overflow: hidden;
margin: auto;
.container {
width: 100%;
height: 100%;
2 years ago
background: #fff;
2 years ago
position: relative;
2 years ago
&-border {
border: .5px solid #333;
}
@mixin h1 {
font-weight: 900;
font-size: 2em;
text-align: center;
2 years ago
text-shadow: 1px 1px #ddd;
2 years ago
}
@mixin h2 {
font-weight: 500;
font-size: 1.2em;
text-align: center;
2 years ago
text-shadow: 1px 1px #ddd;
2 years ago
}
@mixin text {
2 years ago
text-shadow: 1px 1px #ddd;
2 years ago
font-size: 1.1em;
}
2 years ago
& > div {
position: absolute;
}
.no {
2 years ago
@include h2;
2 years ago
transform: translate(20px,20px);
}
.qrcode {
transform: translate(0px,20px);
2 years ago
right: 20px;
text-align: center;
}
.title {
@include h1;
transform: translate(-50%,0);
left: 50%;
2 years ago
top: 22.5%;
2 years ago
}
.text {
@include text;
word-spacing: 4px;
letter-spacing: 1px;
2 years ago
top: 35%;
2 years ago
padding: 0 5em;
text-indent: 2em;
2 years ago
line-height: 2.6;
word-break: break-all;
2 years ago
& > span {
text-decoration: underline;
}
}
.stay {
@include text;
2 years ago
line-height: 1.8;
2 years ago
text-align: right;
2 years ago
padding-top: 1em;
2 years ago
padding-right: 1em;
2 years ago
position: relative;
z-index: 1;
2 years ago
}
2 years ago
.seal {
right: 14%;
2 years ago
width: 7vw;
min-width: 50px;
2 years ago
object-fit: cover;
2 years ago
filter: saturate(1);
transform: translate(-1em,-4em);
2 years ago
2 years ago
z-index: 0;
2 years ago
position: absolute;
}
2 years ago
}
}
2 years ago
.reduction {
transform: translateX(-50%);
position: fixed;
left: 50%;
bottom: 60px;
}
2 years ago
.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>