From 75f6a814525dfd3b19e359a3dfa3de3e9226f32d Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期二, 26 十一月 2024 15:08:46 +0800
Subject: [PATCH] 更新

---
 src/assets/styles/font/fangzhengKT.ttf                                          |    0 
 src/permission.js                                                               |    2 
 src/views/safetyReview/expertManage/experts/index.vue                           |   26 ++---
 src/utils/htmlToPdf.js                                                          |   50 ++++++++++
 package.json                                                                    |    2 
 src/views/safetyReview/expertManage/checkProgress/index.vue                     |   27 +++--
 src/views/safetyReview/expertManage/checkProgress/components/certificatePdf.vue |   53 ++++++++++
 src/views/certificatePdf.vue                                                    |   92 ++++++++++++++++++
 src/assets/images/certBg.jpg                                                    |    0 
 src/router/index.js                                                             |    5 +
 10 files changed, 230 insertions(+), 27 deletions(-)

diff --git a/package.json b/package.json
index fbc916a..6d172b9 100644
--- a/package.json
+++ b/package.json
@@ -27,9 +27,11 @@
     "element-plus": "2.2.27",
     "file-saver": "2.0.5",
     "fuse.js": "6.6.2",
+    "html2canvas": "^1.4.1",
     "js-base64": "^3.7.5",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.3.1",
+    "jspdf": "^2.5.2",
     "nprogress": "0.2.0",
     "pinia": "2.0.22",
     "quill": "^2.0.0-dev.3",
diff --git a/src/assets/images/certBg.jpg b/src/assets/images/certBg.jpg
new file mode 100644
index 0000000..3847592
--- /dev/null
+++ b/src/assets/images/certBg.jpg
Binary files differ
diff --git a/src/assets/styles/font/fangzhengKT.ttf b/src/assets/styles/font/fangzhengKT.ttf
new file mode 100644
index 0000000..1ef7053
--- /dev/null
+++ b/src/assets/styles/font/fangzhengKT.ttf
Binary files differ
diff --git a/src/permission.js b/src/permission.js
index f8a49a3..eef296e 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -11,7 +11,7 @@
 
 NProgress.configure({ showSpinner: false });
 
-const whiteList = ['/homePage','/fillForm','/checkProgress'];
+const whiteList = ['/homePage','/fillForm','/checkProgress','/certPdf'];
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
diff --git a/src/router/index.js b/src/router/index.js
index ebac8ec..e929a04 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -58,6 +58,11 @@
     hidden: true
   },
   {
+    path: '/certPdf',
+    component: () => import('@/views/certificatePdf'),
+    hidden: true
+  },
+  {
     path: '/checkProgress',
     component: () => import('@/views/safetyReview/expertManage/checkProgress/index.vue'),
     hidden: true
diff --git a/src/utils/htmlToPdf.js b/src/utils/htmlToPdf.js
new file mode 100644
index 0000000..3dcb647
--- /dev/null
+++ b/src/utils/htmlToPdf.js
@@ -0,0 +1,50 @@
+// 导出页面为PDF格式
+import html2Canvas from 'html2canvas';
+import JsPDF from 'jspdf';
+
+export default function htmlToPdf(title=new Date().getTime()) {
+    return html2Canvas(document.body, {
+        // useCORS:true, //保证跨域图片的显示
+        // width:window.screen.availWidth, //显示canvas窗口的宽度
+        // height:window.screen.availHeight, //显示canvas窗口的高度
+        // windowHeight: document.body.scrollHeight, //获取y方向滚动条中的内容
+        // windowWidth: document.body.scrollWidth,//获取x方向滚动条中的内容
+        // x:0, //页面在水平方向上没有滚动,故设置为0
+        // y: window.pageXOffset  //页面在垂直方向的滚动距离
+    }).then(function (canvas) {
+        let contentWidth = canvas.width;
+        let contentHeight = canvas.height;
+        let pageHeight = contentWidth / 592.28 * 841.89;
+        let leftHeight = contentHeight;
+        let position = 0;
+        // let imgWidth = 595.28;
+        // let imgHeight = 592.28 / contentWidth * contentHeight;
+        let imgWidth = 838.89;
+        let imgHeight = 835.89 / contentWidth * contentHeight;
+
+        // 将图片转化为dataUrl
+        let pageData = canvas.toDataURL('image/jpeg', 1.0);
+
+        // 三个参数,第一个方向(landscape横向?),第二个尺寸,第三个尺寸格式
+        let PDF = new JsPDF('landscape', 'pt', 'a4');
+
+        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度      (841.89)
+        //当内容未超过pdf一页显示的范围,无需分页
+        if (leftHeight < pageHeight) {
+            // 0, 0, 控制文字距离左边,与上边的距离,后两个参数控制添加图片的尺寸,此处将页面高度按照     a4纸宽高比列进行压缩
+            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
+        } else {
+            while (leftHeight > 0) {
+                PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
+                leftHeight -= pageHeight;
+                position -= 841.89;
+                //避免添加空白页
+                if (leftHeight > 0) {
+                    PDF.addPage();
+                }
+            }
+        }
+        PDF.save(title + '.pdf');
+    });
+
+}
\ No newline at end of file
diff --git a/src/views/certificatePdf.vue b/src/views/certificatePdf.vue
new file mode 100644
index 0000000..f67bbc8
--- /dev/null
+++ b/src/views/certificatePdf.vue
@@ -0,0 +1,92 @@
+<template>
+  <div class="form-container">
+      <div class="certContent" @click="getPdf()">
+        <div class="main-content">
+          兹聘任{{info.name}}同志为自治区应急管理厅专家,聘任期为{{info.employmentDateStart?.substring(0,4)}}年{{info.employmentDateStart?.substring(5,7)}}月至{{info.employmentDateEnd?.substring(0,4)}}年{{info.employmentDateEnd?.substring(5,7)}}月。
+        </div>
+        <div class="main-content">
+          特发此证!
+        </div>
+        <div class="footer-content">
+          自治区应急管理厅<br/>
+          {{info.updateTime?.substring(0,4)}}年{{info.updateTime?.substring(5,7)}}月
+        </div>
+      </div>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, onMounted, nextTick} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus"
+import htmlToPdf from '@/utils/htmlToPdf';
+import { useRoute } from 'vue-router'
+const { proxy } = getCurrentInstance();
+const route = useRoute();
+const data = reactive({
+  info: {}
+})
+const {info} = toRefs(data)
+onMounted(()=>{
+  data.info = route.query
+  nextTick(()=>{
+    getPdf()
+  })
+})
+
+function getPdf() {
+  let title = data.info.name + '专家聘书'
+  htmlToPdf(title);
+}
+
+onMounted(()=>{
+
+})
+
+defineExpose({
+  getPdf
+})
+</script>
+
+<style scoped lang="scss">
+@font-face {
+  font-family: "fangzhengKT";
+  src: url("@/assets/styles/font/fangzhengKT.ttf");
+  font-style: normal;
+  font-weight: normal;
+}
+.form-container{
+  padding: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  .certContent{
+    width: 1920px;
+    height: 1280px;
+    background: url("@/assets/images/certBg.jpg") no-repeat center;
+    background-size: contain;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 550px 380px 80px;
+    color: #9e0500;
+
+    .main-content{
+      width: 100%;
+      font-size: 50px;
+      text-align: left;
+      line-height: 1.8;
+      text-indent: 100px;
+      letter-spacing: 2px;
+      font-family: 'fangzhengKT';
+    }
+
+    .footer-content{
+      font-size: 36px;
+      transform: translate(200px,120px);
+      text-align: center;
+      line-height: 1.8;
+    }
+  }
+}
+</style>
diff --git a/src/views/safetyReview/expertManage/checkProgress/components/certificatePdf.vue b/src/views/safetyReview/expertManage/checkProgress/components/certificatePdf.vue
new file mode 100644
index 0000000..4ada139
--- /dev/null
+++ b/src/views/safetyReview/expertManage/checkProgress/components/certificatePdf.vue
@@ -0,0 +1,53 @@
+<template>
+  <div class="form-container">
+      <div class="certContent">
+        <div></div>
+      </div>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, onMounted} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus"
+import htmlToPdf from '@/utils/htmlToPdf';
+const { proxy } = getCurrentInstance();
+
+const data = reactive({
+  info: {}
+})
+
+const {info} = toRefs(data)
+const deptList = ref([]);
+onMounted(()=>{
+
+})
+
+function getPdf(info) {
+  console.log(info,'info')
+  htmlToPdf();
+}
+
+onMounted(()=>{
+
+})
+
+defineExpose({
+  getPdf
+})
+</script>
+
+<style scoped lang="scss">
+.form-container{
+  padding: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  .certContent{
+    width: 1123px;
+    height: 794px;
+    background: url("@/assets/images/certBg.jpg") no-repeat;
+    background-size: contain;
+  }
+}
+</style>
diff --git a/src/views/safetyReview/expertManage/checkProgress/index.vue b/src/views/safetyReview/expertManage/checkProgress/index.vue
index b448ce7..be60b04 100644
--- a/src/views/safetyReview/expertManage/checkProgress/index.vue
+++ b/src/views/safetyReview/expertManage/checkProgress/index.vue
@@ -1,13 +1,13 @@
 <template>
   <div class="form-container">
     <el-form :model="queryParams" size="default" ref="formRef" inline :rules="formRules" label-width="110px" >
-      <el-form-item label="身份证号:" prop="idCard">
+      <el-form-item label="身份证号:">
         <el-input v-model.trim="queryParams.idCard" placeholder="请输入身份证号"></el-input>
       </el-form-item>
-      <el-form-item label="手机号:" prop="phone">
+      <el-form-item label="手机号:">
         <el-input v-model.trim="queryParams.phone" placeholder="请输入申报时预留的手机号"></el-input>
       </el-form-item>
-      <el-form-item label="业务处室:" prop="deptId">
+      <el-form-item label="业务处室:">
         <el-cascader
             clearable
             placeholder="请选择申请的业务处室"
@@ -27,10 +27,10 @@
         <span v-if="result.state == 3">评定不符合</span>
         <span v-if="result.state == 2">评定通过</span>
       </button>
-      <button :class="result.state == 4?'pro-btn-active':'pro-btn'">
+      <button :class="result.state == 2?'pro-btn-active':'pro-btn'">
         专家入库
       </button>
-      <button :class="result.state == 4?'pro-download-active':'pro-download'">
+      <button :class="result.state == 2?'pro-download-active':'pro-download'" @click="downloadPdf(result)">
         专家证书下载
       </button>
     </div>
@@ -38,14 +38,15 @@
 </template>
 <script setup>
 import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import { useRouter } from 'vue-router'
 import {ElMessage, ElMessageBox} from "element-plus"
 import {verifyPhone, verifyIdCard} from "../../../../utils/validate"
 import { getToken } from "@/utils/auth"
 import {getExpertsList, queryApprove} from "@/api/form";
 import {listOutDept} from "@/api/system/dept";
-
+import CertificatePdf from './components/certificatePdf'
 const { proxy } = getCurrentInstance();
-
+const router = useRouter()
 let validatePhone = (rule, value, callback)=>{
   if(value === ''){
     callback(new Error('请输入手机号'))
@@ -76,9 +77,7 @@
     deptId: null
   },
   formRules:{
-    idCard:[{ required: true, validator: verifyId, trigger: 'blur' }],
-    phone:[{ required: true, validator: validatePhone, trigger: 'blur' }],
-    deptId: [{ required: true, message: '请选择申请的业务处室', trigger: 'blur' }]
+
   },
   result: {}
 })
@@ -91,7 +90,6 @@
 
 const showProgress = ref(false)
 const formRef = ref()
-
 function getDepList() {
   listOutDept({}).then(response => {
     deptList.value = proxy.handleTree(response.data, "deptId",'parentId','children');
@@ -120,6 +118,13 @@
   })
 }
 
+const downloadPdf=(info)=>{
+  const routePath = '/certPdf';
+  const resolvedRoute = router.resolve(routePath);
+  const queryString = new URLSearchParams(info).toString();
+  const fullPath = `${resolvedRoute.href}?${queryString}`;
+  window.open(fullPath, '_blank');
+}
 
 const resetQuery = ()=>{
   data.queryParams = {
diff --git a/src/views/safetyReview/expertManage/experts/index.vue b/src/views/safetyReview/expertManage/experts/index.vue
index 26a6f23..82cc3b7 100644
--- a/src/views/safetyReview/expertManage/experts/index.vue
+++ b/src/views/safetyReview/expertManage/experts/index.vue
@@ -89,19 +89,7 @@
         </el-table-column>
         <el-table-column label="专家聘书" align="center" prop="expertCertificate">
           <template #default="scope">
-            <div class="demo-image__preview" v-if="scope.row.expertCertificate && scope.row.expertCertificate!==''">
-              <el-image
-                  style="width: 100px; height: 100px"
-                  :src= "scope.row.expertCertificate"
-                  :zoom-rate="1.2"
-                  :max-scale="7"
-                  :min-scale="0.2"
-                  :preview-src-list="[scope.row.expertCertificate]"
-                  :initial-index="0"
-                  fit="cover"
-                  :preview-teleported=true
-              />
-            </div>
+            <el-button type="primary" link @click="viewCert(scope.row)">查看</el-button>
           </template>
         </el-table-column>
         <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
@@ -126,8 +114,8 @@
 import {ElMessage, ElMessageBox} from "element-plus";
 import ExpertForm from "../applyRecords/components/expertForm";
 import {delExpert, getExpertsList, getExpertTypes} from "../../../../api/form";
-import { Plus } from '@element-plus/icons-vue'
-
+import {useRouter} from "vue-router";
+const router = useRouter();
 const loading = ref(false);
 const data = reactive({
   showSearch: true,
@@ -222,6 +210,14 @@
   return null;
 }
 
+const viewCert=(info)=>{
+  const routePath = '/certPdf';
+  const resolvedRoute = router.resolve(routePath);
+  const queryString = new URLSearchParams(info).toString();
+  const fullPath = `${resolvedRoute.href}?${queryString}`;
+  window.open(fullPath, '_blank');
+}
+
 const getSupport =(safety,prevention,emergency)=>{
   let str = []
   let safeArr = safety?.split(',')

--
Gitblit v1.9.2