<!-- 毕业教育考试数据统计报告 -->
<template>
  <div class="dataStatisticsReport-addPage">
    <!-- 操作按钮区 -->
    <!--<div class="action-bar">-->
      <!--<p class="page-inquire-common-style-button download-btn" @click="downloadPdf">-->
        <!--<i class="el-icon-download"></i> 下载PDF-->
      <!--</p>-->
    <!--</div>-->

    <!-- 报告主体（用于截图的区域） -->
    <div class="report-wrap" ref="reportWrap" v-show="showType">
      <div class="report-wrap-big-box">
        <div class="report-wrap-min-box">
          <!--logo-->
          <div class="logo-box">
            <img :src="logUrl" />
          </div>
          <!--标题-->
          <p class="title-p">实验室安全教育成绩报告</p>
          <!--用户信息-->
          <div class="user-box">
            <div class="user-min-box">
              <div>
                <p>姓名：</p>
                <p>{{newData.userName}}</p>
              </div>
              <div>
                <p>学号：</p>
                <p>{{newData.account}}</p>
              </div>
            </div>
            <div class="user-min-box">
              <div>
                <p>学院：</p>
                <p>{{newData.deptName}}</p>
              </div>
              <div>
                <p>年级：</p>
                <p>{{newData.grade}}</p>
              </div>
            </div>
            <div class="user-min-box">
              <div>
                <p>用户类型：</p>
                <p>{{newData.educationTypeName}}</p>
              </div>
            </div>
          </div>
          <!--学年学时-->
          <div class="study-hours-max-big-box" v-if="newData.studyHoursList[0]">
            <div class="study-hours-title-box">
              <p></p>
              <p>学年学时完成情况</p>
            </div>
            <div class="study-hours-text-title-box">
              <p>学年</p>
              <p>完成学时</p>
              <p>要求学时</p>
            </div>
            <div class="study-hours-for-box" v-for="(item,index) in newData.studyHoursList" :key="index">
              <p>{{item.academicYear}}</p>
              <p>{{item.completedStudyHours}}</p>
              <p>{{item.studyHoursRequirement}}</p>
            </div>
            <div class="study-hours-bottom-box">
              <p>累计</p>
              <p>{{newData.totalStudyHours}} 学时</p>
            </div>
          </div>
          <!--考试通过记录-->
          <div class="study-hours-max-big-box-2" v-if="newData.examPassRecords[0]">
            <div class="study-hours-title-box">
              <p></p>
              <p>考试通过记录</p>
            </div>
            <div class="study-hours-text-title-box">
              <p>学年</p>
              <p>考试类型</p>
              <p>成绩</p>
            </div>
            <div class="study-hours-for-box" v-for="(item,index) in newData.examPassRecords" :key="index">
              <p>{{item.academicYear}}</p>
              <p>{{item.examTypeName}}</p>
              <p>{{item.score}}</p>
            </div>
          </div>
          <!--描述信息-->
          <p class="study-text-p">该同学在校期间认真完成实验室安全教育各项学习任务，累计完成 <span>{{newData.totalStudyHours}}</span> 学时安全培训，通过全部年度安全考核，具备良好的实验室安全意识和规范操作能力，特此证明。</p>
          <!--落款-->
          <div class="signature-box">
            <p>{{newData.issuingUnit}}</p>
            <p>{{newData.issuingTime}}</p>
          </div>
          <!-- 水印 -->
          <!--<div class="watermark-box">-->
            <!--<span v-for="n in 40" :key="n" class="watermark-text">实验室安全教育</span>-->
          <!--</div>-->
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import { examElLabEduRelationGraduationReport } from "@/api/safetyEducationExaminationNew/index";
  import html2canvas from 'html2canvas'
  export default {
    name: 'dataStatisticsReport',
    props: {
      dataStatisticsReportPropsData: {}
    },
    data() {
      return {
        logUrl:'https://labcontrol.nwafu.edu.cn/statics/2024/07/22/d1a9d129-ced7-49ac-b258-e5167d85232d.png',
        newData: {
          userName:'',
          account:'',
          deptName:'',
          grade:'',
          userTypeName:'',
          totalStudyHours:'',
          studyHoursList:[],
          examPassRecords:[],
          issuingUnit:'',
          issuingTime:'',
        },
        text:'该同学在校期间认真完成实验室安全教育各项学习任务，累计完成12学时安全培训，通过全部年度安全考核，具备良好的实验室安全意识和规范操作能力，特此证明。',
        downloading: false,
        showType:false,
      }
    },
    mounted() {
      this.initialize()
    },
    methods: {
      initialize() {
        this.$set(this, 'newData', this.dataStatisticsReportPropsData);
        this.$set(this, 'showType', true);
      },
      async downloadPdf() {
        if (this.downloading) return
        this.downloading = true
        try {
          const el = this.$refs.reportWrap
          const canvas = await html2canvas(el, {
            scale: 2,
            useCORS: true,
            backgroundColor: '#ffffff',
            logging: false,
          })
          const imgW = canvas.width
          const imgH = canvas.height
          // 将 canvas 转为 JPEG base64（去掉 data:image/jpeg;base64, 前缀）
          const jpegB64 = canvas.toDataURL('image/jpeg', 0.92).split(',')[1]
          // atob 解码为二进制字节数组
          const jpegBytes = Uint8Array.from(atob(jpegB64), c => c.charCodeAt(0))
          // A4 点数 595×842，按比例缩放图片到页面宽度
          const pdfW = 595
          const pdfH = Math.round((imgH / imgW) * pdfW)
          // 构造最小合法 PDF（内嵌 JPEG，DCTDecode 不需要解码）
          const pdfBytes = this._buildPdf(jpegBytes, imgW, imgH, pdfW, pdfH)
          const blob = new Blob([pdfBytes], { type: 'application/pdf' })
          const url = URL.createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          a.download = `实验室安全教育成绩报告_${this.newData.userName || ''}.pdf`
          document.body.appendChild(a)
          a.click()
          URL.revokeObjectURL(url)
          document.body.removeChild(a)
        } catch (e) {
          console.error(e)
          this.$message && this.$message.error('下载失败，请重试')
        } finally {
          this.downloading = false
        }
      },
      // 构造内嵌单张 JPEG 图片的最小 PDF
      _buildPdf(jpegBytes, imgW, imgH, pageW, pageH) {
        const enc = s => new TextEncoder().encode(s)
        const concat = (...parts) => {
          const total = parts.reduce((n, p) => n + p.length, 0)
          const out = new Uint8Array(total)
          let off = 0
          for (const p of parts) { out.set(p, off); off += p.length }
          return out
        }
        const stream = `q ${pageW} 0 0 ${pageH} 0 0 cm /Im0 Do Q\n`
        const obj = (id, dict, data) => {
          const d = data ? concat(enc(dict + '\nstream\n'), data, enc('\nendstream\n')) : enc(dict + '\n')
          return { id, bytes: concat(enc(`${id} 0 obj\n`), d, enc('endobj\n')) }
        }
        const o1 = obj(1, '<< /Type /Catalog /Pages 2 0 R >>')
        const o2 = obj(2, '<< /Type /Pages /Kids [3 0 R] /Count 1 >>')
        const o3 = obj(3, `<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${pageW} ${pageH}] /Contents 4 0 R /Resources << /XObject << /Im0 5 0 R >> >> >>`)
        const streamEnc = enc(stream)
        const o4 = obj(4, `<< /Length ${streamEnc.length} >>`, streamEnc)
        const o5 = obj(5, `<< /Type /XObject /Subtype /Image /Width ${imgW} /Height ${imgH} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${jpegBytes.length} >>`, jpegBytes)
        const header = enc('%PDF-1.4\n')
        const objs = [o1, o2, o3, o4, o5]
        const offsets = []
        let pos = header.length
        const bodyParts = []
        for (const o of objs) {
          offsets.push(pos)
          pos += o.bytes.length
          bodyParts.push(o.bytes)
        }
        const xrefPos = pos
        const xref = enc(
          `xref\n0 6\n0000000000 65535 f \n` +
          offsets.map(o => `${String(o).padStart(10, '0')} 00000 n \n`).join('') +
          `trailer\n<< /Size 6 /Root 1 0 R >>\nstartxref\n${xrefPos}\n%%EOF\n`
        )
        return concat(header, ...bodyParts, xref)
      },
    }
  }
</script>

<style scoped lang="scss">
.dataStatisticsReport-addPage {
  background: #f5f7fa;
  flex:1;
  display: flex;
  flex-direction: column;
  overflow-y: scroll;

  .action-bar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 16px;

    .download-btn {
      display: flex;
      align-items: center;
      gap: 6px;
      i { font-size: 15px; }
    }
  }
  .report-wrap {
    /*position: relative;*/
    /*background: #fff;*/
    /*border-radius: 8px;*/
    /*box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);*/
    /*padding: 40px 50px;*/
    /*max-width: 900px;*/
    /*margin: 0 auto;*/
    /*overflow: hidden;*/
    flex:1;
    display: flex;
    flex-direction: column;
    width:720px;
    .report-wrap-big-box{
      width:680px;
      margin:20px;
      border: 1px solid #c9a84c;
      border-radius:4px;
      position: relative;
      flex:1;
      display: flex;
      flex-direction: column;
      background-color: #fffdf5;
      .report-wrap-min-box{
        flex:1;
        display: flex;
        flex-direction: column;
        border: 1px solid #c9a84c;
        border-radius:4px;
        margin:1px;
        height: 500px;
        //logo
        .logo-box{
          width:578px;
          height:88px;
          border-radius:6px;
          background-color: #1a6e3a;
          margin:40px 0 0 48px;
          overflow: hidden;
          img{
            width: 350px;
            margin: 6px auto;
            display: block;
          }
        }
        //标题
        .title-p{
          line-height:56px;
          color:#8b452f;
          text-align: center;
          font-size:20px;
          letter-spacing: 6px;
        }
        //用户信息
        .user-box{
          width:578px;
          height:99px;
          background-color: #faf6ec;
          border:1px solid #e8dcc8;
          margin:9px 0 0 48px;
          border-radius:4px;
          padding:10px 20px;
          .user-min-box{
            display: flex;
            div{
              flex:1;
              display: flex;
              p{
                line-height:26px;
                font-size:14px;
                color:#4a3c2a;
              }
              p:nth-child(1){
                font-weight:700;
              }
              p:nth-child(2){

              }
            }
          }
        }
        //列表
        .study-hours-max-big-box{
          margin:20px 48px 0 48px;
          .study-hours-title-box{
            display: flex;
            p:nth-child(1){
              height:20px;
              width:3px;
              background-color: #c9a84c;
            }
            p:nth-child(2){
              line-height:20px;
              font-size:12px;
              flex:1;
              color:#8b4513;
              margin-left:8px;
              font-weight:700;
            }
          }
          .study-hours-text-title-box{
            display: flex;
            background-color: #f5edd8;
            border-bottom:1px solid #d4c5a0;
            margin-top:10px;
            p{
              line-height:34px;
              font-size:12px;
              color: #5a4320;
              flex:1;
              text-align: center;
              font-weight:700;
            }
          }
          .study-hours-for-box{
            display: flex;
            border-bottom:1px solid #ebe3d0;
            p{
              line-height:32px;
              font-size:12px;
              color: #4a3c2a;
              flex:1;
              text-align: center;
            }
          }
          .study-hours-bottom-box{
            display: flex;
            background-color: #faf6ec;
            border-bottom:1px solid #ebe3d0;
            p{
              line-height:32px;
              font-size:12px;
              color: #4a3c2a;
              font-weight: 700;
              text-align: center;
            }
            p:nth-child(1){
              width:216px;
            }
            p:nth-child(2){
              flex:1;
            }
          }
        }
        .study-hours-max-big-box-2{
          margin:20px 48px 0 48px;
          .study-hours-title-box{
            display: flex;
            p:nth-child(1){
              height:20px;
              width:3px;
              background-color: #c9a84c;
            }
            p:nth-child(2){
              line-height:20px;
              font-size:12px;
              flex:1;
              color:#8b4513;
              margin-left:8px;
              font-weight:700;
            }
          }
          .study-hours-text-title-box{
            display: flex;
            background-color: #f5edd8;
            border-bottom:1px solid #d4c5a0;
            margin-top:10px;
            p{
              line-height:34px;
              font-size:12px;
              color: #5a4320;
              flex:1;
              text-align: center;
              font-weight:700;
            }
            p:nth-child(1){
              width:216px;
            }
            p:nth-child(2){
              width:182px;
            }
            p:nth-child(3){
              width:180px;
            }
          }
          .study-hours-for-box{
            display: flex;
            border-bottom:1px solid #ebe3d0;
            p{
              line-height:32px;
              font-size:12px;
              color: #4a3c2a;
            }
            p:nth-child(1){
              width:126px;
              text-align: right;
            }
            p:nth-child(2){
              flex: 1;
              text-align: center;
            }
            p:nth-child(3){
              width:60px;
              margin-right:66px;
              text-align: center;
            }
          }
        }
        //描述信息
        .study-text-p{
          margin:25px 48px 0 48px;
          line-height:24px;
          font-size:14px;
          color:#4a3c2a;
          text-indent: 28px;
          span{
            font-weight:700;
          }
        }
        //落款
        .signature-box{
          /*margin:63px 180px 40px 48px;*/
          margin:103px 180px 80px 48px;
          p{
            height:24px;
            text-align: right;
            font-size: 14px;
            color:#4a3c2a;
            line-height:24px;
          }
        }
        // 水印
        .watermark-box {
          position: absolute;
          top: 0; left: 0; right: 0; bottom: 0;
          pointer-events: none;
          display: flex;
          flex-wrap: wrap;
          align-content: flex-start;
          padding: 60px 20px;
          gap: 40px 60px;
          z-index: 0;
          opacity: 0.04;
          .watermark-text {
            font-size: 18px;
            color: #0183fa;
            transform: rotate(-30deg);
            white-space: nowrap;
            display: inline-block;
            user-select: none;
          }
        }
      }
    }
  }
}
</style>
