y595705120 hace 3 días
padre
commit
2acf7150ea
Se han modificado 3 ficheros con 493 adiciones y 0 borrados
  1. 233 0
      src/containers/certificate/index.css
  2. 254 0
      src/containers/certificate/index.vue
  3. 6 0
      src/router/index.js

+ 233 - 0
src/containers/certificate/index.css

@@ -0,0 +1,233 @@
+.cert-body {
+  width: 100%;
+  overflow-y: hidden;
+  max-width: 500px;
+  margin: 0px auto;
+  background-size: 100% auto;
+  background-color: #4eaceb;
+  font-family: "Arial";
+  color: #fff;
+  background-image: linear-gradient(#207ec8, #fff);
+}
+
+.box_title {
+  height: 3rem;
+  font-size: 1.6rem;
+  text-align: center;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+}
+
+.content_box_title{
+  color: #000;
+  background-color: #f3f8fc;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 57px;
+}
+.content_box_title span{
+  width: 55%;
+  text-align: center;
+}
+
+.sign-serach{
+  width: 360px;
+  margin-top: 1rem;
+  padding-top: 1rem;
+  margin: 1rem auto;
+  background-color: white;
+}
+
+.sign-serach button{
+  padding: 12px 64px;
+}
+
+.mess_style {
+  background-color: #f3f8fc;
+  padding: 1rem;
+  font-size: 1.1rem;
+  color: #999;
+  line-height: 1.5rem;
+  margin-top: 1.2rem;
+}
+
+
+
+.mess_title {
+  color: #000;
+  font-weight: 600;
+  margin-top: 1rem;
+}
+
+.mess_explain {
+  position: relative;
+  width: 6rem;
+  height: 3rem;
+  text-align: right;
+  float: right;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #fff;
+  background: #178ce8;
+  opacity: .7;
+  border-radius: 0 0 0 20px;
+}
+
+.mess_explain img {
+  width: 2rem;
+  margin-right: 8px;
+}
+
+.mess_text {
+  display: inline-block;
+  text-align: justify;
+  text-indent: 2rem;
+  margin-top: .8rem;
+  line-height: 2rem;
+}
+
+
+.qr-code {
+  cursor: pointer; /* 鼠标悬停显示手型,提示可点击 */
+  display: inline-block;
+}
+
+/* 验证码图片样式 */
+.qr-code img {
+  height: 40px; /* 与输入框高度保持一致 */
+  width: auto; /* 自动计算宽度,保持图片比例 */
+  vertical-align: middle; /* 垂直居中对齐 */
+  border-radius: 4px; /* 可选:添加轻微圆角,与输入框风格统一 */
+}
+
+
+.certificate-cards {
+  display: flex;
+  margin-top: 0rem;
+  flex-direction: column;
+  gap: 15px;
+  overflow-y: hidden;
+}
+
+.card {
+  background-color: #fff;
+  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.04);
+}
+
+.card-title {
+  font-size: 15px;
+  font-weight: bold;
+  margin: 0;
+  color: #333;
+}
+
+.card-status {
+  padding: 2px 8px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.card-status.valid {
+  background-color: #e6f7ed;
+  color: #00875a;
+}
+
+.card-status.expired {
+  background-color: #fff2e8;
+  color: #e53e3e;
+}
+
+/* 信息网格布局,适合手机屏幕 */
+.info-grid {
+  display: grid;
+  grid-template-columns: 1fr;
+  gap: 0; /* 移除间隙,让线条连贯 */
+}
+
+.info-item {
+  display: flex;
+  padding: 0;
+}
+
+/* 为第一列(标签列)添加背景色 */
+.certificate-cards .el-table_1_column_1 {
+  flex: 0 0 35%;
+  font-size: 14px;
+  color: #666;
+  background-color: #f5f7fa !important; /* 浅灰色背景 */
+  padding: 10px 8px;
+  border-bottom: 1px solid #e9e9e9;
+  font-weight: 500;
+}
+
+.info-value {
+  flex: 0 0 65%;
+  font-size: 14px;
+  color: #333;
+  padding: 10px 8px;
+  border-bottom: 1px solid #e7f1f9;
+  word-break: break-word;
+}
+
+/* 最后一项去除底部边框 */
+.info-grid :last-child .info-label,
+.info-grid :last-child .info-value {
+  border-bottom: none;
+}
+
+.remark {
+  margin-top: 12px;
+  padding: 8px;
+  background-color: #f5f7fa;
+  border-left: 3px solid #2f86eb;
+  color: #666;
+  font-size: 13px;
+  line-height: 1.5;
+}
+
+.cls-label{
+  background-color: #999;
+}
+/* 适配小屏手机 */
+@media (max-width: 360px) {
+  .main-title {
+    font-size: 15px;
+  }
+  .info-label, .info-value {
+    font-size: 13px;
+    padding: 8px 6px;
+  }
+}
+
+
+
+ /* 左上角后退按钮 */
+.back-button {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 40px;
+    height: 40px;
+    background-color: #1E88E5;
+    border: none;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: background-color 0.3s ease;
+}
+
+.back-button:hover {
+    background-color: #1565C0;
+}
+
+.back-button svg {
+    width: 30px;
+    height: 30px;
+    fill: white;
+}

+ 254 - 0
src/containers/certificate/index.vue

@@ -0,0 +1,254 @@
+<template>
+  <div class="cert-body">
+
+    <div v-if="showTable" class="back-button" @click="showTable=false">
+        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+            <path d="M19 11H7.83l4.88-4.88c.39-.39.39-1.03 0-1.42-.39-.39-1.02-.39-1.41 0l-6.59 6.59c-.39.39-.39 1.02 0 1.41l6.59 6.59c.39.39 1.02.39 1.41 0 .39-.39.39-1.03 0-1.42L7.83 13H19c.55 0 1-.45 1-1s-.45-1-1-1z"/>
+        </svg>
+    </div>
+
+    <el-card style="border-radius: 10px; padding-top: 2rem;">
+      <div class="content_box_title">
+        <img
+          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAOCAYAAABaSYBTAAAABHNCSVQICAgIfAhkiAAAANRJREFUWEftmO0NgyAYhOtOMIxr6By6RoeBnVTqR2rL6wlFOJPyy+QC3j0vIlAZY55a6/ohNHbd2S7tUWJXOcFaOyilXs++xq4zZPBx24CyA0T+GAHvZisKwK6zAf5aCtgBIn9MgL3rLArArrMAvu1PDBWYAbAIl8EcAoj00hkO4ZY2l+L9KcZARZR0CLekuXXvGBvufe/56xgx/U/B/QOeyxQK+DTcmME/Ty2h5lL3z50hCG5uc1ccxXNmCIa7mGunu4hOuIpwn08z6T2rvmS42mM7AlIFLwQXiU8MAAAAAElFTkSuQmCC" />
+        <span style="font-weight: 700;">{{showTable?'培训信息验证结果':'培训信息查询'}}</span>
+        <img
+          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAOCAYAAABaSYBTAAAABHNCSVQICAgIfAhkiAAAALRJREFUWEft2LENgCAQBVCZwtoZkBHcwtItnMTedSgI29CgmGhiRBS8K0w+7YX75AEFiCpzGGMa59yglBpjU7nrIZM7g6q/yLHVWkvv/dSuIzaPux4yuTMo+7/GpQwt2Zi/wYb1vsIFbNmNecQFbBns48kFbDlsEhew32BvcQH7HTaKC1ga2AsuYOlgT7iApYU9cAFLD7vhApYHdsftpZRz7Elqra3XT5qOqx4yuTO4+6f+ZhZW89Ai/bICGAAAAABJRU5ErkJggg==" />
+      </div>
+
+      <div v-if="showTable">
+        <div class="certificate-cards">
+          <div v-for="(certificate, index) in certificates" :key="index" class="card">
+            <el-table :data="certificate.tableData" border style="width: 100%" :show-header="false">
+              <el-table-column prop="label" label="项目"
+                width="110"
+               :cell-style="{ backgroundColor: '#000' }"/>
+              <el-table-column prop="value" label="内容" />
+            </el-table>
+
+            <h3 style="margin: 1rem;">培训记录</h3>
+
+            <el-table :data="certificate.logList" stripe border style="width: 100%;fant-size:1rem" highlight-current-row class="dark-header-table">
+              <el-table-column prop="dateRange" label="培训日期" align="left" width="100px">
+                <template slot-scope="{row}">
+                  <span>{{row.startDate}}</span>
+                  <p>至</p>
+                  <span>{{row.endDate}}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column prop="certificateOrgan"  label="培训机构" align="left" />
+              <el-table-column prop="xs"      label="培训学时" width="60px" align="center" />
+              <el-table-column prop="result"   label="是否合格"  width="60px" align="center"/>
+            </el-table>
+          </div>
+        </div>
+      </div>
+
+      <div v-else>
+        <el-form class="sign-serach" :rules="rules" :inline="false" :model="searchInfo" ref="searchForm"
+          label-width="80px">
+          <el-form-item label="身份证号" prop="cardId">
+            <el-input placeholder="输入身份证" v-model="searchInfo.cardId" type="text" style="width:260px;"
+              clearable></el-input>
+          </el-form-item>
+          <el-form-item label="学员姓名" prop="nickname">
+            <el-input placeholder="输入姓名" v-model="searchInfo.nickname" type="text" style="width:260px;"
+              clearable></el-input>
+          </el-form-item>
+
+
+          <el-form-item label="校验码" prop="code">
+            <el-input placeholder="校验码" v-model="searchInfo.code" type="text" style="width:130px;" clearable></el-input>
+            <span class="qr-code ng-scope" @click="changeCode()">
+              <img alt="验证码" :src="codeShow" v-show="codeShow">
+            </span>
+          </el-form-item>
+
+          <el-form-item class="form-btn-group" label-width="0px">
+            <el-button size="medium" @click="resetForm">重 置</el-button>
+            <el-button size="medium" type="primary" @click="queryCertificate">查 询</el-button>
+          </el-form-item>
+        </el-form>
+
+
+        <div class="mess_style">
+          <div class="mess_explain">
+            <img
+              src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABHNCSVQICAgIfAhkiAAAATZJREFUSIm1lrtxwzAQRA8czTh36h5UgBKjEVfgBpyJylyDmwEVuhnHzp4DH6QT/hKlneFwCO7eLsATICcdAF5E9mbI630RkaOIiHNu7tWpFgcCOUpjANcZJYWCGvqE44FZLwtfrlpP3xZcaq1ZfVY2fYPzNGiUBzSEagrgHfgFvhocXzSyCRril2Tt3xrcuOTBDg51CPBtuNsO9zwbM72mgQqfgU9gN8CNdcNGzj+uLpxzPyLyMcq3juE0rTHe0NKq5v879z64EfgbTALApM9LT7AG0cQ/qP4xmiwip9323thHk4djEpGDdb0XTGMcJufcog/Zdr4Sr5lrttfkyYZbmNpm2xNrz6eX74TJTOovB8HloVeuwejptlZLfmbPtYbQ5OmRPR6uYIYWm6n/iymGudXsquJ/zhquFSAu+Z8AAAAASUVORK5CYII=" />
+            <span>说明</span>
+          </div>
+          <div style="margin-top: 3rem;">
+            <div class="mess_title">01、证书依据</div>
+            <div class="mess_text">
+              《中华人民共和国安全生产法》《生产经营单位安全培训规定》等,要求工贸企业从业人员经安全培训合格,特种作业人员需持特种作业操作证,以规范安全管理。            </div>
+            <div class="mess_title">02、查询范围</div>
+            <div class="mess_text">
+              本平台提供由宁德市应急管理部门按照国家有关规定经宁德聚仁教育服务有限公司培训,取得相应其他生产经营单位主要负责人及安全生产管理人员证件的信息查询。
+            </div>
+            <div class="mess_title">03、相关说明</div>
+            <div class="mess_text">
+              平台中数据由宁德聚仁教育服务有限公司提供,经宁德市应急管理部门备案,如对查询结果存有疑问,请与原发证部门联系。            </div>
+          </div>
+        </div>
+      </div>
+    </el-card>
+  </div>
+</template>
+<script>
+  import {
+    httpServer
+  } from "@/components/httpServer/httpServer.js";
+  export default {
+    data() {
+      return {
+        id:'',
+        codeShow: '',
+        showTable: false,
+        certificates: [],
+        searchInfo: {
+          cardId: '',
+          nickname: '',
+          code: '',
+          courseType: '特种作业',
+          captchaId: '',
+        },
+        rules: {
+          code: [{
+              required: true,
+              message: '请输入校验码',
+              trigger: 'blur'
+            },
+            {
+              len: 5,
+              message: '校验码有误',
+              trigger: 'blur'
+            },
+          ],
+          nickname: [{
+            required: true,
+            message: '请输入姓名',
+            trigger: 'blur',
+            min: 2
+          }],
+          cardId: [{
+              required: true,
+              message: '请输入身份证号码',
+              trigger: 'blur'
+            },
+            {
+              validator: (rule, value, callback) => {
+                if (!value) {
+                  return callback(new Error('请输入身份证号码'));
+                }
+                const cleanValue = value.replace(/[\s()]/g, '').toUpperCase();
+                const mainlandReg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
+                const hkReg = /^(?:C(?:\d{8}|[A-HJ-NP-Z]\d{7})|[HM](?:\d{10}|\d{8}))$/;
+                if (mainlandReg.test(cleanValue) || hkReg.test(cleanValue)) {
+                  callback();
+                } else {
+                  callback(new Error('请输入正确的大陆身份证(18位)或香港身份证(如 A1234567)'));
+                }
+              },
+              trigger: 'blur'
+            }
+          ],
+        },
+      }
+    },
+    methods: {
+      resetForm() {
+        this.searchInfo.cardId = '';
+        this.searchInfo.nickname = '';
+
+      },
+      changeCode() {
+        httpServer("Auth.GetValidateCode", {}).then(res => {
+          if (res.code == 200) {
+            this.codeShow = res.data.codeData;
+            this.searchInfo.captchaId = res.data.captchaId;
+          } else {
+            this.codeShow = ''
+          }
+        })
+      },
+      packData(data) {
+        this.showTable = true;
+        let firstItem = data[0]||{};
+        let logList = [];
+        for (let i in data) {
+          let item = data[i];
+          logList.push({startDate:item.startDate, endDate:item.endDate, xs:item.xs, result:item.result, certificateOrgan:item.certificateOrgan})
+        }
+        let certificate = {
+          logList,
+          tableData: [{
+              label: '姓名',
+              value: firstItem.nickname
+            },
+            {
+              label: '性别',
+              value: firstItem.gender
+            },
+            {
+              label: '身份证号',
+              value: firstItem.cardId
+            },
+            {
+              label: '人员类型',
+              value: firstItem.courseName
+            },
+            {
+              label: '行业类别',
+              value: firstItem.certificateType
+            },
+            {
+              label: '单位名称',
+              value: firstItem.company
+            },
+            {
+              label: '初领日期',
+              value: firstItem.signDate
+            }
+          ]
+        }
+        this.certificates = [certificate];
+
+      },
+      queryCertificate() {
+        this.$refs.searchForm.validate(valid => {
+          if (!valid) this.changeCode();
+          let param = Object.assign({}, this.searchInfo);
+          httpServer("Auth.QueryCert", param).then(res => {
+            this.changeCode();
+            if (res.code != 200) return;
+            this.packData(res.data || []);
+            this.showTable = true;
+            this.changeCode()
+          })
+        });
+      },
+      queryCertificateById(id) {
+        let param = {id:id};
+          httpServer("Auth.QueryCertById", param).then(res => {
+            this.changeCode();
+            if (res.code != 200) return;
+            this.packData(res.data || []);
+            this.showTable = true;
+            this.changeCode()
+          })
+        });
+      }
+    },
+    created() {
+      this.id = this.$route.query.id || '';
+      if(this.id){
+        this.showTable = true;
+      }
+      this.changeCode();
+    }
+  }
+</script>
+<style>
+  @import url("./index.css");
+</style>

+ 6 - 0
src/router/index.js

@@ -43,6 +43,7 @@ import CenterExamScore from '@/containers/center/exam/score'
 import CenterExamDownload from '@/containers/center/exam/download'
 
 import CenterUserSeat from '@/containers/center/userSeat/index'
+import PublicCertificate from '@/containers/certificate/index'
 
 Vue.use(Router)
 
@@ -60,6 +61,11 @@ export default new Router({
       name: 'register',
       component: Register,
     },
+    {
+      path: '/sm-sign',
+      name: 'sm-sign',
+      component: PublicCertificate,
+    },
     {
       path: '/sign',
       name: 'sign',