Quellcode durchsuchen

Merge branch 'dev' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend-portal into dengfei

695593266@qq.com vor 4 Monaten
Ursprung
Commit
08953db0f9

BIN
src/assets/bg-login.png


+ 23 - 0
src/components/jimureport/api.js

@@ -0,0 +1,23 @@
+import request from '@/utils/request';
+
+export async function getServiceurl () {
+  const res = await request.get('sys/jimureport/getServiceurl');
+  if (res.data.code == 0 && res.data.data) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getPrintMap () {
+  const res = await request.get('sys/jimureport/getPrintMap');
+  if (res.data.code == 0 && res.data.data) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getJmPrintViewUrl (code) {
+  const res = await request.get('sys/jimureport/getJmPrintViewUrl/'+code);
+  if (res.data.code == 0 && res.data.data) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 23 - 0
src/components/jimureport/browse.vue

@@ -0,0 +1,23 @@
+<template>
+  <iframe
+    :src="url"
+    width="100%"
+    style="height: calc(100vh - 100px)"
+    frameborder="0"
+    allowfullscreen="true"
+  ></iframe>
+</template>
+
+<script>
+  export default {
+    props: {
+      url: ''
+    },
+    data() {
+      return {};
+    },
+
+    methods: {}
+  };
+</script>
+<style scoped lang="scss"></style>

+ 52 - 0
src/components/jimureport/browseModal.vue

@@ -0,0 +1,52 @@
+<template>
+  <div>
+    <ele-modal
+      :visible.sync="showEditFlag"
+      :close-on-click-modal="false"
+      custom-class="ele-dialog-form"
+      append-to-body
+      :fullscreen="true"
+    >
+      <browse :url="fileUrl"></browse
+    ></ele-modal>
+    <el-link type="primary" @click="open">{{ text }}</el-link>
+  </div>
+</template>
+
+<script>
+  import { getToken } from '@/utils/token-util';
+  import { getJmPrintViewUrl } from './api.js';
+  import browse from './browse.vue';
+
+  export default {
+    components: {
+      browse
+    },
+    props: {
+      text: {
+        default: '打印预览'
+      },
+      businessId: {
+        default: ''
+      },
+      businessCode: {
+        default: ''
+      }
+    },
+    data() {
+      return {
+        fileUrl: '',
+        showEditFlag: false
+      };
+    },
+
+    methods: {
+      async open() {
+        this.showEditFlag = true;
+        let url = await getJmPrintViewUrl(this.businessCode);
+        this.fileUrl = `${url}?token=${getToken()}&id=${this.businessId}`;
+      }
+    }
+  };
+</script>
+<style scoped lang="scss"></style>

+ 1 - 1
src/layout/components/header-tools.vue

@@ -190,7 +190,7 @@ export default {
     async showExpiryConfirm() {
       const confirmConfig = {
         title: '密码修改提醒',
-        message: '您的登录密码已长时间未做修改,请修改密码后重新登录!',
+        message: '您的登录密码为弱密码或已长时间未做修改,请修改密码后重新登录!',
         confirmButtonText: '确认修改',
         cancelButtonText: '取消',
         type: 'warning',

+ 9 - 2
src/micro-app.js

@@ -9,6 +9,7 @@ const microApps = [
   },
   {
     name: 'page-main-data',
+    // entry: 'http://localhost:8081/main-data/',
     entry: '/main-data/',
     activeRule: '/page-main-data'
   },
@@ -19,6 +20,7 @@ const microApps = [
   },
   {
     name: 'eam',
+    // entry: 'http://localhost:8083/eam/',
     entry: '/eam/',
     activeRule: '/page-eam'
   },
@@ -43,7 +45,6 @@ const microApps = [
   {
     name: 'eos',
     entry: '/eos/',
-    // entry: process.env.NODE_ENV == 'development'?'http://localhost:8081/eos/':'/eos/',
     activeRule: '/page-eos'
   },
 
@@ -61,6 +62,12 @@ const microApps = [
     name: 'fm',
     entry: '/fm/',
     activeRule: '/page-fm'
+  },
+  {
+    name: 'pcs',
+    // entry: 'http://localhost:8080/pcs/',
+    entry: '/pcs/',
+    activeRule: '/page-pcs'
   }
 ];
 
@@ -70,7 +77,7 @@ const apps = microApps.map((item) => {
     container: '#micro-container', // 子应用挂载的div
     props: {
       routerBase: item.activeRule, // 下发基础路由
-      parentWindow: window, 
+      parentWindow: window,
       fileMain, //文档上传组件 下发给子应用
       store
     }

+ 4 - 6
src/utils/page-tab-util.js

@@ -254,21 +254,19 @@ export function logout(route, from) {
     if (localStorage.getItem('singleUserInfo') == '1') {
       router.push({
         path: '/singleLogin',
-        query: from ? { from } : void 0
+        // query: from ? { from } : void 0
       });
     } else {
       router.push({
         path: '/login',
-        query: from ? { from } : void 0
+        // query: from ? { from } : void 0
       });
     }
   } else {
     if (localStorage.getItem('singleUserInfo') == '1') {
-      location.replace(
-        BASE_URL + 'singleLogin' + (from ? '?from=' + from : '')
-      );
+      location.replace(window.location.origin + '/singleLogin');
     } else {
-      location.replace(BASE_URL + 'login' + (from ? '?from=' + from : ''));
+      location.replace(window.location.origin + '/login');
     }
   }
 

+ 139 - 50
src/views/login/index.vue

@@ -5,12 +5,21 @@
       ['', 'login-form-right', 'login-form-left'][direction]
     ]"
   >
+    <!-- 左侧标题区域 -->
+    <div class="login-header">
+      <h1 class="login-title">
+        工业互联网<span class="highlight">平台</span>
+      </h1>
+      <p class="login-subtitle">让工业更智能,让生产更可信,让运营更高效</p>
+    </div>
+
+    <!-- 登录表单 -->
     <el-form
       ref="form"
       size="large"
       :model="form"
       :rules="rules"
-      class="login-form ele-bg-white"
+      class="login-form"
       @keyup.enter.native="submit"
     >
       <el-popover width="150" trigger="hover">
@@ -21,13 +30,14 @@
         <div slot="reference" class="switch-btn"></div>
       </el-popover>
 
-      <h4>{{ $t('login.title') }}</h4>
+      <h4 class="form-title">欢迎登录</h4>
       <el-form-item prop="loginName">
         <el-input
           clearable
           v-model="form.loginName"
           prefix-icon="el-icon-user"
           placeholder="请输入登录账号"
+          class="login-input"
         />
       </el-form-item>
       <el-form-item prop="loginPwd">
@@ -36,6 +46,7 @@
           v-model="form.loginPwd"
           prefix-icon="el-icon-lock"
           placeholder="请输入登录密码"
+          class="login-input"
         />
       </el-form-item>
       <el-form-item prop="captcha">
@@ -44,7 +55,8 @@
             clearable
             v-model="form.captcha"
             prefix-icon="el-icon-_vercode"
-            :placeholder="$t('login.code')"
+            placeholder="请输入验证码"
+            class="login-input"
           />
           <img
             alt=""
@@ -54,19 +66,6 @@
           />
         </div>
       </el-form-item>
-      <!-- <div class="el-form-item">
-        <el-checkbox v-model="form.remember">
-          {{ $t('login.remember') }}
-        </el-checkbox>
-        <el-link
-          type="primary"
-          :underline="false"
-          class="ele-pull-right"
-          @click="$router.push('/forget')"
-        >
-          忘记密码
-        </el-link>
-      </div> -->
       <div class="el-form-item">
         <el-button
           size="large"
@@ -75,30 +74,22 @@
           :loading="loading"
           @click="submit"
         >
-          {{ loading ? $t('login.loading') : $t('login.login') }}
+          {{ loading ? $t('login.loading') : '登 录' }}
         </el-button>
       </div>
-      <div class="ele-text-center" style="margin-bottom: 10px">
-        <!-- <i class="login-oauth-icon el-icon-_qq" style="background: #3492ed"></i>
-        <i
-          class="login-oauth-icon el-icon-_wechat"
-          style="background: #4daf29"
-        ></i>
-        <i
-          class="login-oauth-icon el-icon-_weibo"
-          style="background: #cf1900"
-        ></i> -->
-      </div>
     </el-form>
+
     <div class="login-copyright">
       <!-- copyright © 2022 eleadmin.com all rights reserved. -->
     </div>
+
     <!-- 多语言切换 -->
     <div style="position: absolute; right: 30px; top: 20px">
       <i18n-icon
         :icon-style="{ fontSize: '22px', color: '#fff', cursor: 'pointer' }"
       />
     </div>
+
     <!-- 实际项目去掉这段 -->
     <div
       class="hidden-xs-only"
@@ -277,7 +268,7 @@
       /* 跳转到首页 */
       goHome() {
         localStorage.setItem('singleUserInfo', '0');
-        this.$router.push(this.$route?.query?.from ?? '/').catch(() => {});
+        this.$router.push('/').catch(() => {});
       },
       /* 更换图形验证码 */
       changeCaptcha() {
@@ -338,14 +329,19 @@
     padding: 50px 20px;
     position: relative;
     box-sizing: border-box;
-    background-image: url('@/assets/bg-login.jpg');
+    background-image: url('@/assets/bg-login.png');
     background-repeat: no-repeat;
     background-size: cover;
+    background-position: center bottom;
     min-height: 100vh;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: flex-start;
 
     &:before {
       content: '';
-      background-color: rgba(0, 0, 0, 0.2);
+      background: linear-gradient(180deg, rgba(135, 180, 255, 0.3) 0%, rgba(200, 220, 255, 0.1) 50%, rgba(255, 255, 255, 0) 100%);
       position: absolute;
       top: 0;
       left: 0;
@@ -354,25 +350,82 @@
     }
   }
 
+  /* 头部标题区域 */
+  .login-header {
+    position: relative;
+    z-index: 2;
+    text-align: center;
+    margin-top: 8vh;
+    margin-bottom: 30px;
+  }
+
+  .login-title {
+    font-size: 42px;
+    font-weight: 600;
+    color: #1a3a5c;
+    margin: 0 0 12px 0;
+    letter-spacing: 4px;
+
+    .highlight {
+      color: #409eff;
+      font-weight: 700;
+    }
+  }
+
+  .login-subtitle {
+    font-size: 16px;
+    color: #4a6a8a;
+    margin: 0;
+    letter-spacing: 2px;
+  }
+
   /* 卡片 */
   .login-form {
     margin: 0 auto;
-    width: 360px;
+    width: 400px;
     max-width: 100%;
-    padding: 25px 30px;
+    padding: 35px 40px;
     position: relative;
-    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15);
+    background: rgba(255, 255, 255, 0.95);
+    box-shadow: 0 8px 32px rgba(31, 100, 200, 0.15);
     box-sizing: border-box;
-    border-radius: 4px;
+    border-radius: 12px;
     z-index: 2;
+    backdrop-filter: blur(10px);
 
-    h4 {
+    .form-title {
       text-align: center;
-      margin: 0 0 25px 0;
+      margin: 0 0 30px 0;
+      font-size: 20px;
+      font-weight: 500;
+      color: #303133;
     }
 
     & > .el-form-item {
-      margin-bottom: 25px;
+      margin-bottom: 22px;
+    }
+  }
+
+  /* 输入框样式 */
+  .login-input {
+    :deep(.el-input__inner) {
+      border-radius: 6px;
+      height: 44px;
+      line-height: 44px;
+      padding-left: 40px;
+      border: 1px solid #dcdfe6;
+      transition: all 0.3s;
+
+      &:focus {
+        border-color: #409eff;
+        box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+      }
+    }
+
+    :deep(.el-input__prefix) {
+      left: 12px;
+      color: #909399;
+      font-size: 16px;
     }
   }
 
@@ -395,22 +448,43 @@
   }
 
   .login-captcha {
-    height: 38px;
-    width: 102px;
-    margin-left: 10px;
-    border-radius: 4px;
+    height: 44px;
+    width: 110px;
+    margin-left: 12px;
+    border-radius: 6px;
     border: 1px solid #dcdfe6;
     text-align: center;
     cursor: pointer;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
 
     &:hover {
-      opacity: 0.75;
+      opacity: 0.85;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
     }
   }
 
   .login-btn {
     display: block;
     width: 100%;
+    height: 46px;
+    font-size: 16px;
+    font-weight: 500;
+    border-radius: 6px;
+    margin-top: 8px;
+    background: linear-gradient(135deg, #409eff 0%, #2c8cf0 100%);
+    border: none;
+    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.35);
+    transition: all 0.3s;
+
+    &:hover {
+      background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
+      box-shadow: 0 6px 16px rgba(64, 158, 255, 0.45);
+      transform: translateY(-1px);
+    }
+
+    &:active {
+      transform: translateY(0);
+    }
   }
 
   /* 第三方登录图标 */
@@ -435,11 +509,7 @@
   /* 响应式 */
   @media screen and (min-height: 550px) {
     .login-form {
-      position: absolute;
-      top: 50%;
-      left: 50%;
-      transform: translateX(-50%);
-      margin-top: -220px;
+      margin-top: 0;
     }
 
     .login-form-right .login-form,
@@ -447,12 +517,13 @@
       left: auto;
       right: 15%;
       transform: translateX(0);
-      margin: -220px auto auto auto;
+      margin: 0 15% 0 auto;
     }
 
     .login-form-left .login-form {
       right: auto;
       left: 15%;
+      margin: 0 auto 0 15%;
     }
 
     .login-copyright {
@@ -464,12 +535,30 @@
   }
 
   @media screen and (max-width: 768px) {
+    .login-header {
+      margin-top: 5vh;
+    }
+
+    .login-title {
+      font-size: 28px;
+    }
+
+    .login-subtitle {
+      font-size: 14px;
+    }
+
+    .login-form {
+      width: 100%;
+      max-width: 360px;
+      padding: 25px 25px;
+    }
+
     .login-form-right .login-form,
     .login-form-left .login-form {
       left: 50%;
       right: auto;
       transform: translateX(-50%);
-      margin-right: auto;
+      margin: 0 auto;
     }
   }
 </style>

+ 1 - 1
src/views/traceability/traceabilityCode/company.vue

@@ -69,7 +69,7 @@
           </div>
           <div class="info-item">
             <span class="info-label">营业执照:</span>
-            <img style="width: 200px;" v-if="companyInfo.businessLicenseFile[0].url" :src="companyInfo.businessLicenseFile[0].url" alt="">
+            <img style="width: 200px;" v-if="companyInfo.businessLicenseFile?.length && companyInfo.businessLicenseFile[0].url" :src="companyInfo.businessLicenseFile[0].url" alt="">
           </div>
         </div>
         <!-- 查看更多信息按钮 -->

+ 14 - 8
src/views/traceability/traceabilityCode/index.vue

@@ -35,6 +35,8 @@
                 <span class="info-value">{{ detail.productName }}</span>
               </div>
             </div>
+          </div>
+          <div class="info-row">
             <div class="info-col">
               <div class="info-item">
                 <span class="info-label">产地:</span>
@@ -49,6 +51,8 @@
                 <span class="info-value">{{ detail.productCode }}</span>
               </div>
             </div>
+          </div>
+          <div class="info-row">
             <div class="info-col">
               <div class="info-item">
                 <span class="info-label">批号:</span>
@@ -64,6 +68,8 @@
                   <span class="info-value">{{ detail.specification }}</span>
                 </div>
               </div>
+            </div>
+            <div class="info-row">
               <div class="info-col">
                 <div class="info-item">
                   <span class="info-label">内控等级:</span>
@@ -87,38 +93,38 @@
                 </div>
               </div>
             </div>
-            <div class="info-row">
+            <!-- <div class="info-row">
               <div class="info-col">
                 <div class="info-item">
                   <span class="info-label">性味与归经:</span>
                   <span class="info-value"></span>
                 </div>
               </div>
-            </div>
-            <div class="info-row">
+            </div> -->
+            <!-- <div class="info-row">
               <div class="info-col">
                 <div class="info-item">
                   <span class="info-label">功能与主治:</span>
                   <span class="info-value"></span>
                 </div>
               </div>
-            </div>
-            <div class="info-row">
+            </div> -->
+            <!-- <div class="info-row">
               <div class="info-col">
                 <div class="info-item">
                   <span class="info-label">用法与用量:</span>
                   <span class="info-value"></span>
                 </div>
               </div>
-            </div>
-            <div class="info-row">
+            </div> -->
+            <!-- <div class="info-row">
               <div class="info-col">
                 <div class="info-item">
                   <span class="info-label">贮藏:</span>
                   <span class="info-value">{{ detail.layBy }}</span>
                 </div>
               </div>
-            </div>
+            </div> -->
           </div>
         </div>
         <!-- 查看更多信息按钮 -->

+ 11 - 3
src/views/traceability/traceabilityCode/purchase.vue

@@ -28,13 +28,17 @@
           采购详情
         </div>
         <div class="info-item">
-          <span class="info-label">原药批号:</span>
+          <span class="info-label">批号:</span>
           <span class="info-value">{{ purchaseInfo.sourceBatchNo }}</span>
         </div>
         <div class="info-item">
-          <span class="info-label">原药产地:</span>
+          <span class="info-label">产地:</span>
           <span class="info-value">{{ purchaseInfo.purchaseOrigins }}</span>
         </div>
+        <div class="info-item">
+          <span class="info-label">供应商名称:</span>
+          <span class="info-value">{{ purchaseInfo.supplierName }}</span>
+        </div>
         <div class="info-item">
           <span class="info-label">采收时间:</span>
           <span class="info-value"></span>
@@ -43,9 +47,13 @@
           <span class="info-label">采购人员:</span>
           <span class="info-value">{{ purchaseInfo.purchaseUserName }}</span>
         </div>
+        <div class="info-item">
+          <span class="info-label">采购数量:</span>
+          <span class="info-value">{{ purchaseInfo.purchaseQuantity }}{{ purchaseInfo.measuringUnit }}</span>
+        </div>
         <div class="info-item">
           <span class="info-label">采购重量:</span>
-          <span class="info-value">{{ purchaseInfo.purchaseWeight }}{{ detail.unit }}</span>
+          <span class="info-value">{{ purchaseInfo.purchaseWeight }}{{ purchaseInfo.weightUnit }}</span>
         </div>
         <div class="info-item">
           <span class="info-label">采购日期:</span>

+ 118 - 4
src/views/traceability/traceabilityCode/quality.vue

@@ -12,7 +12,7 @@
     <!-- 主内容区 -->
     <div class="content-wrapper">
       <!-- 编辑中标签 -->
-      <div class="edit-tag">编辑中</div>
+      <!-- <div class="edit-tag">编辑中</div> -->
       
       <!-- 产品图片区域 -->
       <div class="product-image-section">
@@ -31,13 +31,84 @@
           质检详情
         </div>
         <div class="info-item">
-          <span class="info-label">检测依据:</span>
-          <span class="info-value"></span>
+          <span class="info-label">编号:</span>
+          <span class="info-value">{{ qualityInfo.code || '-' }}</span>
         </div>
+        <div class="info-item">
+          <span class="info-label">报告单号:</span>
+          <span class="info-value">{{ qualityInfo.reportNumber || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">检品名称:</span>
+          <span class="info-value">{{ qualityInfo.productName || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">批号/序列号:</span>
+          <span class="info-value">{{ qualityInfo.batchNo || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">规格型号:</span>
+          <span class="info-value">{{ qualityInfo.specification || '-' }}/{{ qualityInfo.modelType || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">数量:</span>
+          <span class="info-value">{{ qualityInfo.total || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">请验日期:</span>
+          <span class="info-value">{{ qualityInfo.pleaseVerifyDate || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">请验部门:</span>
+          <span class="info-value">{{ qualityInfo.pleaseVerifyDepartment || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">报告日期:</span>
+          <span class="info-value">{{ qualityInfo.reportDate || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">有效期:</span>
+          <span class="info-value">{{ qualityInfo.expirationDate || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">检验依据:</span>
+          <span class="info-value">{{ qualityInfo.inspectionBasis || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">检验员:</span>
+          <span class="info-value">{{ qualityInfo.inspector || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">检验日期:</span>
+          <span class="info-value">{{ qualityInfo.inspectionTime || '-' }}</span>
+        </div>
+        <!-- <div class="info-item">
+          <span class="info-label">复核人:</span>
+          <span class="info-value">{{ qualityInfo.reviewer || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">复核日期:</span>
+          <span class="info-value">{{ qualityInfo.reviewTime || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">审核人:</span>
+          <span class="info-value">{{ qualityInfo.checker || '-' }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">审核日期:</span>
+          <span class="info-value">{{ qualityInfo.approvedDate || '-' }}</span>
+        </div> -->
         <div class="images-section">
           <span class="section-subtitle">报告单:</span>
           <div class="images-grid">
             <!-- <img class="detail-image" :src="detailImageSrc" alt="质检报告单"> -->
+             <div v-if="template">
+                <div v-html="template"> </div>
+              </div>
+              <!-- <browse v-else :url="fileUrl"></browse> -->
+               <div v-else class="report-template-container">
+                 <reportTemplate :templateInfo="this.qualityInfo"></reportTemplate>
+               </div>
           </div>
         </div>
       </div>
@@ -53,8 +124,16 @@
 </template>
 
 <script>
+// import browse from '@/components/jimureport/browse.vue';
+// import { getJmPrintViewUrl } from '@/components/jimureport//api.js';
+// import { getToken } from '@/utils/token-util';
+import reportTemplate from '@/views/traceability/traceabilityCode/reportTemplate.vue';
 export default {
   name: 'QualityTraceabilityPage',
+  components: {
+    // browse,
+    reportTemplate,
+  },
   data() {
     return {
       // 使用项目中已有的图标路径
@@ -62,9 +141,12 @@ export default {
       detailImageSrc: require('@/assets/traceability/1.svg'),
       detail: {},
       purchaseInfo: {},
+      qualityInfo: {},
+      fileUrl: '',
+      template: '',
     };
   },
-  mounted() {
+  async mounted() {
     console.log('路由参数:');
     console.log('路由参数:', this.$route.query);
     // 从路由参数中获取detail对象
@@ -74,10 +156,19 @@ export default {
         this.detail = JSON.parse(this.$route.query.detail);
         console.log('获取到的detail参数:', this.detail);
         this.purchaseInfo = this.detail.purchaseInfo || {};
+        this.qualityInfo = this.detail.qualityInfo || {};
+        if (this.qualityInfo.reportTemplateJson?.template) {
+          this.template = this.qualityInfo.reportTemplateJson.template;
+        } else {
+          // let url = await getJmPrintViewUrl('qmsqualityinspectionprint');
+          // this.fileUrl = `${url}?token=${getToken()}&id=${this.qualityInfo.id}`;
+          // console.log('fileUrl~~~', this.fileUrl);
+        }
       } catch (error) {
         console.error('解析detail参数失败:', error);
         this.detail = {};
         this.purchaseInfo = {};
+        this.qualityInfo = {};
       }
     }
   },
@@ -272,6 +363,29 @@ export default {
   object-fit: cover;
 }
 
+.report-template-container {
+  overflow-x: auto;
+  white-space: nowrap;
+}
+
+.report-template-container::-webkit-scrollbar {
+  height: 8px;
+}
+
+.report-template-container::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 4px;
+}
+
+.report-template-container::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 4px;
+}
+
+.report-template-container::-webkit-scrollbar-thumb:hover {
+  background: #a8a8a8;
+}
+
 .home-button {
   position: fixed;
   bottom: 30px;

+ 182 - 0
src/views/traceability/traceabilityCode/reportTemplate.vue

@@ -0,0 +1,182 @@
+<template>
+  <div class="report-container">
+    <div class="report-header">
+      <!-- <div class="company-logo">
+        <img src="@/assets/logo.png" alt="嘉实医药" />
+      </div> -->
+      <div class="report-title">检验报告书</div>
+    </div>
+    
+    <div class="report-info">
+      <div class="info-item">
+        <span class="label">编号:</span>
+        <span class="value">{{ templateInfo.code }}</span>
+      </div>
+      <div class="info-item">
+        <span class="label">报告单号:</span>
+        <span class="value">{{ templateInfo.reportNumber }}</span>
+      </div>
+    </div>
+    
+    <table class="report-table">
+      <tbody>
+        <tr>
+          <td class="td-label">检品名称</td>
+          <td class="td-value" colspan="2">{{ templateInfo.productName }}</td>
+          <td class="td-label">批号/序列号</td>
+          <td class="td-value" colspan="2">{{ templateInfo.batchNo }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">规格型号</td>
+          <td class="td-value" colspan="2">{{ templateInfo.specification }}/{{ templateInfo.modelType }}</td>
+          <td class="td-label">数量</td>
+          <td class="td-value" colspan="2">{{ templateInfo.total }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">请验日期</td>
+          <td class="td-value" colspan="2">{{ templateInfo.pleaseVerifyDate }}</td>
+          <td class="td-label">请验部门</td>
+          <td class="td-value" colspan="2">{{ templateInfo.pleaseVerifyDepartment }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">报告日期</td>
+          <td class="td-value" colspan="2">{{ templateInfo.reportDate }}</td>
+          <td class="td-label">有效期</td>
+          <td class="td-value" colspan="2">{{ templateInfo.expirationDate }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">来源</td>
+          <td class="td-value" colspan="2">{{ templateInfo.source }}</td>
+          <td class="td-label">储存条件</td>
+          <td class="td-value" colspan="2">{{ templateInfo.storageCondition }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">检验依据</td>
+          <td class="td-value" colspan="5">{{ templateInfo.inspectionBasis }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">检验项目</td>
+          <td class="td-value" colspan="3">标准规定</td>
+          <td class="td-value" colspan="2">检验结果</td>
+        </tr>
+        <tr v-for="(item, index) in templateInfo.list" :key="index">
+          <td class="td-value">{{ item.item }}</td>
+          <td class="td-value" colspan="3">{{ item.standardRegulations }}</td>
+          <td class="td-value" colspan="2">{{ item.results }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">结论</td>
+          <td class="td-value" colspan="5">{{ templateInfo.conclusion }}</td>
+        </tr>
+        <tr>
+          <td class="td-label">备注</td>
+          <td class="td-value" colspan="5">{{ templateInfo.remarks }}</td>
+        </tr>
+      </tbody>
+    </table>
+    
+    <div class="report-footer">
+      <div class="footer-item">检验员:{{ templateInfo.inspector }} /日期:{{ templateInfo.inspectionTime }}</div>
+      <div class="footer-item">复核人:{{ templateInfo.reviewer }} /日期:{{ templateInfo.reviewTime }}</div>
+      <div class="footer-item">审核人:{{ templateInfo.checker }} /日期:{{ templateInfo.approvedDate }}</div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ReportTemplate',
+  props: {
+    templateInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  }
+}
+</script>
+
+<style scoped>
+.report-container {
+  /* width: 500px; */
+  max-width: 800px;
+  margin: 0 auto;
+  /* padding: 20px; */
+  /* border: 1px solid #000; */
+  /* font-family: Arial, sans-serif; */
+}
+
+.report-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+
+.company-logo {
+  width: 80px;
+  height: 80px;
+}
+
+.company-logo img {
+  width: 100%;
+  height: 100%;
+}
+
+.report-title {
+  font-size: 20px;
+  font-weight: bold;
+  text-align: center;
+  flex: 1;
+  margin-left: -80px;
+}
+
+.report-info {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 20px;
+}
+
+.info-item {
+  display: flex;
+  margin-right: 20px;
+  align-items: center;
+}
+
+.info-item .label {
+  font-weight: bold;
+  margin-right: 10px;
+}
+
+.report-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+}
+
+.report-table td {
+  border: 1px solid #000;
+  padding: 8px;
+}
+
+.td-label {
+  font-weight: bold;
+  background-color: #f5f5f5;
+  width: 90px;
+}
+
+.td-value {
+  width: 100%;
+}
+
+.report-footer {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 20px;
+}
+
+.footer-item {
+  flex: 1;
+  text-align: center;
+  margin-right: 20px;
+}
+</style>