GitBucket
4.23.0
Toggle navigation
Sign in
Files
Branches
1
Releases
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
hanfei
/
VueSharedPrinting
Browse code
han
master
1 parent
496b7fa
commit
2abb8b3243408e355cbe207e601d6c0aa0f6b02e
hanfei
authored
on 22 Jan 2024
Patch
Showing
7 changed files
public/index.html
src/api/resultApi.js
src/components/global.vue
src/components/top.vue
src/views/expense.vue
src/views/operationGuide.vue
src/views/selectFile.vue
Ignore Space
Show notes
View
public/index.html
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= htmlWebpackPlugin.options.title %></title> <style> html { font-size: 16px!important; } </style> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
Ignore Space
Show notes
View
src/api/resultApi.js
import request from '../utils/request' import cite from '../utils/cite' // 打印价格 export const getPrintPriceList = params => { return request({ url: '/device/getPrintPriceList', params }) } // 获取设备ID export const getDeviceByCode = params => { return request({ url: '/device/getDeviceByCode', params }) } // 文件上传 export const upload2Pdf = data => { return request({ method: 'POST', url: '/file/upload2Pdf', data }) } // 文件上传-身份证 export const image2Pdf = data => { return request({ method: 'POST', url: '/file/image2Pdf', data }) } // 设备-获取打印价格 export const getPrintPrice = data => { return request({ url: '/device/getPrintPrice', params: data }) } // 设备-提交打印任务 export const submitPrintingTask = data => { return request({ headers: { "Member-Token": cite.memberLoginVo.token, }, method: 'POST', url: '/device/auth/submitPrintingTask', data }) } // 订单-获取支付二维码 export const getPayQrCode = data => { return request({ url: '/order/getPayQrCode', params: data }) } export const downloadPDF = data => { return request({ url: '/file/download', timeout: 2 * 60 * 1000, responseType: 'blob', params: data }) } // 订单-获取打印任务进度 export const getPrintTask = data => { return request({ url: '/device/getPrintTask', params: data }) } // 获取广告链接 export const getAdvertisement = data => { return request({ url: '/placement/getAdvertisement', params: data }) } // 文件-证件照切换底色 export const changeIdPhotoBgc = data => { return request({ method: 'POST', url: '/file/changeIdPhotoBgc', data }) }
import request from '../utils/request' import cite from '../utils/cite' // 打印价格 export const getPrintPriceList = params => { return request({ url: '/device/getPrintPriceList', params }) } // 获取设备ID export const getDeviceByCode = params => { return request({ url: '/device/getDeviceByCode', params }) } // 文件上传 export const upload2Pdf = data => { return request({ method: 'POST', url: '/file/upload2Pdf', data }) } // 文件上传-身份证 export const image2Pdf = data => { return request({ method: 'POST', url: '/file/image2Pdf', data }) } // 设备-获取打印价格 export const getPrintPrice = data => { return request({ url: '/device/getPrintPrice', params: data }) } // 设备-提交打印任务 export const submitPrintingTask = data => { return request({ header: { "Member-Token": cite.memberLoginVo.token, }, method: 'POST', url: '/device/submitPrintingTask', data }) } // 订单-获取支付二维码 export const getPayQrCode = data => { return request({ url: '/order/getPayQrCode', params: data }) } export const downloadPDF = data => { return request({ url: '/file/download', timeout: 2 * 60 * 1000, responseType: 'blob', params: data }) } // 订单-获取打印任务进度 export const getPrintTask = data => { return request({ url: '/device/getPrintTask', params: data }) } // 获取广告链接 export const getAdvertisement = data => { return request({ url: '/placement/getAdvertisement', params: data }) } // 文件-证件照切换底色 export const changeIdPhotoBgc = data => { return request({ method: 'POST', url: '/file/changeIdPhotoBgc', data }) }
Ignore Space
Show notes
View
src/components/global.vue
<template> <div> <!-- 打印中提示--> <div class="dyzTip" v-show="DYZshow"> <div class="curtain"></div> <div class="content"> <img src="../assets/printing.png" alt=""> <div class="name">正在进行{{ listData.printFileType=='PDF'?'文档':'照片' }}打印...</div> <!-- <div class="flex-center">{{ listData.printFileName }}</div>--> <div class="flex-center">{{ cite.selectedFile.length||1 }}/{{ cite.fileNum||1 }}</div> </div> </div> <!-- 提示--> <div class="tkTip flex-center" v-if="state.sta"> <div>{{ state.name }}</div> </div> <!-- 小程序支付--> <div class="dyzTip" v-if="zfShow"> <div class="curtain"></div> <div class="content content2"> <VueQr v-show="src" :auto-color="true" :dot-scale="1" :logo-src="require('@/assets/logo.png')" :logoMargin="0" :logoScale=".2" :margin="0" :size="300" :text="src" logoBackgroundColor="white"></VueQr> <p> <img @click="onChange('zfShow',false)" class="icon" src="../assets/demo10.png" alt=""> </p> </div> </div> </div> </template> <script> import mqtt from "mqtt/dist/mqtt" import {getAdvertisement, getDeviceByCode} from "@/api/resultApi"; import VueQr from 'vue-qr' import {apiPrint, getDeviceCode, readDownload} from "@/api/bdResultApi"; export default { name: "global", components: { VueQr }, data() { return { client: null, code: '', listData: '', DYZshow: false, // 是否显示打印中 downloadPath: 'D:\\TZDYSHARE\\TEMPFILES\\', state: '', src: '', zfShow: false, }; }, created() { this.toLoad() }, methods: { onChange(name,val){ this[name] = val }, toLoad() { // this.cite.code = 'SNJ-XX-EPSON-X001-00001' // this.code = 'SNJ-XX-EPSON-X001-00001' // this.load() getDeviceCode().then(res =>{ this.cite.code = res.data this.code = res.data this.load() }) }, load() { // 获取名为code的查询参数值 // if (this.cite.code === "") { // this.code = this.$route.query.code; // this.cite.code = this.code; // }else{ // this.code = this.cite.code; // } if (this.cite.facility === "") { this.getDeviceByCode(); } // 判断是否是广告屏 // console.log(this.cite) if(this.cite.name != 'advertising') { this.initMqtt() setInterval(()=>{ if(!this.state.sta&&this.cite.state.sta) { setTimeout(()=>{ this.cite.state.sta = false },3000) } this.state = this.cite.state },1000) } }, initMqtt() { // 连接配置选项 let options = { connectTimeout: 4000, // 超时时间 // 认证信息 clientId: '', //不填默认随机生成一个ID username: 'admin', //用户名 password: 'public' //密码 } this.client = mqtt.connect('wss://mps.xlmalls.com:8084/mqtt', options) //调用连接的api //连接成功 this.client.on('connect', (e) => { console.log('连接成功', e) this.subscribes() }) //重连提醒 this.client.on('reconnect', (error) => { console.log('正在重连', error) }) //连接失败提醒 this.client.on('error', (error) => { console.log('连接失败', error) }) //接收消息 this.client.on('message', (topic, message) => { const data = JSON.parse(message) //接受到控制信号的数据 console.log('接收消息',data) if(data.cmd=='ORDER_INFO') { //小程序支付 this.cite.url = data.payCodeUrl if(this.cite.selectedFile.length<1) { this.src = data.payCodeUrl this.zfShow=true } }else if(data.cmd=='LOGIN') { //登录 this.cite.memberLoginVo = data this.cite.state = { name: '登录设备成功!', sta: true } }else if(data.cmd=='LOGOUT'){ //登出 this.cite.memberLoginVo = '' }else if(data.cmd=='PRINT'){ //打印任务 this.listData = data this.dayin() }else if(data.cmd=='PRINT_STATUS'){ //打印任务完成 console.log(this.cite.selectedFile.length,this.cite.selectedFile) if(data.taskStatus=='COMPLETE') { if(this.cite.selectedFile.length>1) { this.cite.selectedFile.forEach((item,index)=>{ if(item.code == data.taskCode) { this.cite.selectedFile.splice(index, 1) } }) }else{ this.DYZshow = false this.$router.push({ name: 'complete' }) getDeviceByCode({ code: this.code }).then((res) => { this.cite.facility = res; }); } } } }) }, //订阅多个主题 subscribes() { const arr = ['/tzdy/send/device/'+this.code] this.client.subscribe(arr, { qos: 0 }, (err) => { if (!err) { console.log(`消息订阅成功`) } else { console.log('消息订阅失败') } }) }, //获取设备信息 getDeviceByCode() { getDeviceByCode({ code: this.code }).then((res) => { console.log(res) this.cite.facility = res; this.getAdvertisement() }); }, // 获取广告链接 getAdvertisement() { let name = 'DeviceScreen' if(this.cite.name=='advertising') { name = 'AdvertisingScreen' } getAdvertisement({deviceId:this.cite.facility.id,screen: name}).then((res) =>{ // console.log(res) this.cite.advertisement = res || '' }) }, // 小程序下载 downloadPDF(id,name) { // downloadPDF({id: id}).then(res => { // console.log(res) // const fileName = name // const blob = new Blob([res], {type: 'application/octet-stream'}) // if (window.navigator.msSaveOrOpenBlob) { // navigator.msSaveBlob(blob, fileName) // } else { // let link = document.createElement('a') // link.href = window.URL.createObjectURL(blob) // link.download = fileName // link.click() // window.URL.revokeObjectURL(link.href) // } // }).catch(() => { // }) let data = { destUrl: this.downloadPath+name,//下载路径 downloadUrl: 'https://mps.xlmalls.com/api/file/download?id='+id,//名称 } readDownload(data).then(res =>{ console.log(res,id,name) }) }, async dayin() { let _this = this _this.DYZshow = true _this.zfShow = false // let {listData} = _this // await this.downloadPDF(listData.printFileId,listData.printFileName) // setTimeout(() =>{ // _this.DYZshow = true // _this.zfShow = false // _this.setDy(listData,listData.copies) // },4000) }, setDy(listData,num) { let name = this.cite.memberLoginVo.printerGlossy || 'EPSON WF-C5890 Series3' let type = 'img' if(listData.printFileType=='PDF') { name = this.cite.memberLoginVo.printerA4 || 'EPSON WF-C5890 Series2' type = 'pdf' } let PrintColor = '' if(listData.printingColor == 'BW') { PrintColor = '黑白' } let DblPrt = '' if(listData.printingFaces == 'DOUBLE') { DblPrt = '双面打印' } console.log('设备名称',name,type,PrintColor,DblPrt) let res = apiPrint({ "PrinterName": name, "SourceFile": this.downloadPath+listData.printFileName, "FileType": type, "PrintColor": PrintColor, "DblPrt": DblPrt }) console.log(res) if(res) { num = num-1 if(num>0) { this.setDy(listData,num) }else{ setTimeout(()=>{ this.DYZshow = false this.$router.push({ name: 'complete' }) },2000) } }else{ setTimeout(() =>{ this.setDy(listData,num) },2000) } }, } } </script> <style scoped lang="less"> .dyzTip { position: fixed; width: 100%; height: 100%; top: 0; left: 0; .curtain { background: #000; width: 100%; height: 100%; opacity: .3; } .content { position: absolute; left: 50%; margin-left: -19rem; top: 50%; margin-top: -14.5rem; width: 38.56rem; height: 29rem; background: #FFFFFF; border-radius: 1.25rem; overflow: hidden; img { width: 100%; } div { font-size: 1.38rem; font-family: PingFang SC, PingFang SC; font-weight: bold; color: #323232; line-height: 1.88rem; margin-top: 1.3rem; } .name { font-size: 1rem; font-family: PingFang SC, PingFang SC; font-weight: 400; color: #323232; line-height: 1.38rem; text-align: left; padding: 0 3rem; } } .content2 { background: transparent; height: auto; img { width: 18rem; } .icon { width: 3rem; margin-top: 3rem; } } } .tkTip { position: fixed; top: 5%; width: 100%; div { background: rgba(51, 51, 51, 0.5); color: #fff; padding: 1rem 2rem; border-radius: 1rem; } } </style>
<template> <div> <!-- 打印中提示--> <div class="dyzTip" v-show="DYZshow"> <div class="curtain"></div> <div class="content"> <img src="../assets/printing.png" alt=""> <div class="name">正在进行{{ listData.printFileType=='PDF'?'文档':'照片' }}打印...</div> <!-- <div class="flex-center">{{ listData.printFileName }}</div>--> <div class="flex-center">{{ cite.selectedFile.length||1 }}/{{ cite.fileNum||1 }}</div> </div> </div> <!-- 提示--> <div class="tkTip flex-center" v-if="state.sta"> <div>{{ state.name }}</div> </div> <!-- 小程序支付--> <div class="dyzTip" v-if="zfShow"> <div class="curtain"></div> <div class="content content2"> <VueQr v-show="src" :auto-color="true" :dot-scale="1" :logo-src="require('@/assets/logo.png')" :logoMargin="0" :logoScale=".2" :margin="0" :size="300" :text="src" logoBackgroundColor="white"></VueQr> <p> <img @click="onChange('zfShow',false)" class="icon" src="../assets/demo10.png" alt=""> </p> </div> </div> </div> </template> <script> import mqtt from "mqtt/dist/mqtt" import {getAdvertisement, getDeviceByCode} from "@/api/resultApi"; import VueQr from 'vue-qr' import {apiPrint, getDeviceCode, readDownload} from "@/api/bdResultApi"; export default { name: "global", components: { VueQr }, data() { return { client: null, code: '', listData: '', DYZshow: false, // 是否显示打印中 downloadPath: 'D:\\TZDYSHARE\\TEMPFILES\\', state: '', src: '', zfShow: false, }; }, created() { this.toLoad() }, methods: { onChange(name,val){ this[name] = val }, toLoad() { getDeviceCode().then(res =>{ this.cite.code = res.data this.code = res.data this.load() }) }, load() { // 获取名为code的查询参数值 // if (this.cite.code === "") { // this.code = this.$route.query.code; // this.cite.code = this.code; // }else{ // this.code = this.cite.code; // } if (this.cite.facility === "") { this.getDeviceByCode(); } // 判断是否是广告屏 // console.log(this.cite) if(this.cite.name != 'advertising') { this.initMqtt() setInterval(()=>{ if(!this.state.sta&&this.cite.state.sta) { setTimeout(()=>{ this.cite.state.sta = false },3000) } this.state = this.cite.state },1000) } }, initMqtt() { // 连接配置选项 let options = { connectTimeout: 4000, // 超时时间 // 认证信息 clientId: '', //不填默认随机生成一个ID username: 'admin', //用户名 password: 'public' //密码 } this.client = mqtt.connect('wss://mps.xlmalls.com:8084/mqtt', options) //调用连接的api //连接成功 this.client.on('connect', (e) => { console.log('连接成功', e) this.subscribes() }) //重连提醒 this.client.on('reconnect', (error) => { console.log('正在重连', error) }) //连接失败提醒 this.client.on('error', (error) => { console.log('连接失败', error) }) //接收消息 this.client.on('message', (topic, message) => { const data = JSON.parse(message) //接受到控制信号的数据 console.log('接收消息',data) if(data.cmd=='ORDER_INFO') { //小程序支付 this.cite.url = data.payCodeUrl if(this.cite.selectedFile.length<1) { this.src = data.payCodeUrl this.zfShow=true } }else if(data.cmd=='LOGIN') { //登录 this.cite.memberLoginVo = data this.cite.state = { name: '登录设备成功!', sta: true } }else if(data.cmd=='LOGOUT'){ //登出 this.cite.memberLoginVo = '' }else if(data.cmd=='PRINT'){ //打印任务 this.listData = data this.dayin() }else if(data.cmd=='PRINT_STATUS'){ //打印任务完成 console.log(this.cite.selectedFile.length,this.cite.selectedFile) if(data.taskStatus=='COMPLETE') { if(this.cite.selectedFile.length>1) { this.cite.selectedFile.forEach((item,index)=>{ if(item.code == data.taskCode) { this.cite.selectedFile.splice(index, 1) } }) }else{ this.DYZshow = false this.$router.push({ name: 'complete' }) getDeviceByCode({ code: this.code }).then((res) => { this.cite.facility = res; }); } } } }) }, //订阅多个主题 subscribes() { const arr = ['/tzdy/send/device/'+this.code] this.client.subscribe(arr, { qos: 0 }, (err) => { if (!err) { console.log(`消息订阅成功`) } else { console.log('消息订阅失败') } }) }, //获取设备信息 getDeviceByCode() { getDeviceByCode({ code: this.code }).then((res) => { console.log(res) this.cite.facility = res; this.getAdvertisement() }); }, // 获取广告链接 getAdvertisement() { let name = 'DeviceScreen' if(this.cite.name=='advertising') { name = 'AdvertisingScreen' } getAdvertisement({deviceId:this.cite.facility.id,screen: name}).then((res) =>{ // console.log(res) this.cite.advertisement = res || '' }) }, // 小程序下载 downloadPDF(id,name) { // downloadPDF({id: id}).then(res => { // console.log(res) // const fileName = name // const blob = new Blob([res], {type: 'application/octet-stream'}) // if (window.navigator.msSaveOrOpenBlob) { // navigator.msSaveBlob(blob, fileName) // } else { // let link = document.createElement('a') // link.href = window.URL.createObjectURL(blob) // link.download = fileName // link.click() // window.URL.revokeObjectURL(link.href) // } // }).catch(() => { // }) let data = { destUrl: this.downloadPath+name,//下载路径 downloadUrl: 'https://mps.xlmalls.com/api/file/download?id='+id,//名称 } readDownload(data).then(res =>{ console.log(res,id,name) }) }, async dayin() { let _this = this _this.DYZshow = true _this.zfShow = false // let {listData} = _this // await this.downloadPDF(listData.printFileId,listData.printFileName) // setTimeout(() =>{ // _this.DYZshow = true // _this.zfShow = false // _this.setDy(listData,listData.copies) // },4000) }, setDy(listData,num) { let name = this.cite.memberLoginVo.printerGlossy || 'EPSON WF-C5890 Series3' let type = 'img' if(listData.printFileType=='PDF') { name = this.cite.memberLoginVo.printerA4 || 'EPSON WF-C5890 Series2' type = 'pdf' } let PrintColor = '' if(listData.printingColor == 'BW') { PrintColor = '黑白' } let DblPrt = '' if(listData.printingFaces == 'DOUBLE') { DblPrt = '双面打印' } console.log('设备名称',name,type,PrintColor,DblPrt) let res = apiPrint({ "PrinterName": name, "SourceFile": this.downloadPath+listData.printFileName, "FileType": type, "PrintColor": PrintColor, "DblPrt": DblPrt }) console.log(res) if(res) { num = num-1 if(num>0) { this.setDy(listData,num) }else{ setTimeout(()=>{ this.DYZshow = false this.$router.push({ name: 'complete' }) },2000) } }else{ setTimeout(() =>{ this.setDy(listData,num) },2000) } }, } } </script> <style scoped lang="less"> .dyzTip { position: fixed; width: 100%; height: 100%; top: 0; left: 0; .curtain { background: #000; width: 100%; height: 100%; opacity: .3; } .content { position: absolute; left: 50%; margin-left: -19rem; top: 50%; margin-top: -14.5rem; width: 38.56rem; height: 29rem; background: #FFFFFF; border-radius: 1.25rem; overflow: hidden; img { width: 100%; } div { font-size: 1.38rem; font-family: PingFang SC, PingFang SC; font-weight: bold; color: #323232; line-height: 1.88rem; margin-top: 1.3rem; } .name { font-size: 1rem; font-family: PingFang SC, PingFang SC; font-weight: 400; color: #323232; line-height: 1.38rem; text-align: left; padding: 0 3rem; } } .content2 { background: transparent; height: auto; img { width: 18rem; } .icon { width: 3rem; margin-top: 3rem; } } } .tkTip { position: fixed; top: 5%; width: 100%; div { background: rgba(51, 51, 51, 0.5); color: #fff; padding: 1rem 2rem; border-radius: 1rem; } } </style>
Ignore Space
Show notes
View
src/components/top.vue
<template> <div class="top flex-between"> <div class="logo flex-start" @click="_goHome()"> <img src="../assets/logo.png" /> <span></span> <div>天章自助打印</div> </div> <div class="time flex-start"> <div> <div>{{ time.week }}</div> <div>{{ time.y }}/{{ time.M }}/{{ time.d }}</div> </div> <div class="info">{{ time.h }}:{{ time.m }}</div> </div> <div class="tip flex-start"> <div v-for="(item, index) in cite.facility.paperNumber" :key="index">{{ item.name }}*{{ item.residue }}</div> <div>{{cite.memberLoginVo?'已登录':'未登录'}}</div> </div> </div> </template> <script> export default { name: "top", data() { return { time: {}, } }, mounted() { this.format() }, methods: { add(t) { if(t<10) { return '0' + t } return t }, format() { let date = new Date(); let o = { "y": date.getFullYear(), //年 "M": this.add(date.getMonth() + 1), //月份 "d": this.add(date.getDate()), //日 "h": this.add(date.getHours()), //小时 "m": this.add(date.getMinutes()), //分 "week": '', }; let str = "星期"; switch (date.getDay()) { case 0 : str += "日"; break; case 1 : str += "一"; break; case 2 : str += "二"; break; case 3 : str += "三"; break; case 4 : str += "四"; break; case 5 : str += "五"; break; case 6 : str += "六"; break; } o.week = str this.time = o setTimeout(() =>{ this.format() },1000) }, _goHome() { // this.quit() this.$router.push({ name: 'device' }) } } } </script> <style scoped lang="less"> .top { width: 100%; height: 9.81rem; background: #52A39D; position: relative; .logo { padding-left: 5.5rem; font-size: 3.5rem; font-weight: 400; color: #FFFFFF; line-height: 3.69rem; img { width: 5.56rem; height: 5.56rem; } span { width: 0; height: 4.43rem; border-left: 1px solid #FFFFFF; margin: 0 1.94rem; } } .time { padding-right: 3.88rem; font-size: 1.38rem; font-weight: 400; color: #FFFFFF; line-height: 1.94rem; text-align: right; .info { font-weight: bold; color: #FFFFFF; margin-left: 1.13rem; font-size: 3.69rem; line-height: 5.2rem; } } .tip { position: absolute; bottom: .5rem; right: 3.88rem; font-size: 1.2rem; color: #fff; div { margin-left: 2rem; } } } </style>
<template> <div class="top flex-between"> <div class="logo flex-start" @click="_goHome()"> <img src="../assets/logo.png" /> <span></span> <div>天章自助打印</div> </div> <div class="time flex-start"> <div> <div>{{ time.week }}</div> <div>{{ time.y }}/{{ time.M }}/{{ time.d }}</div> </div> <div class="info">{{ time.h }}:{{ time.m }}</div> </div> <div class="tip flex-start"> <div v-for="(item, index) in cite.facility.paperNumber" :key="index">{{ item.name }}*{{ item.residue }}</div> </div> </div> </template> <script> export default { name: "top", data() { return { time: {}, } }, mounted() { this.format() }, methods: { add(t) { if(t<10) { return '0' + t } return t }, format() { let date = new Date(); let o = { "y": date.getFullYear(), //年 "M": this.add(date.getMonth() + 1), //月份 "d": this.add(date.getDate()), //日 "h": this.add(date.getHours()), //小时 "m": this.add(date.getMinutes()), //分 "week": '', }; let str = "星期"; switch (date.getDay()) { case 0 : str += "日"; break; case 1 : str += "一"; break; case 2 : str += "二"; break; case 3 : str += "三"; break; case 4 : str += "四"; break; case 5 : str += "五"; break; case 6 : str += "六"; break; } o.week = str this.time = o setTimeout(() =>{ this.format() },1000) }, _goHome() { // this.quit() this.$router.push({ name: 'device' }) } } } </script> <style scoped lang="less"> .top { width: 100%; height: 9.81rem; background: #52A39D; position: relative; .logo { padding-left: 5.5rem; font-size: 3.5rem; font-weight: 400; color: #FFFFFF; line-height: 3.69rem; img { width: 5.56rem; height: 5.56rem; } span { width: 0; height: 4.43rem; border-left: 1px solid #FFFFFF; margin: 0 1.94rem; } } .time { padding-right: 3.88rem; font-size: 1.38rem; font-weight: 400; color: #FFFFFF; line-height: 1.94rem; text-align: right; .info { font-weight: bold; color: #FFFFFF; margin-left: 1.13rem; font-size: 3.69rem; line-height: 5.2rem; } } .tip { position: absolute; bottom: .5rem; right: 3.88rem; font-size: 1.2rem; color: #fff; div { margin-left: 2rem; } } } </style>
Ignore Space
Show notes
View
src/views/expense.vue
<template> <!-- 费用支付--> <div class="expense"> <navbar :name="name"/> <div class="box flex-center"> <div class="left"> <div class="title">温馨提示</div> <div class="content">请在二维码区域提示的时限内,尽快完成支付。如果操作超时,本次打印业务可能需要重新提交。</div> </div> <div class="right"> <div class="code"> <VueQr :logo-src="require('@/assets/logo.png')" :logoScale=".2" :logoMargin="0" logoBackgroundColor="white" :size="300" :margin="0" :auto-color="true" :dot-scale="1" :text="appSrc"></VueQr> </div> <div class="flex-center tip">提示:请在 {{num}} 秒内完成扫码支付</div> </div> </div> </div> </template> <script> import navbar from '@/components/nav' import {getPayQrCode, downloadPDF, getPrintTask} from "../api/resultApi"; import VueQr from 'vue-qr' import bdRequest from "../utils/bdRequest"; export default { name: "expense", components: { navbar,VueQr }, provide() { return { title: '', type: this.name } }, data() { return { name: this.cite.modeName, appSrc: '', client: '', num: 120, selectedFile: this.cite.selectedFile, listData: { "code":"20240104231724631239-0", "copies":1, "printFileId":112, "printFileType":"PDF", "printingColor":"BW", "printingFaces":"SINGLE" } } }, methods: { skip(href,name) { this.$router.push({ name: href, params: { name: name } }) }, downloadPDF(id,name) { downloadPDF({id: id}).then(res => { const fileName = name const blob = new Blob([res], {type: 'application/octet-stream'}) if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName) } else { let link = document.createElement('a') link.href = window.URL.createObjectURL(blob) link.download = fileName link.click() window.URL.revokeObjectURL(link.href) } }).catch(() => { }) }, async dayin() { let _this = this let {listData,selectedFile} = _this let i = '', deta='' selectedFile.forEach((item,index) => { if(listData.printFileId == item.id) { i=index deta = item } }) await this.downloadPDF(listData.printFileId,listData.printFileName) console.log('打印',deta,listData.copies) setTimeout(() =>{ _this.selectedFile.splice(i, 1) // 按份数循环打印 // for(let i=0;i<listData.copies;i++) { // } let res = bdRequest({ method: 'post', url: '/api/Printer/Print', post: '8080', data: { "PrinterName": "EPSON WF-C5890 Series", // "SourceFile": 'D:\\TZDYSHARE\\TEMPFILES\\'+listData.printFileName, "SourceFile": 'C:\\datasource\\'+listData.printFileName, "FileType": "pdf", "PrintColor": listData.printingColor || "", "DblPrt": listData.printingFaces || "" } }) console.log(res) setTimeout(()=>{ if(_this.selectedFile.length>0) { _this.getPrintTask() }else{ _this.cite.orderId = '' _this.skip('complete',_this.name) } },1000) },2000) }, async getPrintTask() { let _this = this if(_this.cite.orderId) { let res = await getPrintTask({orderId: _this.cite.orderId}) console.log(res,'getPrintTask数据') if(res) { _this.listData = res _this.dayin() }else{ setTimeout(()=>{ _this.getPrintTask() },1000) } } }, load() { let _this = this getPayQrCode({orderId: _this.cite.orderId,payMode: 'TZ_PAY'}).then(res => { // console.log(res.data.qrCode) if(res.qrCode) { _this.appSrc = res.qrCode // 循环查询是否需要调打印 // setTimeout(() =>{ // // _this.dayin() // _this.getPrintTask() // },1000) } }) }, countDown(num) { if(num<1) { this.quit() return } setTimeout(()=>{ this.num = num-1 this.countDown(this.num) },1000) }, }, destroyed() { // 销毁监听 // clearTimeout() }, mounted() { this.countDown(120) this.load() } } </script> <style scoped lang="less"> .box { height: 42.13rem; .css1 { height: 100%; background: #FFFFFF; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0,0,0,0.14); border-radius: 1.63rem; } .left { width: 46.44rem; margin-right: 1.88rem; .css1(); .title { font-size: 2.88rem; font-weight: bold; color: #D41212; line-height: 4.06rem; padding: 4.13rem 0 2.44rem; } .content { width: 37rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; margin: 0 auto; text-align: left; } } .right { width: 62.81rem; .css1(); font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3.13rem; .code { display: inline-block; width: 23.25rem; height: 22.88rem; background: #FFFFFF; //border: 0.06rem solid #707070; margin: 2.94rem auto 1.19rem; img { width: 100%; height: auto; } } } } </style>
<template> <!-- 费用支付--> <div class="expense"> <navbar :name="name"/> <div class="box flex-center"> <div class="left"> <div class="title">温馨提示</div> <div class="content">请在建议时限内尽快完成支付,如果操作超时本次打印业务可能需要重新提交。</div> </div> <div class="right"> <div class="code"> <VueQr :logo-src="require('@/assets/logo.png')" :logoScale=".2" :logoMargin="0" logoBackgroundColor="white" :size="300" :margin="0" :auto-color="true" :dot-scale="1" :text="appSrc"></VueQr> </div> <div class="flex-center tip">提示:请在 {{num}} 秒内完成扫码支付</div> </div> </div> </div> </template> <script> import navbar from '@/components/nav' import {getPayQrCode, downloadPDF, getPrintTask} from "../api/resultApi"; import VueQr from 'vue-qr' import bdRequest from "../utils/bdRequest"; export default { name: "expense", components: { navbar,VueQr }, provide() { return { title: '', type: this.name } }, data() { return { name: this.cite.modeName, appSrc: '', client: '', num: 120, selectedFile: this.cite.selectedFile, listData: { "code":"20240104231724631239-0", "copies":1, "printFileId":112, "printFileType":"PDF", "printingColor":"BW", "printingFaces":"SINGLE" } } }, methods: { skip(href,name) { this.$router.push({ name: href, params: { name: name } }) }, downloadPDF(id,name) { downloadPDF({id: id}).then(res => { const fileName = name const blob = new Blob([res], {type: 'application/octet-stream'}) if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName) } else { let link = document.createElement('a') link.href = window.URL.createObjectURL(blob) link.download = fileName link.click() window.URL.revokeObjectURL(link.href) } }).catch(() => { }) }, async dayin() { let _this = this let {listData,selectedFile} = _this let i = '', deta='' selectedFile.forEach((item,index) => { if(listData.printFileId == item.id) { i=index deta = item } }) await this.downloadPDF(listData.printFileId,listData.printFileName) console.log('打印',deta,listData.copies) setTimeout(() =>{ _this.selectedFile.splice(i, 1) // 按份数循环打印 // for(let i=0;i<listData.copies;i++) { // } let res = bdRequest({ method: 'post', url: '/api/Printer/Print', post: '8080', data: { "PrinterName": "EPSON WF-C5890 Series", // "SourceFile": 'D:\\TZDYSHARE\\TEMPFILES\\'+listData.printFileName, "SourceFile": 'C:\\datasource\\'+listData.printFileName, "FileType": "pdf", "PrintColor": listData.printingColor || "", "DblPrt": listData.printingFaces || "" } }) console.log(res) setTimeout(()=>{ if(_this.selectedFile.length>0) { _this.getPrintTask() }else{ _this.cite.orderId = '' _this.skip('complete',_this.name) } },1000) },2000) }, async getPrintTask() { let _this = this if(_this.cite.orderId) { let res = await getPrintTask({orderId: _this.cite.orderId}) console.log(res,'getPrintTask数据') if(res) { _this.listData = res _this.dayin() }else{ setTimeout(()=>{ _this.getPrintTask() },1000) } } }, load() { let _this = this getPayQrCode({orderId: _this.cite.orderId}).then(res => { // console.log(res.data.qrCode) if(res.qrCode) { _this.appSrc = res.qrCode // 循环查询是否需要调打印 // setTimeout(() =>{ // // _this.dayin() // _this.getPrintTask() // },1000) } }) }, countDown(num) { if(num<1) { this.quit() return } setTimeout(()=>{ this.num = num-1 this.countDown(this.num) },1000) }, }, destroyed() { // 销毁监听 // clearTimeout() }, mounted() { this.countDown(120) this.load() } } </script> <style scoped lang="less"> .box { height: 42.13rem; .css1 { height: 100%; background: #FFFFFF; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0,0,0,0.14); border-radius: 1.63rem; } .left { width: 46.44rem; margin-right: 1.88rem; .css1(); .title { font-size: 2.88rem; font-weight: bold; color: #D41212; line-height: 4.06rem; padding: 4.13rem 0 2.44rem; } .content { width: 37rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; margin: 0 auto; text-align: left; } } .right { width: 62.81rem; .css1(); font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3.13rem; .code { display: inline-block; width: 23.25rem; height: 22.88rem; background: #FFFFFF; //border: 0.06rem solid #707070; margin: 2.94rem auto 1.19rem; img { width: 100%; height: auto; } } } } </style>
Ignore Space
Show notes
View
src/views/operationGuide.vue
<template> <!-- 操作指南--> <div class="operationGuide"> <navbar :name="name"/> <div class="box flex-between"> <div class="picture" v-show="name=='U盘打印'"> <img class="icon" src="../assets/typeUp.png" /> <div class="flex-between name"> <div>U盘</div> <div>USB接口</div> </div> </div> <div class="picture flex-center" v-show="name=='扫描打印'"> <img src="../assets/typeSMFY.png" /> </div> <div class="picture" v-show="name=='身份证打印'"> <img src="../assets/typeSFZ.png" /> </div> <div class="tip"> <div class="title">温馨提示</div> <div class="content">{{ content }}</div> <div class="btn flex-center" @click="skip('selectFile',name)">{{ btnName }}</div> </div> </div> </div> </template> <script> import navbar from '@/components/nav' export default { name: "operationGuide", components: { navbar }, provide() { return { title: this.tit, type: this.name } }, data() { return { tit: this.cite.modeName=='U盘打印'?'资料选取提交':'资料扫描提交', name: this.cite.modeName, content: '', btnName: '', } }, methods: { skip(href,name) { this.$router.push({ name: href, params: { name: name } }) }, }, mounted() { let name = this.cite.modeName if(name=='U盘打印') { this.content='如图所示,请先将存放打印资料的U盘插入打印终端机器上标记有"USB"字样的接口中,确认正确插入后,请按下面的“选取文件”按钮开始选取需要打印的资料。' this.btnName='选取文件' }else if(name=='扫描打印') { this.content='如左图所示,请先把需要扫码的资料页面展开,将需要的版面朝上放置在机器的“扫描复印”口中,并保持页面纸张靠格口右上角紧贴放好,这时您可以在实时预览小窗中查看并确认是否是自己需要的版面。确认无误后,请按下面的“开始扫描”按钮开始资料的扫描。' this.btnName='开始扫描' }else if(name=='身份证打印') { this.content='身份证件信息已读取成功。请您核对个人信息确认无误后,按“信息无读,继续提按钮进行后续操作。此时您可以取回您的身份证卡片并妥善保存。' this.btnName='开始读卡' } } } </script> <style scoped lang="less"> .operationGuide { .box { width: 114.06rem; height: 42.13rem; background: #FFFFFF; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0,0,0,0.14); border-radius: 1.63rem; margin: 0 auto; .picture { margin-left: 4.75rem; img { width: 29.06rem; margin-left: 11.81rem; } .icon { margin-left: 0; width: 56rem; margin-bottom: 2.69rem; } .name { font-size: 2.13rem; font-weight: bold; color: #323232; line-height: 3rem; div { width: 30%; text-align: center; } } } .tip { margin-right: 7.81rem; width: 40rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; .title { font-size: 2.88rem; font-weight: bold; color: #D41212; line-height: 4.06rem; } .content { margin: 3rem auto 3.69rem; text-align: center; } .btn { width: 100%; height: 5.5rem; background: linear-gradient(132deg, #52A39D 0%, #A1C553 50%, #81D012 100%); border-radius: 1.25rem; font-size: 1.88rem; font-weight: 400; color: #FFFFFF; line-height: 2.63rem; cursor: pointer; } } } } </style>
<template> <!-- 操作指南--> <div class="operationGuide"> <navbar :name="name"/> <div class="box flex-between"> <div class="picture" v-show="name=='U盘打印'"> <img class="icon" src="../assets/typeUp.png" /> <div class="flex-between name"> <div>U盘</div> <div>USB接口</div> </div> </div> <div class="picture flex-center" v-show="name=='扫描打印'"> <img src="../assets/typeSMFY.png" /> </div> <div class="picture" v-show="name=='身份证打印'"> <img src="../assets/typeSFZ.png" /> </div> <div class="tip"> <div class="title">温馨提示</div> <div class="content">{{ content }}</div> <div class="btn flex-center" @click="skip('selectFile',name)">{{ btnName }}</div> </div> </div> </div> </template> <script> import navbar from '@/components/nav' export default { name: "operationGuide", components: { navbar }, provide() { return { title: this.tit, type: this.name } }, data() { return { tit: this.cite.modeName=='U盘打印'?'资料选取提交':'资料扫描提交', name: this.cite.modeName, content: '', btnName: '', } }, methods: { skip(href,name) { this.$router.push({ name: href, params: { name: name } }) }, }, mounted() { let name = this.cite.modeName if(name=='U盘打印') { this.content='如作图所示,请先将储存有打印资料的U盘插入到USB接口中,确认正确插入后,请按下面“选取文件”按钮进行需要打印资料的选择' this.btnName='选取文件' }else if(name=='扫描打印') { this.content='如左图所示,请先将需要扫描的资料页面展开,并且需要的版面朝上放置在机器的“扫描复印”口中央(也就是说放好之后,自己是可以看到你需要的那个版面内容的。)准备就绪后,请按下面的“开始扫描”开始资料扫描。' this.btnName='开始扫描' }else if(name=='身份证打印') { this.content='如左图所示,请先将身份证水平放置在机器的“身份证”读取卡口中,准备就绪后,请按下面的“开始读卡”开始身份证信息读取。' this.btnName='开始扫描' } } } </script> <style scoped lang="less"> .operationGuide { .box { width: 114.06rem; height: 42.13rem; background: #FFFFFF; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0,0,0,0.14); border-radius: 1.63rem; margin: 0 auto; .picture { margin-left: 4.75rem; img { width: 29.06rem; margin-left: 11.81rem; } .icon { margin-left: 0; width: 56rem; margin-bottom: 2.69rem; } .name { font-size: 2.13rem; font-weight: bold; color: #323232; line-height: 3rem; div { width: 30%; text-align: center; } } } .tip { margin-right: 7.81rem; width: 40rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; .title { font-size: 2.88rem; font-weight: bold; color: #D41212; line-height: 4.06rem; } .content { margin: 3rem auto 3.69rem; text-align: center; } .btn { width: 100%; height: 5.5rem; background: linear-gradient(132deg, #52A39D 0%, #A1C553 50%, #81D012 100%); border-radius: 1.25rem; font-size: 1.88rem; font-weight: 400; color: #FFFFFF; line-height: 2.63rem; cursor: pointer; } } } } </style>
Ignore Space
Show notes
View
src/views/selectFile.vue
<template> <!-- 选取资料--> <div class="selectFile"> <navbar :name="name" /> <!-- U盘打印--> <div class="box flex-center" v-if="name == 'U盘打印'"> <div class="tip" style="width: 20rem;"> <div class="title">温馨提示</div> <div class="content">请在右侧文件浏览区,找到待印资料文件存放的目录(文件夹),然后点选您需要打印的文件,之后按下“确认资料”按钮来提交资料。</div> </div> <div class="file"> <div class="main" style="width: 50rem;"> <div v-for="(item, index) in usbList" v-bind:key="index" class="li flex-start" @click="onChange(index, 'usbList',!item.sta)"> <input type="checkbox" v-model="item.sta"> <div class="name flex-start">{{ item.name }}</div> </div> </div> <div class="flex-between but"> <div class="btn flex-center" @click="skip('argument', name)">确认资料</div> </div> </div> </div> <!-- 扫描打印--> <div class="box flex-center" v-if="name == '扫描打印'"> <div class="file2"> <div class="title flex-between">已完成扫描的版面 <span :class="[{ act: smfyIndex == -1 }]" @click="onChange(-1, 'smfyIndex')">预览</span></div> <div class="main flex-between"> <div class="smfyData"> <div v-for="(item, index) in imgList" v-bind:key="index" :class="['flex-center', { act: smfyIndex == index }]" @click="onChange(index, 'smfyIndex')"> <div class="name">{{ index + 1 }}</div> <span @click="onCancel(index, 'imgList')">删除</span> </div> </div> <img v-show="smfyIndex!=-1" :src="imgList[smfyIndex]" alt="" style="width: 25rem; height: 100%" /> <img v-show="smfyIndex==-1" id="myCanvas" style="width: 25rem; height: 100%" /> </div> </div> <div class="tip tip2"> <div class="title">温馨提示</div> <div class="content">每次扫描前,可以按“预览”按钮来实时查看版面效果。已经扫描好的 页面显示在左边的列表中,您可以点击列表中的缩略图进行浏览核对, 不满意的页面可以点旁边的“删除”进行移除并重新扫描。如果有文件需要继续扫描,请按要求放置好资料后,按“继续扫描”。按照刚才的方法,重复扫描过程,直到完成了所有需要的页面。核对无误后,可以按“完成扫描”结束资料扫描工作。 </div> <div class="flex-between but"> <div class="btn flex-center" @click="paiz()">{{ imgList.length>0?'继续扫描':'开始扫描' }}</div> <div class="btn flex-center" @click="skip('argument', name)">完成扫描</div> </div> </div> </div> <!-- 身份证打印--> <div class="box flex-center" v-if="name == '身份证打印'"> <div class="file2 file3" style="margin-right: 20rem"> <div class="title">请核对您的信息</div> <div class="card" ref="captureArea" v-if="cardInfo!=''"> <div class="card-box2"> <img src="../assets/card2.png" alt="身份证正面" /> <div class="diamond"> <div class="name">{{ cardInfo.name }}</div> <div class="gender flex-start">{{ cardInfo.xbmc }} <div>{{ cardInfo.mzmc }}</div></div> <div class="birth flex-start"> <span>{{ cardInfo.birthday | joinYear }}</span> <div>{{ cardInfo.birthday | joinMonth }}</div> <div>{{ cardInfo.birthday | joinDay }}</div> </div> <div class="addr">{{ cardInfo.address }}</div> <div class="idNum">{{ cardInfo.idNum }}</div> <div class="avatar"><img :src="photo" alt=""></div> </div> </div> <div class="card-box2"> <img src="../assets/card1.png" alt="身份证反面" /> <div class="diamond diamond2"> <div class="sign">{{ cardInfo.issueOrg }}</div> <div class="date">{{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}}</div> </div> </div> <div class="card-box" v-show="false"> <img src="../assets/card2.png" alt="身份证反面" /> <div class="card-name">{{ cardInfo.name }}</div> <div class="card-gender"> {{ cardInfo.xbmc }}<span>{{ cardInfo.mzmc }}</span> </div> <div class="card-birth"> {{ cardInfo.birthday | joinYear }} <span class="month">{{ cardInfo.birthday | joinMonth }}</span> <span class="day">{{ cardInfo.birthday | joinDay }}</span> </div> <div class="card-addr"> {{ cardInfo.address }} </div> <div class="card-id">{{ cardInfo.idNum }}</div> <div class="card-avatar"> <!-- <img :src="'data:image/png;base64,'+cardInfo.photo" alt="" />--> <img :src="photo" alt=""> </div> </div> <div class="card-box" v-show="false"> <img src="../assets/card1.png"/> <div class="card-sign">{{ cardInfo.issueOrg }}</div> <div class="card-date"> {{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}} </div> </div> </div> </div> <div class="tip"> <div class="title">温馨提示</div> <div class="content">身份证件信息读取成功,请您核对个人信息无误后,按“信息无误,继续”按钮进行后续操作。此时您可以取回您的身份证卡片并妥善保存。</div> <div class="btn flex-center" @click="skip('argument', name)">信息无误,继续</div> </div> </div> </div> </template> <script> import navbar from "@/components/nav"; import html2canvas from "html2canvas"; import {upload2Pdf, changeIdPhotoBgc, image2Pdf} from '@/api/resultApi' import {readUsb, readFile, readCard} from '@/api/bdResultApi' import parseCardWzxx from "../utils/mz"; export default { name: 'selectFile', components: { navbar }, provide() { return { title: this.tit, type: this.name } }, filters: { joinYear(val) { return val.substring(0, 4) }, joinMonth(val) { if(val.substring(4, 5)==0) { return val.substring(5, 6) } return val.substring(4, 6) }, joinDay(val) { if(val.substring(6, 7)==0) { return val.substring(7, 8) } return val.substring(6, 8) }, joinRq(val) { return val.substring(0, 4)+'.'+val.substring(4, 6)+'.'+val.substring(6, 8) } }, data() { return { isChecked: true, tit: this.cite.modeName == 'U盘打印' ? '资料选取提交' : '资料扫描提交', name: this.cite.modeName, path: this.cite.inWebURL, socket: '', imgList: [], smfyIndex: -1, photo: '', UpFile: [], cardInfo: '', usbList: [], usbTime: '' }; }, methods: { async uploadImg(data, sta) { let _this = this for (let i = 0; i < data.length; i++) { let formData = new FormData() let file = data[i] if (sta) { // let dataURL = file.toDataURL('image/png') let name = i + '.png' file = _this.dataURLtoFile(file, name) } formData.append('file', file) // 使用数组语法添加多个文件 if(this.cite.modeName=='身份证打印') { let res = await image2Pdf(formData) _this.cite.selectedFile.push(res) // console.log('打印文件', this.cite.selectedFile, res) }else{ let res = await upload2Pdf(formData) _this.cite.selectedFile.push(res) // console.log('打印文件', this.cite.selectedFile, res) } } }, async skip(href, name) { if (this.usbList.length > 0) { // 保存选中的U盘文件 // await this.uploadImg(this.UpFile, false) await this.dealFile() } else if (this.imgList.length > 0) { // 保存高拍仪图片 await this.uploadImg(this.imgList, true) } else if (this.cardInfo) { // 保存身份证图片 await this.captureAndDownload() } else { this.cite.state = { name: '请选择文件打印!', sta: true } return } this.$router.push({ name: href, params: { name: name } }) }, async captureAndDownload() { const captureArea = this.$refs.captureArea // 使用 html2canvas 将区域内容生成为图片 const canvas = await html2canvas(captureArea) // 将 canvas 转为图片 URL const dataURL = canvas.toDataURL('image/png') const name = 'sfz.png' const file = this.dataURLtoFile(dataURL, name) this.uploadImg([file], false) }, dataURLtoFile(dataURL, filename) { const arr = dataURL.split(',') const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, {type: mime}) }, onChange(index, name, sta) { if (name == 'usbList') { this[name][index].sta = sta } else { this[name] = index } }, onCancel(index, name) { if (name == 'imgList') { this.smfyIndex = -1 } this[name].splice(index, 1) }, paiz() { this.socket.send('Capture@2') }, init: function () { if (typeof WebSocket === 'undefined') { alert('您的浏览器不支持socket') } else { // 实例化socket this.socket = new WebSocket(this.path) // 监听socket连接 this.socket.onopen = this.open // 监听socket错误信息 this.socket.onerror = this.error // 监听socket消息 this.socket.onmessage = this.getMessage } }, open: function () { // console.log("socket连接成功") this.socket.send('OpenIdCardEx@0') this.socket.send('OpenDevice@1') this.socket.send('SetResolution@2@2592@1944') this.socket.send('OpenVideo') this.socket.send('RotateRight') this.socket.send('Deskew') }, error: function () { console.log('连接错误') }, getMessage: function (msg) { if (typeof msg.data == 'string') { if (msg.data.indexOf('GetDevCount') == 0) { let s = msg.data.substring(12) if ('1' == s || '2' == s) { //如果是双摄像头 那就需要判断 s = 2;表示当前是连接了2个设备 alert('检测到已经连接上摄像头') } } else if (msg.data.indexOf('Capture') == 0) { let s = msg.data.substring(8) if (s) { this.imgList.push('data:image/jpeg;base64,' + s) } } else if (msg.data.indexOf('MoveDetectEvent') == 0) { this.socket.send('Capture@2') } else if (msg.data.indexOf('IdCardEvent') == 0) { this.socket.send('UnFaceDetect') } else if (msg.data.indexOf('ReadIdCard') == 0) { let s = msg.data.substring(11) if ('1' == s) { this.socket.send('GetIdCardResult@||') this.socket.send('GetIdCardImage@2') } } else if (msg.data.indexOf('GetIdCardResult') == 0) { let s = msg.data.substring(16) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetBarcode') == 0) { // alert(msg.data); let s = msg.data.substring(11) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetIdCardImage') == 0) { let s = msg.data.substring(15) let arr = s.split('#') let faceImg = arr[0] let myimg = document.getElementById('myCanvas3') myimg.src = 'data:image/jpeg;base64,' + faceImg } else if (msg.data.indexOf('GetBase64') == 0) { let s = msg.data.substring(10) let myimg = document.getElementById('myCanvas2') myimg.src = 'data:image/jpeg;base64,' + s alert(s) } else if (msg.data.indexOf('GetRecognitionFromFileName') == 0) { let s = msg.data.substring(27) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetOcrFromFileName') == 0) { let s = msg.data.substring(19) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetDogSN') == 0) { let s = msg.data.substring(11) let info = document.getElementById('info') info.value = s } } else { let reader = new FileReader() reader.onload = function (msg) { if (msg.target.readyState == FileReader.DONE) { let url = msg.target.result; document.getElementById('myCanvas').src = url; } } reader.readAsDataURL(msg.data) } }, close: function () { // console.log("socket已经关闭") this.socket.close() this.socket = '' }, handleFileChange(event) { let file = event.target.files[0] if (file) { this.UpFile.push(file) } }, // 获取身份证信息 async sfzCard() { let _this = this let res = await readCard() if (res.errorMsg == 'OK') { // console.log(res.resultContent) _this.imgDeals(res.resultContent.photo) _this.cardInfo = parseCardWzxx(res.resultContent) } else { if(this.$route.name == 'selectFile') { setTimeout(() => { this.sfzCard() }, 1000) } } }, // 图片处理 imgDeals(re) { let file = this.dataURLtoFile('data:image/png;base64,' + re, 'sfzTx.png') let formData = new FormData() formData.append('file', file) formData.append('colorEnum', 'CLEAR') changeIdPhotoBgc(formData).then((res) => { console.log(res) this.photo = res.previewPath }) }, // 读取U盘 readUsb() { let data = { extensions: 'pdf,doc,docx,xls,xlsx,ppt,pptx,jpg,png' } readUsb(data).then((res) => { // console.log(res) if (res) { if(this.UpFile.length != res.length) { // console.log(this.UpFile , res) this.UpFile = res this.usbList = [] res.forEach(re =>{ this.usbList.push({ name: re, sta: false }) }) } } else { this.UpFile = [] this.usbList = [] this.cite.state = { name: '请插入U盘', sta: true } } if(this.$route.name == 'selectFile') { setTimeout(() =>{ this.readUsb() },1000) } }) }, // 处理选中文件 async dealFile() { let {usbList} = this await usbList.forEach(re =>{ if(re.sta) { this.readFile(re.name) } }) }, async readFile(url) { let res = await readFile({filePath: url}) console.log(res) this.cite.selectedFile.push(res.data) }, }, destroyed() { // 销毁监听 if(this.socket) { this.close() } }, mounted() { this.cite.selectedFile = [] if (this.cite.modeName == "扫描打印") { this.init(); }else if(this.cite.modeName == "身份证打印") { this.sfzCard() }else if(this.cite.modeName == "U盘打印") { this.readUsb() } } } </script> <style scoped lang="less"> @font-face { font-family: 'STHeiti';//自定义字体名字 src: url('../assets/typeface/STHeiti.ttf') format('truetype');//定义好文件的相对地址 } @font-face { font-family: 'OCR';//自定义字体名字 src: url('../assets/typeface/OCR-B-10-BT.ttf') format('truetype');//定义好文件的相对地址 } .selectFile { .box { width: 114.06rem; height: 42.13rem; background: #ffffff; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0, 0, 0, 0.14); border-radius: 1.63rem; margin: 0 auto; .tip { //margin-right: 15.31rem; width: 37rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; .title { font-size: 2.88rem; font-weight: bold; color: #d41212; line-height: 4.06rem; } .content { margin: 3rem auto 59px; text-align: center; } } .file { margin-left: 9.69rem; .main { width: 31.63rem; height: 26.56rem; background: #ffffff; border: 0.06rem solid #707070; margin: 0 auto 2.81rem; padding: 1rem 0; overflow-y: scroll; .li { padding-left: 1rem; .name { min-height: 1.8rem; text-align: left; max-width: 80%; margin-left: 1rem; } img { width: 1.3rem; margin-left: 1rem; } } } } .tip2 { width: 52rem; .but { .btn { width: 24.44rem; position: relative; input { position: absolute; width: 100%; height: 100%; top: 0; left: 0; opacity: 0; } } } } .file2 { margin-right: 9.69rem; .title { font-size: 2.13rem; font-weight: bold; color: #323232; line-height: 3rem; //text-align: left; span { text-decoration: underline; font-size: 1.5rem; font-weight: bold; color: #323232; line-height: 2rem; } .act { color: #52a39d; } } .main { width: 39.81rem; height: 31.31rem; background: #eeeeee; margin: 1.38rem auto 0; } .card { //width: 42.81rem; width: 20rem; margin: 0 10rem; height: 35.31rem; display: flex; flex-direction: column; justify-content: space-around; align-items: flex-end; .card-box { width: 25rem; height: 15rem; margin-right: 5rem; position: relative; font-weight: 500; font-size: .9rem; line-height: 1rem; .card-title { padding: 1rem 0; } img { width: 25rem; } .card-sign { position: absolute; bottom: 2.6rem; left: 10.5rem; } .card-date { position: absolute; bottom: 0.5rem; left: 10.5rem; } .card-name { position: absolute; top: 2.2rem; left: 4.5rem; } .card-gender { position: absolute; top: 4.1rem; left: 4.5rem; span { margin-left: 5rem; } } .card-birth { position: absolute; top: 6.15rem; left: 4.5rem; .month { margin-left: 1.7rem; } .day { margin-left: 1.2rem; } } .card-addr { width: 11rem; position: absolute; top: 8.1rem; left: 4.5rem; text-align: left; line-height: 1.3rem; } .card-id { position: absolute; bottom: .8rem; left: 8rem; letter-spacing: .2rem; } .card-avatar { position: absolute; top: 3.2rem; right: 2rem; width: 7rem; height: 9rem; img { width: 7rem; height: 9rem; background-size: contain; } } } .card-box2 { position: relative; font-family: 'STHeiti'; margin: 0 auto; img { width: 100%; } .diamond { position: absolute; top: 0; //left: 60px; right: 0; height: 100%; //font-size: 12px; text-align: left; left: 3.75rem; font-size: 0.75rem; .name { //font-size: 14px; font-family: 'OCR'; //margin: 23px 0 10px; font-size: 0.875rem; margin: 1.4375rem 0 0.625rem; } .gender { div { //margin-left: 50px; margin-left: 3.125rem; } } .birth { //margin: 12px 0; margin: 0.75rem 0; span { //margin-right: 3px; margin-right: 0.1875rem; } div { //width: 20px; //margin-left: 11px; text-align: center; width: 1.25rem; margin-left: 0.6875rem; } } .addr { //width: 150px; //line-height: 18px; width: 9.375rem; line-height: 1.125rem; } .idNum { position: absolute; //bottom: 26px; //left: 46px; //letter-spacing: 2px; font-family: 'OCR'; //font-size: 14px; font-weight: 600; bottom: 1.625rem; left: 2.875rem; letter-spacing: 0.125rem; font-size: 0.875rem; } .avatar { position: absolute; //right: 20px; //top: 40px; //width: 82px; right: 1.25rem; top: 2.5rem; width: 5.125rem; } } .diamond2 { //left: 130px; height: auto; top: auto; //bottom: 21px; left: 8.125rem; bottom: 1.3125rem; .sign { //margin-bottom: 14px; margin-bottom: 0.875rem; } } } } } .file3 { margin-right: 28.13rem; .main { width: 20.75rem; height: 28.88rem; border: 0.06rem solid #707070; margin: 1.06rem 0 0 13.38rem; } } .btn { width: 100%; height: 5.5rem; background: linear-gradient(132deg, #52a39d 0%, #a1c553 50%, #81d012 100%); border-radius: 1.25rem; font-size: 1.88rem; font-weight: 400; color: #ffffff; line-height: 2.63rem; cursor: pointer; } } .smfyData { height: 90%; width: 14.81rem; font-size: 1rem; font-weight: bold; color: #323232; line-height: 2rem; overflow: auto; cursor: pointer; .act { color: #52a39d; } .name { text-decoration: underline; } span { margin-left: 5rem; } } } </style>
<template> <!-- 选取资料--> <div class="selectFile"> <navbar :name="name" /> <!-- U盘打印--> <div class="box flex-center" v-if="name == 'U盘打印'"> <div class="tip"> <div class="title">温馨提示</div> <div class="content">请在右侧文件浏览区,找到文件存放的目录/文件夹,然后点选您要打印的文件,之后按下“确认资料”按钮。</div> </div> <div class="file"> <div class="main"> <div v-for="(item, index) in usbList" v-bind:key="index" class="li flex-start" @click="onChange(index, 'usbList',!item.sta)"> <input type="checkbox" v-model="item.sta"> <div class="name flex-start">{{ item.name }}</div> </div> </div> <div class="flex-between but"> <div class="btn flex-center" @click="skip('argument', name)">确认资料</div> </div> </div> </div> <!-- 扫描打印--> <div class="box flex-center" v-if="name == '扫描打印'"> <div class="file2"> <div class="title flex-between">已完成扫描的版面 <span :class="[{ act: smfyIndex == -1 }]" @click="onChange(-1, 'smfyIndex')">预览</span></div> <div class="main flex-between"> <div class="smfyData"> <div v-for="(item, index) in imgList" v-bind:key="index" :class="['flex-center', { act: smfyIndex == index }]" @click="onChange(index, 'smfyIndex')"> <div class="name">{{ index + 1 }}</div> <span @click="onCancel(index, 'imgList')">删除</span> </div> </div> <img v-show="smfyIndex!=-1" :src="imgList[smfyIndex]" alt="" style="width: 25rem; height: 100%" /> <img v-show="smfyIndex==-1" id="myCanvas" style="width: 25rem; height: 100%" /> </div> </div> <div class="tip tip2"> <div class="title">温馨提示</div> <div class="content"> 已经扫描好的页面显示在左边的列表中,您可以点击列表中的缩略图进行核对,有不满意的请点旁边的“X”进行移除并重新扫描。如果有文件需要继续扫描,请按要求放置好资料后,按“继续扫描”。 按照刚才的方法,重复扫描过程,直到完成了所有需要的页面。核对无误后,可以按“完成扫描”结束资料扫描过程。 </div> <div class="flex-between but"> <div class="btn flex-center" @click="paiz()">继续扫描</div> <div class="btn flex-center" @click="skip('argument', name)">完成扫描</div> </div> </div> </div> <!-- 身份证打印--> <div class="box flex-center" v-if="name == '身份证打印'"> <div class="file2 file3" style="margin-right: 20rem"> <div class="title">请核对您的信息</div> <div class="card" ref="captureArea" v-if="cardInfo!=''"> <div class="card-box2"> <img src="../assets/card2.png" alt="身份证正面" /> <div class="diamond"> <div class="name">{{ cardInfo.name }}</div> <div class="gender flex-start">{{ cardInfo.xbmc }} <div>{{ cardInfo.mzmc }}</div></div> <div class="birth flex-start"> <span>{{ cardInfo.birthday | joinYear }}</span> <div>{{ cardInfo.birthday | joinMonth }}</div> <div>{{ cardInfo.birthday | joinDay }}</div> </div> <div class="addr">{{ cardInfo.address }}</div> <div class="idNum">{{ cardInfo.idNum }}</div> <div class="avatar"><img :src="photo" alt=""></div> </div> </div> <div class="card-box2"> <img src="../assets/card1.png" alt="身份证反面" /> <div class="diamond diamond2"> <div class="sign">{{ cardInfo.issueOrg }}</div> <div class="date">{{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}}</div> </div> </div> <div class="card-box" v-show="false"> <img src="../assets/card2.png" alt="身份证反面" /> <div class="card-name">{{ cardInfo.name }}</div> <div class="card-gender"> {{ cardInfo.xbmc }}<span>{{ cardInfo.mzmc }}</span> </div> <div class="card-birth"> {{ cardInfo.birthday | joinYear }} <span class="month">{{ cardInfo.birthday | joinMonth }}</span> <span class="day">{{ cardInfo.birthday | joinDay }}</span> </div> <div class="card-addr"> {{ cardInfo.address }} </div> <div class="card-id">{{ cardInfo.idNum }}</div> <div class="card-avatar"> <!-- <img :src="'data:image/png;base64,'+cardInfo.photo" alt="" />--> <img :src="photo" alt=""> </div> </div> <div class="card-box" v-show="false"> <img src="../assets/card1.png"/> <div class="card-sign">{{ cardInfo.issueOrg }}</div> <div class="card-date"> {{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}} </div> </div> </div> </div> <div class="tip"> <div class="title">温馨提示</div> <div class="content">身份证件信息读取成功,请您核对个人信息无误后,按“信息无误,继续”按钮进行后续操作。此时您可以取回您的身份证卡片并妥善保存。</div> <div class="btn flex-center" @click="skip('argument', name)">信息无误,继续</div> </div> </div> </div> </template> <script> import navbar from "@/components/nav"; import html2canvas from "html2canvas"; import {upload2Pdf, changeIdPhotoBgc, image2Pdf} from '@/api/resultApi' import {readUsb, readFile, readCard} from '@/api/bdResultApi' import parseCardWzxx from "../utils/mz"; export default { name: 'selectFile', components: { navbar }, provide() { return { title: this.tit, type: this.name } }, filters: { joinYear(val) { return val.substring(0, 4) }, joinMonth(val) { if(val.substring(4, 5)==0) { return val.substring(5, 6) } return val.substring(4, 6) }, joinDay(val) { if(val.substring(6, 7)==0) { return val.substring(7, 8) } return val.substring(6, 8) }, joinRq(val) { return val.substring(0, 4)+'.'+val.substring(4, 6)+'.'+val.substring(6, 8) } }, data() { return { isChecked: true, tit: this.cite.modeName == 'U盘打印' ? '资料选取提交' : '资料扫描提交', name: this.cite.modeName, path: this.cite.inWebURL, socket: '', imgList: [], smfyIndex: -1, photo: '', UpFile: [], cardInfo: '', usbList: [], usbTime: '' }; }, methods: { async uploadImg(data, sta) { let _this = this for (let i = 0; i < data.length; i++) { let formData = new FormData() let file = data[i] if (sta) { // let dataURL = file.toDataURL('image/png') let name = i + '.png' file = _this.dataURLtoFile(file, name) } formData.append('file', file) // 使用数组语法添加多个文件 if(this.cite.modeName=='身份证打印') { let res = await image2Pdf(formData) _this.cite.selectedFile.push(res) // console.log('打印文件', this.cite.selectedFile, res) }else{ let res = await upload2Pdf(formData) _this.cite.selectedFile.push(res) // console.log('打印文件', this.cite.selectedFile, res) } } }, async skip(href, name) { if (this.usbList.length > 0) { // 保存选中的U盘文件 // await this.uploadImg(this.UpFile, false) await this.dealFile() } else if (this.imgList.length > 0) { // 保存高拍仪图片 await this.uploadImg(this.imgList, true) } else if (this.cardInfo) { // 保存身份证图片 await this.captureAndDownload() } else { this.cite.state = { name: '请选择文件打印!', sta: true } return } this.$router.push({ name: href, params: { name: name } }) }, async captureAndDownload() { const captureArea = this.$refs.captureArea // 使用 html2canvas 将区域内容生成为图片 const canvas = await html2canvas(captureArea) // 将 canvas 转为图片 URL const dataURL = canvas.toDataURL('image/png') const name = 'sfz.png' const file = this.dataURLtoFile(dataURL, name) this.uploadImg([file], false) }, dataURLtoFile(dataURL, filename) { const arr = dataURL.split(',') const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, {type: mime}) }, onChange(index, name, sta) { if (name == 'usbList') { this[name][index].sta = sta } else { this[name] = index } }, onCancel(index, name) { if (name == 'imgList') { this.smfyIndex = -1 } this[name].splice(index, 1) }, paiz() { this.socket.send('Capture@2') }, init: function () { if (typeof WebSocket === 'undefined') { alert('您的浏览器不支持socket') } else { // 实例化socket this.socket = new WebSocket(this.path) // 监听socket连接 this.socket.onopen = this.open // 监听socket错误信息 this.socket.onerror = this.error // 监听socket消息 this.socket.onmessage = this.getMessage } }, open: function () { // console.log("socket连接成功") this.socket.send('OpenIdCardEx@0') this.socket.send('OpenDevice@1') this.socket.send('SetResolution@2@2592@1944') this.socket.send('OpenVideo') this.socket.send('RotateRight') this.socket.send('Deskew') }, error: function () { console.log('连接错误') }, getMessage: function (msg) { if (typeof msg.data == 'string') { if (msg.data.indexOf('GetDevCount') == 0) { let s = msg.data.substring(12) if ('1' == s || '2' == s) { //如果是双摄像头 那就需要判断 s = 2;表示当前是连接了2个设备 alert('检测到已经连接上摄像头') } } else if (msg.data.indexOf('Capture') == 0) { let s = msg.data.substring(8) if (s) { this.imgList.push('data:image/jpeg;base64,' + s) } } else if (msg.data.indexOf('MoveDetectEvent') == 0) { this.socket.send('Capture@2') } else if (msg.data.indexOf('IdCardEvent') == 0) { this.socket.send('UnFaceDetect') } else if (msg.data.indexOf('ReadIdCard') == 0) { let s = msg.data.substring(11) if ('1' == s) { this.socket.send('GetIdCardResult@||') this.socket.send('GetIdCardImage@2') } } else if (msg.data.indexOf('GetIdCardResult') == 0) { let s = msg.data.substring(16) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetBarcode') == 0) { // alert(msg.data); let s = msg.data.substring(11) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetIdCardImage') == 0) { let s = msg.data.substring(15) let arr = s.split('#') let faceImg = arr[0] let myimg = document.getElementById('myCanvas3') myimg.src = 'data:image/jpeg;base64,' + faceImg } else if (msg.data.indexOf('GetBase64') == 0) { let s = msg.data.substring(10) let myimg = document.getElementById('myCanvas2') myimg.src = 'data:image/jpeg;base64,' + s alert(s) } else if (msg.data.indexOf('GetRecognitionFromFileName') == 0) { let s = msg.data.substring(27) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetOcrFromFileName') == 0) { let s = msg.data.substring(19) let info = document.getElementById('info') info.value = s } else if (msg.data.indexOf('GetDogSN') == 0) { let s = msg.data.substring(11) let info = document.getElementById('info') info.value = s } } else { let reader = new FileReader() reader.onload = function (msg) { if (msg.target.readyState == FileReader.DONE) { let url = msg.target.result; document.getElementById('myCanvas').src = url; } } reader.readAsDataURL(msg.data) } }, close: function () { // console.log("socket已经关闭") this.socket.close() this.socket = '' }, handleFileChange(event) { let file = event.target.files[0] if (file) { this.UpFile.push(file) } }, // 获取身份证信息 async sfzCard() { let _this = this let res = await readCard() if (res.errorMsg == 'OK') { // console.log(res.resultContent) _this.imgDeals(res.resultContent.photo) _this.cardInfo = parseCardWzxx(res.resultContent) } else { if(this.$route.name == 'selectFile') { setTimeout(() => { this.sfzCard() }, 1000) } } }, // 图片处理 imgDeals(re) { let file = this.dataURLtoFile('data:image/png;base64,' + re, 'sfzTx.png') let formData = new FormData() formData.append('file', file) formData.append('colorEnum', 'CLEAR') changeIdPhotoBgc(formData).then((res) => { console.log(res) this.photo = res.previewPath }) }, // 读取U盘 readUsb() { let data = { extensions: 'pdf,png,jpg,doc,docx,tng' } readUsb(data).then((res) => { // console.log(res) if (res) { if(this.UpFile.length != res.length) { // console.log(this.UpFile , res) this.UpFile = res this.usbList = [] res.forEach(re =>{ this.usbList.push({ name: re, sta: false }) }) } } else { this.UpFile = [] this.usbList = [] } if(this.$route.name == 'selectFile') { setTimeout(() =>{ this.readUsb() },1000) } }) }, // 处理选中文件 async dealFile() { let {usbList} = this await usbList.forEach(re =>{ if(re.sta) { this.readFile(re.name) } }) }, async readFile(url) { let res = await readFile({filePath: url}) console.log(res) this.cite.selectedFile.push(res.data) }, }, destroyed() { // 销毁监听 if(this.socket) { this.close() } }, mounted() { this.cite.selectedFile = [] if (this.cite.modeName == "扫描打印") { this.init(); }else if(this.cite.modeName == "身份证打印") { this.sfzCard() }else if(this.cite.modeName == "U盘打印") { this.readUsb() } } } </script> <style scoped lang="less"> @font-face { font-family: 'STHeiti';//自定义字体名字 src: url('../assets/typeface/STHeiti.ttf') format('truetype');//定义好文件的相对地址 } @font-face { font-family: 'OCR';//自定义字体名字 src: url('../assets/typeface/OCR-B-10-BT.ttf') format('truetype');//定义好文件的相对地址 } .selectFile { .box { width: 114.06rem; height: 42.13rem; background: #ffffff; box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0, 0, 0, 0.14); border-radius: 1.63rem; margin: 0 auto; .tip { //margin-right: 15.31rem; width: 37rem; font-size: 2.25rem; font-weight: bold; color: #323232; line-height: 3rem; .title { font-size: 2.88rem; font-weight: bold; color: #d41212; line-height: 4.06rem; } .content { margin: 3rem auto 59px; text-align: center; } } .file { margin-left: 9.69rem; .main { width: 31.63rem; height: 26.56rem; background: #ffffff; border: 0.06rem solid #707070; margin: 0 auto 2.81rem; padding: 1rem 0; overflow-y: scroll; .li { padding-left: 1rem; .name { min-height: 1.8rem; text-align: left; max-width: 80%; margin-left: 1rem; } img { width: 1.3rem; margin-left: 1rem; } } } } .tip2 { width: 52rem; .but { .btn { width: 24.44rem; position: relative; input { position: absolute; width: 100%; height: 100%; top: 0; left: 0; opacity: 0; } } } } .file2 { margin-right: 9.69rem; .title { font-size: 2.13rem; font-weight: bold; color: #323232; line-height: 3rem; //text-align: left; span { text-decoration: underline; font-size: 1.5rem; font-weight: bold; color: #323232; line-height: 2rem; } .act { color: #52a39d; } } .main { width: 39.81rem; height: 31.31rem; background: #eeeeee; margin: 1.38rem auto 0; } .card { width: 42.81rem; height: 35.31rem; display: flex; flex-direction: column; justify-content: space-around; align-items: flex-end; .card-box { width: 25rem; height: 15rem; margin-right: 5rem; position: relative; font-weight: 500; font-size: .9rem; line-height: 1rem; .card-title { padding: 1rem 0; } img { width: 25rem; } .card-sign { position: absolute; bottom: 2.6rem; left: 10.5rem; } .card-date { position: absolute; bottom: 0.5rem; left: 10.5rem; } .card-name { position: absolute; top: 2.2rem; left: 4.5rem; } .card-gender { position: absolute; top: 4.1rem; left: 4.5rem; span { margin-left: 5rem; } } .card-birth { position: absolute; top: 6.15rem; left: 4.5rem; .month { margin-left: 1.7rem; } .day { margin-left: 1.2rem; } } .card-addr { width: 11rem; position: absolute; top: 8.1rem; left: 4.5rem; text-align: left; line-height: 1.3rem; } .card-id { position: absolute; bottom: .8rem; left: 8rem; letter-spacing: .2rem; } .card-avatar { position: absolute; top: 3.2rem; right: 2rem; width: 7rem; height: 9rem; img { width: 7rem; height: 9rem; background-size: contain; } } } .card-box2 { position: relative; font-family: 'STHeiti'; margin: 0 auto; img { width: 320px; } .diamond { position: absolute; top: 0; left: 60px; right: 0; height: 100%; font-size: 12px; text-align: left; .name { font-size: 14px; font-family: 'OCR'; margin: 23px 0 10px; } .gender { div { margin-left: 50px; } } .birth { margin: 12px 0; span { margin-right: 3px; } div { width: 20px; margin-left: 11px; text-align: center; } } .addr { width: 150px; line-height: 18px; } .idNum { position: absolute; bottom: 26px; left: 46px; letter-spacing: 2px; font-family: 'OCR'; font-size: 14px; font-weight: 600; } .avatar { position: absolute; right: 20px; top: 40px; width: 82px; img { width: 100%; } } } .diamond2 { left: 130px; height: auto; top: auto; bottom: 21px; .sign { margin-bottom: 14px; } } } } } .file3 { margin-right: 28.13rem; .main { width: 20.75rem; height: 28.88rem; border: 0.06rem solid #707070; margin: 1.06rem 0 0 13.38rem; } } .btn { width: 100%; height: 5.5rem; background: linear-gradient(132deg, #52a39d 0%, #a1c553 50%, #81d012 100%); border-radius: 1.25rem; font-size: 1.88rem; font-weight: 400; color: #ffffff; line-height: 2.63rem; cursor: pointer; } } .smfyData { height: 90%; width: 14.81rem; font-size: 1rem; font-weight: bold; color: #323232; line-height: 2rem; overflow: auto; cursor: pointer; .act { color: #52a39d; } .name { text-decoration: underline; } span { margin-left: 5rem; } } } </style>
Show line notes below