实现背景:之前电子证书的实现是后端实现的,主要采用GD库技术,在底图上添加文字水印和图片水印实现的。这里采用前端技术实现电子证书的呈现以及点击证书下载,优点是:后端给前端传递的是一组数据,不需要传证书的图片,交互所需数据流大大减少了。后端不需要生成证书,就不需要额外开辟存储证书的空间,当用户量很大时,节省开支。
前端技术栈:vite+vue3+typescript+elementPlus
证书查询首页实现,代码如下:
<template><el-rowclass="header"><el-col:span="24"><el-text>电子证书查询系统</el-text></el-col></el-row><el-rowclass="main"><el-col:span="24"><el-cardstyle="max-width: 680px"shadow="always"><template#header><divclass="card-header"><span>证书查询系统</span></div></template><el-formref="ruleFormRef":model="ruleForm":rules="rules"label-width="auto"class="demo-ruleForm":size="formSize":label-position="labelPosition"status-icon><el-form-itemlabel="姓 名"prop="name"><el-inputv-model="ruleForm.name"placeholder="请输入姓名"/></el-form-item><el-form-itemlabel="身份证号"prop="idNo"><el-inputv-model="ruleForm.idNo"placeholder="请输入身份证号"/></el-form-item><el-form-itemlabel="证书编号"prop="certificateNo"><el-inputv-model="ruleForm.certificateNo"placeholder="请输入证书编号"/></el-form-item><el-form-item><el-buttontype="primary"@click="submitForm(ruleFormRef)"> 查询 </el-button></el-form-item></el-form></el-card></el-col></el-row></template><scriptlang="ts"setupname="CertificateIndex">import{ reactive, ref }from'vue'import type { ComponentSize, FormInstance, FormRules, FormProps }from'element-plus'import{ ElMessage }from'element-plus'import{ createItem }from'../services/crudService'import{ useRouter }from'vue-router'const router =useRouter()interfaceRuleForm{name: string
idNo: string
certificateNo: string
}const formSize = ref<ComponentSize>('large')const labelPosition = ref<FormProps['labelPosition']>('left')const ruleFormRef = ref<FormInstance>()const ruleForm = reactive<RuleForm>({name:'',idNo:'',certificateNo:''})const rules = reactive<FormRules<RuleForm>>({name:[{required:true,message:'请输入姓名',trigger:'blur'}],idNo:[{required:true,message:'请输入身份证号',trigger:'blur'}],certificateNo:[{required:true,message:'请输入证书编号',trigger:'blur'}]})constsubmitForm=async(formEl: FormInstance |undefined)=>{if(!formEl)return// Validate the formawait formEl.validate()// If validation passes, call createItem with the form dataconst{ data }=awaitcreateItem(ruleForm)if(!data.id){ElMessage({message:'暂无此人相关证书!',type:'warning'})return}
router.push({name:'CertificateDetail',query:{data:JSON.stringify(data)}})}</script><stylescopedstyle="scss">.header{background-color: #1174c2;width: 100%;height: 50px;.el-col{text-align: center;vertical-align: center;padding: 0.5rem 0;.el-text{font-size: 1.5rem;color: #fff;}}}.main{margin-top: 100px;.el-col{.el-card{margin: 0 auto;.card-header{text-align: center;vertical-align: center;font-size: 1.5rem;background-color: #1174c2;color: #fff;width: 100%;padding: 0.8rem 0;}.el-form{.el-form-item{margin: 2rem auto;}.el-button{font-size: 1.5rem;padding: 1.5rem 0;width: 100%;background-color: #1174c2;}}}}}</style>
证书查询首页实现,效果呈现如下:
电子证书查询结果实现,代码如下:
<template><divclass="main"><divclass="card-header p-2 w-full bg-[#1174c2] text-[#fff] text-center text-xl fixed top-0 left-0 w-full z-50"><span>电子证书查询结果</span></div><el-cardshadow="always"class="mt-20"><divclass="content"ref="contentToCapture"><divclass="logo w-28 h-10 mt-4"></div><divclass="text-center mt-20 mb-6 text-lg dirBlod font-bold">内部审核员证书</div><divclass="mb-4 main"><img:src="crossOriginImageSrc"alt="Cross-origin image"style="width: 88px;height: 118px"fit="cover"/><divclass="text-base mt-6">{{ form.name }}</div></div><divclass="id text-base mb-4 dirBlod text-center">ID: {{ form.idNo }}</div><divclass="text text-base"><divclass="mb-4 dirBlod text-center">兹证明其参加了 {{ form.course }}</div><divclass="ml-4 dirBlod">内部审核员培训课程并经考核合格,特发此证。</div></div><divclass="footer mt-20"><divclass="text-xs"><divclass="dirBlod leading-6">发证日期 {{ form.authorizationDate }}</div><divclass="dirBlod leading-6">编号 {{ form.certificateNo }}</div><divclass="dirBlod leading-6">查询 {{ form.url }}</div></div><divclass="text-base dirBlod gz-bg"><divclass="gz-bg-img"></div>
xx教育培训有限公司
</div></div></div><div@click="captureAndDownload"class="text-center mt-5 text-blue-600 cursor-pointer">
证书下载
</div></el-card></div></template><scriptlang="ts"setupname="CertificateDetail">import{ ref, reactive, onMounted }from'vue'import{ useRoute }from'vue-router'import html2canvas from'html2canvas'import{ saveAs }from'file-saver'// 后端基本路径const url ='/dev-api'const route =useRoute()const form =reactive(JSON.parse(route.query.data as string))const crossOriginImageSrc =ref(url + form.path)// 示例跨域图片const contentToCapture = ref<HTMLDivElement>()asyncfunctioncaptureAndDownload(){if(!contentToCapture.value)returntry{const canvas =awaithtml2canvas(contentToCapture.value,{useCORS:true// 允许跨域请求})const imgDataUrl = canvas.toDataURL('image/png')const uniqueBlobUrl =URL.createObjectURL(newBlob([awaitfetch(imgDataUrl).then((res)=> res.blob())],{type:'image/png'}))saveAs(uniqueBlobUrl,'screenshot.png')}catch(error){
console.error('Error capturing screenshot:', error)}}</script><stylescopedlang="scss">.main{display: flex;flex-direction: column;justify-content: center;align-items: center;}.card-header{height: 50px;}.el-card{margin-top: 60px;margin-bottom: 60px;width: 620px;}.content{position: relative;background:url(@/assets/images/bg.png) no-repeat;background-size: 100% 100%;height: 880px;padding: 106px;font-family:'dirBlod', sans-serif;.logo{background:url(@/assets/images/logo.png) no-repeat;background-size: 100% 100%;}}.footer{display: flex;justify-content: space-between;align-items: center;}.dirBlod{font-family:'dirBlod', sans-serif;}.gz-bg{position: relative;.gz-bg-img{position: absolute;top: -280%;left: 20%;width: 120px;height: 120px;background:url(@/assets/images/seal.png) no-repeat;background-size: 100% 100%;}}</style>
电子证书查询结果实现,效果呈现如下:
小结:
1、节省了存储电子证书图片的空间;
2、后端负责数据,前端负责呈现,实现更加灵活
版权归原作者 程序员buddha2080 所有, 如有侵权,请联系我们删除。