Forráskód Böngészése

质检报告修改

yusheng 3 hónapja
szülő
commit
e9799ee350

+ 77 - 0
src/api/experimentList/index.js

@@ -0,0 +1,77 @@
+import request from '@/utils/request';
+
+// 列表
+
+export async function getList(params) {
+  const res = await request.get(`/qms/experiment/page`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//收样
+
+export async function sampleCollection(data) {
+  const res = await request.put(`/qms/taskmonad/sampleCollection`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 派单
+export async function qualityInspectionItemDispatching(data) {
+  const res = await request.post(
+    `/qms/quality_work_order/qualityInspectionItemDispatching`,
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//请托
+export async function qualityInspectionItemRequest(data) {
+  const res = await request.post(
+    `/qms/quality_work_order/qualityInspectionItemRequest`,
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//任务报工
+export async function exeTaskReportWork(data) {
+  const res = await request.post(`/qms/taskmonad/exeReportWork`, data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//请托报工
+export async function exeEntrustReportWork(data) {
+  const res = await request.post(`/qms/requestentrust/exeReportWork`, data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取详情
+export async function getById(id) {
+  const res = await request.get(`/qms/taskmonad/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 检查是否责任人
+export async function verificationQualityInspector(id) {
+  const res = await request.post(
+    `/qms/taskmonad/verificationQualityInspector/${id}`
+  );
+  return res.data.code;
+}

+ 3 - 0
src/components/addDoc/util.js

@@ -64,6 +64,9 @@ export function setFileUrl(row) {
     fileNames[fileNames.length - 1];
   return '/kkfile/onlinePreview?url=' + btoa(url);
 }
+export function getFileUrl(url) {
+  return window.location.origin + '/api/main/file/getFile?objectName=' + url;
+}
 export function setFolderList(data) {
   //递归过滤文件夹权限
   data.forEach((item) => {

+ 55 - 0
src/components/reportTemplateWrapper/reportTemplateWrapper.vue

@@ -0,0 +1,55 @@
+<template>
+  <component
+    :is="componentName"
+    v-if="componentName"
+    :key="componentName"
+    :isView="isView"
+    :visible.sync="proxyVisible"
+    :row="row"
+    :item="item"
+    @reload="$emit('reload')"
+    :type="type"
+  ></component>
+</template>
+
+<script>
+  export default {
+    name: 'ReportTemplateWrapper',
+    props: {
+      componentName: {
+        type: String,
+        default: null
+      },
+      isView: {
+        type: Boolean,
+        default: false
+      },
+      visible: {
+        type: Boolean,
+        default: false
+      },
+      row: {
+        type: Object,
+        default: () => ({})
+      },
+      item: {
+        type: Object,
+        default: () => ({})
+      },
+      type: {
+        type: String,
+        default: '0'
+      }
+    },
+    computed: {
+      proxyVisible: {
+        get() {
+          return this.visible;
+        },
+        set(val) {
+          this.$emit('update:visible', val);
+        }
+      }
+    }
+  };
+</script>

+ 266 - 0
src/views/experimentList/index.vue

@@ -0,0 +1,266 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never">
+      <!-- 搜索表单 -->
+      <seekPage
+        :seekList="seekList"
+        :formLength="3"
+        @search="reload"
+      ></seekPage>
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        row-key="code"
+        :page-size="20"
+        full-height="calc(100vh - 140px)"
+        height="calc(100vh - 310px)"
+        @columns-change="handleColumnChange"
+        :cache-key="cacheKeyUrl"
+      >
+        <template v-slot:code="{ row }">
+          <el-link type="primary" :underline="false" @click="openEdit(row)">{{
+            row.code
+          }}</el-link>
+        </template>
+        <template v-slot:imgUrl="{ row }">
+          <div style="display: flex">
+            <el-image
+              v-for="url in row.imgUrl"
+              style="width: 50px; height: 50px"
+              :src="getFileUrl(url.storePath)"
+              :preview-src-list="
+                row.imgUrl.map((item) => getFileUrl(item.storePath))
+              "
+            >
+            </el-image>
+          </div>
+        </template>
+      </ele-pro-table>
+    </el-card>
+
+    <experimentReport ref="experimentReportRef"></experimentReport>
+  </div>
+</template>
+
+<script>
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import { getFileUrl } from '@/components/addDoc/util.js';
+  import { getList } from '@/api/experimentList';
+  import experimentReport from '@/views/inspectionWork/components/experimentReport.vue';
+  export default {
+    components: { experimentReport },
+    mixins: [tabMixins],
+    data() {
+      return {
+        getFileUrl,
+        cacheKeyUrl: 'qsm-c2e9664a-experimentList',
+        seekList: [
+          {
+            label: '实验编号:',
+            value: 'code',
+            type: 'input',
+            placeholder: '请输入'
+          },
+          {
+            label: '检测工单编码:',
+            value: 'qualityWorkOrderCode',
+            type: 'input',
+            placeholder: '请输入'
+          },
+
+          {
+            label: '批次号:',
+            value: 'batchNo',
+            type: 'input',
+            placeholder: '请输入'
+          },
+          {
+            label: '编号:',
+            value: 'productCode',
+            type: 'input',
+            placeholder: '请输入'
+          },
+
+          {
+            label: '实验结论:',
+            value: 'results',
+            type: 'select',
+            placeholder: '请选择',
+            planList: [
+              { label: '合格', value: 1 },
+              { label: '不合格', value: 2 }
+            ]
+          }
+        ],
+        // 表格列配置
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'code',
+            slot: 'code',
+            label: '实验编码',
+            showOverflowTooltip: true,
+            align: 'center',
+            minWidth: 130
+          },
+          {
+            prop: 'inspectionName',
+            label: '检测项',
+            showOverflowTooltip: true,
+            align: 'center',
+            minWidth: 130
+          },
+          {
+            prop: 'inspectionCode',
+            label: '检测项编码',
+            showOverflowTooltip: true,
+            align: 'center',
+            minWidth: 130
+          },
+          {
+            prop: 'workshopName',
+            label: '实验室',
+            showOverflowTooltip: true,
+            align: 'center',
+            minWidth: 150
+          },
+          {
+            prop: 'experimentalTime',
+            label: '实验时间',
+            showOverflowTooltip: true,
+            align: 'center',
+            minWidth: 150
+          },
+
+          {
+            prop: 'imgUrl',
+            slot: 'imgUrl',
+            label: '实验图片',
+            align: 'center',
+            minWidth: 110
+          },
+          {
+            prop: 'qualityWorkOrderCode',
+            minWidth: 110,
+            label: '检测工单编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'qualityWorkOrderName',
+            minWidth: 110,
+            label: '检测工单名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productCode',
+            minWidth: 110,
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productName',
+            minWidth: 110,
+            label: '名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'batchNo',
+            minWidth: 110,
+            label: '批次号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            minWidth: 110,
+            label: '规格',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'brandNo',
+            minWidth: 110,
+            label: '牌号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'produceTaskName',
+            minWidth: 110,
+            label: '工序名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'resultsDescription',
+            minWidth: 150,
+            label: '实验结果',
+            align: 'center',
+
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'results',
+            minWidth: 110,
+            label: '实验结论',
+            align: 'center',
+            formatter: (row) => {
+              return row.results == 1
+                ? '合格'
+                : row.results == 2
+                ? '不合格'
+                : '';
+            },
+            showOverflowTooltip: true
+          }
+          // {
+          //   prop: 'createUserName',
+          //   minWidth: 110,
+          //   label: '创建人',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // }
+        ]
+      };
+    },
+    created() {},
+    methods: {
+      /* 表格数据源 */
+      datasource({ page, where, limit }) {
+        return getList({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
+      },
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ page: 1, where: where });
+      },
+      /* 打开编辑弹窗 */
+      openEdit(row) {
+        this.$refs.experimentReportRef.open(
+          {
+            experimentId: row.id
+          },
+          'detail'
+        );
+      }
+    }
+  };
+</script>

+ 16 - 31
src/views/inspectionProjectRequest/components/inspectionProjectRequestList.vue

@@ -176,18 +176,11 @@
       ref="processSubmitDialogRef"
       @reload="reload"
     ></processSubmitDialog>
-    <component
-      :is="targetComponent"
+    <ReportTemplateWrapper
       ref="targetComponentRef"
-      v-if="targetComponent"
-      :key="targetComponent"
-      :isView="isView"
-      :visible.sync="targetVisible"
-      :row="currentRow"
-      :item="currentItem"
-      @reload="reload"
       :type="'2'"
-    ></component>
+      @reload="reload"
+    ></ReportTemplateWrapper>
     <sampleReport ref="sampleReportRef" @reload="reload"></sampleReport>
 
     <Transfer
@@ -220,12 +213,12 @@
   import search from './search.vue';
   import Transfer from './transfer.vue';
   import sampleReport from '@/views/inspectionWork/components/sampleReport.vue';
+  import ReportTemplateWrapper from '@/views/inspectionReport/components/reportTemplateWrapper.vue';
 
   import tabMixins from '@/mixins/tableColumnsMixin';
   import inspectionProjectTaskSend from '@/views/inspectionProjectTask/components/inspectionProjectTaskSend.vue';
   import inspectionProjectReport from '@/views/inspectionWork/components/inspectionProjectReport.vue';
-  import inspection_report1 from '@/views/inspectionReport/template/inspection_report1.vue';
-  import inspection_report2 from '@/views/inspectionReport/template/inspection_report2.vue';
+
   import {
     getList,
     sampleCollection,
@@ -251,8 +244,7 @@
       Transfer,
       bpmDetail,
       sampleReport,
-      inspection_report1,
-      inspection_report2
+      ReportTemplateWrapper
     },
     mixins: [dictMixins, tabMixins],
     props: {
@@ -600,7 +592,11 @@
         if (row.recordingMethod == 1) {
           this.$refs.inspectionProjectReportRef.open(
             {
-              workData: { ...res, measureUnit: res.sampleMeasureUnit,workSampleCount:res.sampleTotal },
+              workData: {
+                ...res,
+                measureUnit: res.sampleMeasureUnit,
+                workSampleCount: res.sampleTotal
+              },
               list: res.templateList
             },
             type,
@@ -630,26 +626,15 @@
           });
       },
       generateReportApproval(row, item) {
-        this.targetComponent = item.code;
-        this.isView = false;
-        this.currentRow = row;
-        this.currentItem = item;
-        this.$nextTick(() => {
-          this.targetVisible = true;
-          console.log('targetVisible~~~~', this.targetVisible);
-        });
+        row.reportTemplateCode = item.code;
+        this.$refs.targetComponentRef.open({ row, item }, false);
       },
       async openReport(row) {
         const data = await getById(row.id);
-        this.targetComponent = row.reportTemplateCode;
-        this.isView = true;
-        this.currentRow = row;
-        this.currentRow.reportApprovalTaskVos =
-          data.reportApprovalTaskVos || {};
-        this.$nextTick(() => {
-          this.targetVisible = true;
-        });
+        row.reportApprovalTaskVos = data.reportApprovalTaskVos || {};
+        this.$refs.targetComponentRef.open({ row, item: {} }, true);
       },
+
       isEmptyObject(obj = {}) {
         return Object.keys(obj).length === 0;
       },

+ 13 - 30
src/views/inspectionProjectTask/components/inspectionProjectTaskList.vue

@@ -101,18 +101,11 @@
       ref="inspectionProjectReportRef"
       @reload="reload"
     />
-    <component
-      :is="targetComponent"
+    <ReportTemplateWrapper
       ref="targetComponentRef"
-      v-if="targetComponent"
-      :key="targetComponent"
-      :isView="isView"
-      :visible.sync="targetVisible"
-      :row="currentRow"
-      :item="currentItem"
-      @reload="reload"
       :type="'1'"
-    ></component>
+      @reload="reload"
+    ></ReportTemplateWrapper>
     <sampleReport ref="sampleReportRef" @reload="reload"></sampleReport>
     <process-submit-dialog
       api-fun-name="qmsReportApprovalAPI"
@@ -130,6 +123,8 @@
   import inspectionProjectReport from '@/views/inspectionWork/components/inspectionProjectReport.vue';
   import sampleReport from '@/views/inspectionWork/components/sampleReport.vue';
   import tabMixins from '@/mixins/tableColumnsMixin';
+  import ReportTemplateWrapper from '@/views/inspectionReport/components/reportTemplateWrapper.vue';
+
   import {
     getList,
     sampleCollection,
@@ -151,6 +146,7 @@
       sampleReport,
       inspection_report2,
       inspection_report1,
+      ReportTemplateWrapper,
       processSubmitDialog
     },
     mixins: [dictMixins, tabMixins],
@@ -163,14 +159,11 @@
     },
     data() {
       return {
-        targetComponent: '',
         cacheKeyUrl: 'qsm-c2e9664a-inspectionProjectTask',
         reportTemplateList: [],
         targetVisible: false,
         processSubmitDialogFlag: false,
-        currentItem: '',
-        currentRow: '',
-        isView: false,
+
         // 表格列配置
         columns: [
           {
@@ -443,27 +436,17 @@
             console.error('获取报表模板列表失败:', err);
           });
       },
+
       generateReportApproval(row, item) {
-        this.targetComponent = item.code;
-        this.isView = false;
-        this.currentRow = row;
-        this.currentItem = item;
-        this.$nextTick(() => {
-          this.targetVisible = true;
-          console.log('targetVisible~~~~', this.targetVisible);
-        });
+        row.reportTemplateCode = item.code;
+        this.$refs.targetComponentRef.open({ row, item }, false);
       },
       async openReport(row) {
         const data = await getById(row.id);
-        this.targetComponent = row.reportTemplateCode;
-        this.isView = true;
-        this.currentRow = row;
-        this.currentRow.reportApprovalTaskVos =
-          data.data.reportApprovalTaskVos || {};
-        this.$nextTick(() => {
-          this.targetVisible = true;
-        });
+        row.reportApprovalTaskVos = data.data.reportApprovalTaskVos || {};
+        this.$refs.targetComponentRef.open({ row, item: {} }, true);
       },
+
       isEmptyObject(obj = {}) {
         return Object.keys(obj).length === 0;
       },

+ 491 - 0
src/views/inspectionReport/components/reportTemplateWrapper.vue

@@ -0,0 +1,491 @@
+<template>
+  <ele-modal
+    :visible="visible"
+    width="70%"
+    append-to-body
+    title="检测报告"
+    @close="cancel"
+    :maxable="true"
+  >
+    <div class="switch">
+      <div class="switch_left">
+        <ul>
+          <li
+            v-for="item in tabOptions"
+            :key="item.key"
+            :class="{ active: activeComp == item.key }"
+            @click="activeComp = item.key"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+    </div>
+    <component
+      :is="targetComponent"
+      ref="templateRef"
+      v-if="visible"
+      v-show="activeComp == 'main'"
+      :key="componentName"
+      :isView="isView"
+      :type="type"
+    ></component>
+
+    <template v-slot:footer>
+      <el-button v-if="isView" type="primary" @click="print">打印</el-button>
+      <el-button v-if="!isView" type="primary" @click="save">确认</el-button>
+      <el-button @click="cancel">关闭</el-button>
+    </template>
+
+    <unqualifiedProduct
+      ref="unqualifiedProductRef"
+      v-show="activeComp == 'unqualifiedList'"
+      @setQualifiedNumber="setQualifiedNumber"
+      :total="basicInfoData.total"
+      :isView="isView"
+    >
+    </unqualifiedProduct>
+    <div style="margin-top: 10px" v-if="activeComp != 'bpm' && !isView">
+      结论:
+      <el-select
+        v-model="basicInfoData.qualityResults"
+        placeholder="请选择"
+        style="width: 140px"
+        @change="selectResult"
+      >
+        <el-option label="整单合格" :value="1" />
+        <el-option label="整单不合格" :value="2" />
+        <el-option label="部分合格" :value="3" />
+        <el-option label="整单让步接收" :value="4" />
+      </el-select>
+
+      合格数:
+      <el-input
+        v-model="basicInfoData.qualifiedNumber"
+        placeholder="合格数"
+        style="width: 140px"
+        disabled
+      ></el-input>
+
+      不合格数:
+      <el-input
+        v-model="basicInfoData.noQualifiedNumber"
+        placeholder="不合格数"
+        disabled
+        style="width: 140px"
+      ></el-input>
+    </div>
+    <bpmDetail
+      v-if="activeComp === 'bpm' && processInstanceId"
+      :id="processInstanceId"
+    ></bpmDetail>
+  </ele-modal>
+</template>
+
+<script>
+  import inspection_report1 from '../template/inspection_report1.vue';
+  import inspection_report2 from '../template/inspection_report2.vue';
+  import {
+    queryInspectionReportData,
+    queryInspectionReportList,
+    generateReport
+  } from '@/api/inspectionReport';
+  import bpmDetail from '@/views/bpm/processInstance/detail.vue';
+  import unqualifiedProduct from '@/views/inspectionReport/components/unqualifiedProduct.vue';
+  import { getList } from '@/api/unacceptedProduct/index';
+  import { getCode } from '@/api/login';
+  const defForm = {
+    poList: [],
+    unqualifiedProductsCode: '',
+    sourceCode: '',
+    batchNo: '',
+    brandNum: '',
+    categoryCode: '',
+    categoryId: '',
+    categoryName: '',
+    specification: '',
+    modelType: '',
+    produceRoutingId: '',
+    produceRoutingName: '',
+    taskId: '',
+    taskName: '',
+    quantity: '',
+    measureQuantity: '',
+    measureUnit: '',
+    weight: '',
+    weightUnit: '',
+    qualityType: ''
+  };
+  export default {
+    name: 'ReportTemplateWrapper',
+    components: {
+      inspection_report1,
+      inspection_report2,
+      unqualifiedProduct,
+      bpmDetail
+    },
+
+    data() {
+      return {
+        unqualifiedProducts: {
+          ...defForm
+        },
+        isView: false,
+
+        visible: false,
+        loading: false,
+        currentRow: {}, // 存储当前行数据
+        templateItem: {}, // 存储当前模板项数据
+        // 基本信息数据
+        basicInfoData: {},
+        componentName: '',
+        // 检验项目
+        inspectionItems: [],
+        tabOptions: [],
+        activeComp: 'main',
+        processInstanceId: '',
+        reportApprovalTaskVos: []
+      };
+    },
+    props: {
+      type: {
+        type: String,
+        default: '0'
+      }
+    },
+    methods: {
+      /* 打开质检报告 */
+      async open({ row, item }, isView) {
+        // this.visible = true;
+        this.isView = isView;
+        this.componentName = row.reportTemplateCode;
+        this.currentRow = row;
+        this.templateItem = item?.id ? item : row;
+
+        this.processInstanceId = row.reportProcessInstanceId;
+        this.reportApprovalTaskVos = row.reportApprovalTaskVos;
+        this.tabOptions = [
+          { key: 'main', name: '业务详情' },
+          { key: 'unqualifiedList', name: '不合格品台账' }
+        ];
+
+        if (this.processInstanceId) {
+          this.tabOptions.push({ key: 'bpm', name: '流程详情' });
+        }
+
+        this.visible = true;
+        if (this.currentRow.reportTemplateJson?.basicInfoData) {
+          this.basicInfoData =
+            this.currentRow.reportTemplateJson.basicInfoData || {};
+          this.inspectionItems =
+            this.currentRow.reportTemplateJson.inspectionItems || [];
+
+          const reviewTime =
+            this.reportApprovalTaskVos?.[
+              this.reportApprovalTaskVos.length - 2
+            ]?.endTime?.split(' ')[0] || '';
+          const approvedDate =
+            this.reportApprovalTaskVos?.[
+              this.reportApprovalTaskVos.length - 3
+            ]?.endTime?.split(' ')[0] || '';
+          const reviewer =
+            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
+              ?.approvalUserName || '';
+          const checker =
+            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
+              ?.approvalUserName || '';
+
+          this.$set(
+            this.basicInfoData,
+            'inspectionTime',
+            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'reviewTime',
+            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'approvedDate',
+            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'reviewer',
+            this.basicInfoData.reviewer || reviewer || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'checker',
+            this.basicInfoData.checker || checker || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'qualityResults',
+            this.basicInfoData.qualityResults
+          );
+          this.$set(
+            this.basicInfoData,
+            'qualifiedNumber',
+            this.basicInfoData.qualifiedNumber
+          );
+          this.$set(
+            this.basicInfoData,
+            'noQualifiedNumber',
+            this.basicInfoData.noQualifiedNumber
+          );
+          this.$nextTick(() => {
+            this.$refs.templateRef.init(
+              this.basicInfoData,
+              this.inspectionItems
+            );
+          });
+          this.initUnqualifiedProduct();
+        } else {
+          await this.getBasicInfo();
+          await this.getInspectionItems();
+          this.$nextTick(() => {
+            this.$refs.templateRef.init(
+              this.basicInfoData,
+              this.inspectionItems
+            );
+          });
+        }
+      },
+
+      async initUnqualifiedProduct() {
+        const data = await getList({
+          sourceCode: this.currentRow.code
+        });
+        if (data.list[0]) {
+          this.unqualifiedProducts = data.list[0];
+        }
+
+        this.$nextTick(() => {
+          this.$refs.unqualifiedProductRef.init({
+            id: this.unqualifiedProducts?.id,
+            qualityType: this.basicInfoData.qualityType,
+            workOrderCode: this.currentRow.code,
+            qualityWorkerId: this.basicInfoData.qualityWorkerId,
+            workOrderId: this.currentRow.workOrderId,
+            qualityResults: this.basicInfoData.qualityResults
+          });
+        });
+      },
+
+      setQualifiedNumber(data) {
+        this.basicInfoData.qualifiedNumber = data.qualifiedNumber;
+        this.basicInfoData.noQualifiedNumber = data.noQualifiedNumber;
+        if (!data.noQualifiedNumber) {
+          if (data.isQualifiedNumber) {
+            this.basicInfoData.qualityResults = 1;
+          } else {
+            this.basicInfoData.qualityResults = 4;
+          }
+        }
+        if (data.noQualifiedNumber == this.basicInfoData.total) {
+          this.basicInfoData.qualityResults = 2;
+        }
+        if (data.qualifiedNumber && data.noQualifiedNumber) {
+          this.basicInfoData.qualityResults = 3;
+        }
+      },
+
+      selectResult() {
+        this.$refs.unqualifiedProductRef.selectResult(
+          this.basicInfoData.qualityResults
+        );
+      },
+      getBasicInfo() {
+        return queryInspectionReportData({
+          id: this.currentRow.id,
+          type: this.type || this.currentRow.type || 0
+        }).then((res) => {
+          this.basicInfoData = res;
+          this.basicInfoData.reportCode = res.reportCode || '';
+
+          const reviewTime =
+            this.reportApprovalTaskVos?.[
+              this.reportApprovalTaskVos.length - 2
+            ]?.endTime?.split(' ')[0] || '';
+          const approvedDate =
+            this.reportApprovalTaskVos?.[
+              this.reportApprovalTaskVos.length - 3
+            ]?.endTime?.split(' ')[0] || '';
+          const reviewer =
+            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
+              ?.approvalUserName || '';
+          const checker =
+            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
+              ?.approvalUserName || '';
+          this.$set(
+            this.basicInfoData,
+            'version',
+            this.templateItem.versionSymbol +
+              this.templateItem.bigVersion +
+              this.templateItem.versionMark +
+              this.templateItem.smallVersion
+          );
+          this.$set(
+            this.basicInfoData,
+            'inspectionTime',
+            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'reviewTime',
+            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'approvedDate',
+            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'reviewer',
+            this.basicInfoData.reviewer || reviewer || ''
+          );
+          this.$set(
+            this.basicInfoData,
+            'checker',
+            this.basicInfoData.checker || checker || ''
+          );
+
+          this.$set(
+            this.basicInfoData,
+            'qualityResults',
+            this.currentRow.noQualifiedNumber == this.basicInfoData.total
+              ? 2
+              : this.currentRow.noQualifiedNumber == 0
+              ? 1
+              : 3
+          );
+          this.$set(
+            this.basicInfoData,
+            'qualifiedNumber',
+            this.currentRow.qualifiedNumber
+          );
+          this.$set(
+            this.basicInfoData,
+            'noQualifiedNumber',
+            this.currentRow.noQualifiedNumber
+          );
+          this.$set(
+            this.basicInfoData,
+            'noQualifiedNumber',
+            this.currentRow.noQualifiedNumber
+          );
+
+          this.$set(this.basicInfoData, 'qualityWorkerId', this.currentRow.id);
+          this.$set(
+            this.basicInfoData,
+            'workOrderId',
+            this.currentRow.workOrderId
+          );
+          this.$set(this.basicInfoData, 'type', this.type || 0);
+          this.$set(
+            this.basicInfoData,
+            'qualityType',
+            this.currentRow.qualityType
+          );
+          if (!this.basicInfoData.reportNumber) {
+            getCode('quality_Inspection_report_number').then((res) => {
+              this.$set(this.basicInfoData, 'reportNumber', res);
+            });
+          }
+          this.initUnqualifiedProduct();
+        });
+      },
+      getInspectionItems() {
+        return queryInspectionReportList({
+          id: this.currentRow.id,
+          type: this.type || this.currentRow.type || 0
+        }).then((res) => {
+          this.inspectionItems = res;
+        });
+      },
+
+      cancel() {
+        this.visible = false;
+        this.$emit('close');
+        this.unqualifiedProducts = { ...defForm };
+      },
+      /* 打印 */
+      print() {
+        const printSection = document.getElementById('printSection');
+        console.log('printSection', printSection.innerHTML);
+        // 创建打印任务
+        const printWindow = window.open('', '_blank');
+        printWindow.document.open();
+        printWindow.document.write('<html><head><title>打印预览</title>');
+        printWindow.document.write(
+          '<link rel="stylesheet" href="your-stylesheet-url.css" type="text/css" />'
+        );
+        printWindow.document.write('</head><body>');
+        printWindow.document.write(printSection.innerHTML);
+        printWindow.document.write('</body></html>');
+        printWindow.document.close();
+        printWindow.onload = function () {
+          printWindow.print();
+        };
+      },
+      /* 保存编辑 */
+      save() {
+        this.loading = true;
+        this.isView = true;
+
+        this.$nextTick(() => {
+          const printSection = document.getElementById('printSection');
+
+          const params = {
+            id: this.currentRow.id,
+            type: this.type || this.basicInfoData.type || 0,
+            reportTemplateId:
+              this.templateItem.reportTemplateId || this.templateItem.id,
+            reportTemplateCode:
+              this.templateItem.reportTemplateCode || this.templateItem.code,
+            reportTemplateName:
+              this.templateItem.reportTemplateName || this.templateItem.name,
+            unqualifiedProducts: this.$refs.unqualifiedProductRef.getValue(),
+            reportTemplateJson: {
+              template: printSection.innerHTML,
+              basicInfoData: this.$refs.templateRef.getValue(),
+              inspectionItems: this.inspectionItems
+            }
+          };
+
+          generateReport(params)
+            .then((res) => {
+              this.loading = false;
+              this.isView = false;
+
+              this.$message({
+                message: '保存成功',
+                type: 'success'
+              });
+              this.$emit('reload');
+              this.cancel();
+              // this.$emit('update:visible', false);
+              // this.visible = false;
+            })
+            .catch((err) => {
+              this.loading = false;
+              this.isView = false;
+
+              this.$message({
+                message: err.message,
+                type: 'error'
+              });
+            });
+        });
+      }
+    },
+    computed: {
+      targetComponent() {
+        return this.componentName;
+      }
+    }
+  };
+</script>

+ 905 - 0
src/views/inspectionReport/components/unqualifiedProduct.vue

@@ -0,0 +1,905 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never" v-loading="loading">
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="poList"
+        :selection.sync="selection"
+        :needPage="false"
+        row-key="id"
+      >
+        <!-- 操作列 -->
+        <template v-slot:toolbar v-if="!isView">
+          <el-button type="primary" slot="reference" @click="add"
+            >新增</el-button
+          >
+          <el-button
+            type="primary"
+            slot="reference"
+            :disabled="selection.length == 0"
+            @click="disposeFn(1)"
+            >批量处置</el-button
+          >
+
+          <el-popconfirm
+            class="ele-action"
+            title="确定要删除吗?"
+            @confirm="remove"
+            style="margin-left: 10px"
+          >
+            <template v-slot:reference>
+              <el-button :disabled="selection.length == 0" type="danger"
+                >批量删除</el-button
+              >
+            </template>
+          </el-popconfirm>
+        </template>
+      </ele-pro-table>
+    </el-card>
+
+    <ele-modal
+      :visible.sync="dialogVisible"
+      width="35%"
+      @close="close"
+      append-to-body
+      title="处置"
+    >
+      <el-form
+        ref="disposeForm"
+        :model="disposeForm"
+        label-width="150px"
+        :rules="rules"
+      >
+        <el-form-item label="处置方式:" prop="disposeType">
+          <el-select
+            v-model="disposeForm.disposeType"
+            placeholder="请选择"
+            style="width: 100%"
+            @change="disposeTypeChange"
+          >
+            <el-option
+              v-for="item in disposeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <template
+          v-if="disposeForm.disposeType == 1 || disposeForm.disposeType == 2"
+        >
+          <el-form-item label="回流工序" prop="taskId" align="center">
+            <el-select
+              style="width: 100%"
+              v-model="disposeForm.taskId"
+              clearable
+            >
+              <el-option
+                v-for="item in refluxTaskList"
+                :key="item.taskId"
+                :value="item.taskId"
+                :label="item.taskTypeName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+
+        <template v-if="disposeForm.disposeType == 6">
+          <el-row>
+            <el-col :span="24">
+              <el-form-item
+                label="留样数量:"
+                prop="keepSampleQuantity"
+                align="center"
+              >
+                <el-input
+                  v-model="disposeForm.keepSampleQuantity"
+                  placeholder="请输入"
+                  style="width: 100%"
+                >
+                  <template slot="append">{{
+                    current?.measureUnit
+                  }}</template></el-input
+                >
+              </el-form-item>
+            </el-col>
+            <el-col :span="6"> </el-col>
+          </el-row>
+          <el-row style="margin-top: 12px">
+            <el-col :span="24">
+              <el-form-item label="留样日期:" prop="sampleDate" align="center">
+                <el-date-picker
+                  class="w100"
+                  v-model="disposeForm.sampleDate"
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  placeholder="请输入"
+                ></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6"> </el-col>
+          </el-row>
+          <el-row style="margin-top: 12px">
+            <el-col :span="24">
+              <el-form-item
+                label="留样条件:"
+                prop="sampleCondition"
+                align="center"
+              >
+                <el-input
+                  v-model="disposeForm.sampleCondition"
+                  placeholder="请输入"
+                  style="width: 100%"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 12px">
+            <el-col :span="24">
+              <el-form-item
+                label="生产商/受托生产:"
+                prop="producerManufacturer"
+                align="center"
+              >
+                <el-input
+                  v-model="disposeForm.producerManufacturer"
+                  placeholder="请输入"
+                  style="width: 100%"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 12px">
+            <el-col :span="24">
+              <el-form-item
+                label="留样地点:"
+                prop="samplePlace"
+                align="center"
+              >
+                <el-input
+                  type="textarea"
+                  v-model="disposeForm.samplePlace"
+                  placeholder="请输入"
+                  style="width: 100%"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 12px">
+            <el-col :span="24">
+              <el-form-item
+                label="留样备注:"
+                prop="sampleRemark"
+                align="center"
+              >
+                <el-input
+                  type="textarea"
+                  v-model="disposeForm.sampleRemark"
+                  placeholder="请输入"
+                  style="width: 100%"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row style="margin-top: 12px">
+            <el-col :span="24"> </el-col>
+          </el-row>
+        </template>
+
+        <template
+          v-if="
+            disposeForm.disposeType == 3 ||
+            disposeForm.disposeType == 6 ||
+            disposeForm.disposeType == 9
+          "
+        >
+          <el-form-item label="入库仓库:" prop="depotId" align="center">
+            <el-select style="width: 100%" v-model="disposeForm.depotId">
+              <el-option
+                v-for="item in warehouseList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+                @click.native="chooseWarehouse(item)"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+      </el-form>
+
+      <!-- <DictSelection
+        dictName="不良品处理类型"
+        :filterArr="all ? ['返工返修'] : []"
+        v-model="current.disposalStatus"
+      /> -->
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消 </el-button>
+        <el-button type="primary" @click="handleDispose">确 定</el-button>
+      </div>
+    </ele-modal>
+
+    <ele-modal
+      :visible.sync="addDialogVisible"
+      width="60%"
+      append-to-body
+      title="选择"
+    >
+      <el-table
+        :data="inventoryList"
+        @selection-change="handleAddSelectionChange"
+        row-key="id"
+        ref="table1"
+      >
+        <el-table-column
+          type="selection"
+          width="55"
+          align="center"
+          :selectable="
+            (row, index) => {
+              return (
+                !poList.map((item) => item.sourceId).includes(row.sourceId) ||
+                inventoryList.length == 1
+              );
+            }
+          "
+        ></el-table-column>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="55"
+          align="center"
+        ></el-table-column>
+        <el-table-column
+          prop="sampleCode"
+          label="样品编码"
+          width="150"
+          align="center"
+        ></el-table-column>
+        <el-table-column
+          prop="packageNo"
+          label="包装编码"
+          width="150"
+          align="center"
+        ></el-table-column>
+        <el-table-column
+          prop="categoryCode"
+          label="物品编码"
+          width="150"
+          align="center"
+        ></el-table-column>
+        <el-table-column
+          prop="categoryName"
+          label="物品名称"
+          width="150"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          prop="specification"
+          label="规格"
+          width="120"
+          align="center"
+        ></el-table-column>
+        <el-table-column prop="measureQuantity" label="计量数量" align="center">
+          <template slot-scope="scope">
+            <template v-if="inventoryList.length === 1">
+              <el-input-number
+                v-model="singleQuantity"
+                :min="0"
+                :max="total"
+                style="width: 120px"
+              ></el-input-number>
+            </template>
+            <template v-else>
+              {{ scope.row.measureQuantity }}
+            </template>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="measureUnit"
+          label="计量单位"
+          align="center"
+        ></el-table-column>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="addDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="handleAddSave">确 定</el-button>
+      </div>
+    </ele-modal>
+  </div>
+</template>
+
+<script>
+  import Edit from '@/views/unqualifiedProduct/unqualifiedList/components/edit.vue';
+  import { getWarehouseList } from '@/api/samplemanagement';
+  import dictMixins from '@/mixins/dictMixins';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import { getById } from '@/api/unacceptedProduct/index';
+  import {
+    queryQualitySamplContent,
+    queryQualityInventory
+  } from '@/api/inspectionWork';
+  export default {
+    components: {
+      Edit
+    },
+    props: {
+      total: {
+        type: Number,
+        default: 0
+      },
+      isView: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mixins: [dictMixins, tabMixins],
+    data() {
+      return {
+        cacheKeyUrl: 'qsm-c2e9664a-unqualifiedList-detailList',
+        key: '',
+        warehouseList: [],
+        rules: {
+          disposeType: [
+            { required: true, message: '请选择处置方式', trigger: 'change' }
+          ],
+          depotId: [
+            { required: true, message: '请选择仓库', trigger: 'change' }
+          ],
+          keepSampleQuantity: [
+            {
+              validator: (rule, value, callback) => {
+                if (
+                  this.disposeForm.disposeType === 6 &&
+                  this.current &&
+                  this.current.measureQuantity !== undefined
+                ) {
+                  const inputVal = Number(value);
+                  const maxVal = Number(this.current.measureQuantity);
+                  if (inputVal > maxVal) {
+                    return callback(new Error(`不能超过原计量数量${maxVal}`));
+                  }
+                }
+                callback();
+              },
+              trigger: 'blur'
+            }
+          ]
+        },
+        disposeType: '',
+        disposeForm: {
+          disposeType: '',
+          sampleCondition: '',
+          sampleDate: '',
+          samplePlace: '',
+          sampleRemark: '',
+          producerManufacturer: '',
+          depotId: '',
+          depotName: '',
+          taskId: '',
+          keepSampleQuantity: ''
+        },
+        loading: false,
+        selection: [],
+        poList: [],
+        id: '',
+        dialogVisible: false,
+        current: {},
+        formData: {},
+        all: false,
+        qualityType: null,
+        allList: [
+          { value: 1, label: '返工' },
+          { value: 2, label: '返修' },
+          { value: 3, label: '报废' },
+          { value: 4, label: '降级使用' },
+          { value: 5, label: '让步接收' },
+          { value: 6, label: '留样' },
+          { value: 7, label: '消耗' },
+          { value: 8, label: '回用/归批' },
+          { value: 9, label: '转试销' },
+          { value: 10, label: '退货' }
+        ],
+
+        //生产
+        disposalStatusList: [
+          {
+            value: 1,
+            label: '返工'
+          },
+          {
+            value: 2,
+            label: '返修'
+          },
+          {
+            value: 3,
+            label: '报废'
+          },
+          {
+            value: 4,
+            label: '降级使用'
+          },
+          {
+            value: 5,
+            label: '让步接收'
+          },
+          {
+            value: 6,
+            label: '留样'
+          },
+          {
+            value: 7,
+            label: '消耗'
+          },
+          {
+            value: 8,
+            label: '回用'
+          }
+        ],
+        workOrderCode: '',
+        qualityWorkerId: '',
+        qualityResults: '',
+        refluxTaskList: [],
+        sampleList: [],
+        inventoryList: [],
+        oldList: [],
+        addDialogVisible: false,
+        addSelection: [],
+        singleQuantity: ''
+      };
+    },
+    computed: {
+
+      disposeList() {
+        if (this.qualityType == 1) {
+          return this.allList.filter((item) => [5, 10].includes(item.value));
+        }
+        if (this.qualityType == 2) {
+          return this.allList.filter((item) => item.value !== 8);
+        }
+        if (this.qualityType == 2 || this.qualityType == 3) {
+          return this.allList.filter(
+            (item) => item.value !== 8 && item.value !== 10
+          );
+        } else {
+          return this.allList;
+        }
+      },
+      // 表格列配置
+      columns() {
+        const arr = [
+          {
+            width: 45,
+            type: 'selection',
+            columnKey: 'selection',
+            reserveSelection: true,
+            align: 'center'
+          },
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            label: '样品编码',
+            prop: 'sampleCode',
+            width: '150',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'categoryCode',
+            label: '物品编码',
+            width: '150',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'categoryName',
+            label: '物品名称',
+            width: '150',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '规格',
+            prop: 'specification',
+            width: '120',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'brandNum',
+            label: '牌号',
+            align: 'center'
+          },
+          {
+            prop: 'modelType',
+            label: '型号',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true
+          },
+          {
+            label: '机型',
+            prop: 'modelKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '颜色',
+            prop: 'colorKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'weight',
+            label: '重量',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'weightUnit',
+            label: '重量单位',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'engrave',
+            label: '刻码',
+            align: 'center'
+          },
+
+          { label: '计量数量', prop: 'measureQuantity', align: 'center' },
+          { label: '计量单位', prop: 'measureUnit', align: 'center' },
+
+          {
+            prop: 'produceRoutingName',
+            label: '工艺路线',
+            align: 'center'
+          },
+          {
+            prop: 'produceTaskName',
+            label: '工序',
+            align: 'center'
+          },
+          {
+            prop: 'badTypeName',
+            label: '不良类型',
+            width: '180',
+            align: 'center'
+          },
+          {
+            prop: 'badNameName',
+            label: '不良名称',
+            width: '180',
+            align: 'center'
+          },
+          {
+            prop: 'reasonTypeName',
+            label: '原因类型',
+            width: '180',
+            align: 'center'
+          },
+          {
+            prop: 'unqualifiedReason',
+            label: '原因',
+            width: '180',
+            align: 'center'
+          },
+          {
+            prop: 'disposeTime',
+            label: '处置时间',
+            align: 'center',
+            width: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'disposalStatus',
+            label: '处置状态',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true,
+            formatter: (row, column, cellValue) => {
+              return this.disposalStatustList[cellValue ? cellValue : 0];
+            }
+          },
+          {
+            prop: 'disposeType',
+            label: '处置类型',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true,
+            formatter: (row, column, cellValue) => {
+              console.log(this.allList.find((item) => item.value == cellValue));
+
+              return this.allList.find((item) => item.value == cellValue)
+                ?.label;
+            }
+          }
+        ];
+        return arr;
+      },
+      disposalStatustList() {
+        return { 0: '待处置', 1: '处置中', 2: '处置完成' };
+      }
+    },
+
+    methods: {
+      async init(row) {
+        this.qualityType = row.qualityType;
+        this.id = row.id;
+        console.log(row, 'row');
+        this.workOrderCode = row.workOrderCode;
+        this.qualityWorkerId = row.qualityWorkerId;
+        this.qualityResults = row.qualityResults;
+        this.warehouseList = await getWarehouseList();
+        await this.getQueryQualityInventory();
+        await this.queryQualitySamplContent();
+        if (this.id) {
+          await this.datasource();
+        }
+      },
+      setQualifiedNumber() {
+        let isQualifiedNumber = true;
+        let noQualifiedNumber = this.poList
+          .filter((item) => item.disposeType != 5)
+          .reduce((acc, cur) => acc + cur.measureQuantity, 0);
+
+        if (
+          this.poList
+            .filter((item) => item.disposeType == 5)
+            .reduce((acc, cur) => acc + cur.measureQuantity, 0) == this.total
+        ) {
+          isQualifiedNumber = false;
+        }
+        this.$emit('setQualifiedNumber', {
+          noQualifiedNumber,
+          qualifiedNumber: this.total - noQualifiedNumber,
+          isQualifiedNumber
+        });
+      },
+      selectResult(qualityResults) {
+        if (qualityResults == 1) {
+          this.poList = JSON.parse(JSON.stringify(this.oldList));
+          this.poList = this.poList.map((item) => {
+            item.disposalStatus = 1;
+            item.disposeType = 5;
+            return item;
+          });
+        }
+        if (qualityResults == 4) {
+          this.poList = JSON.parse(JSON.stringify(this.inventoryList));
+          this.poList = this.poList.map((item) => {
+            item.disposalStatus = 1;
+            item.disposeType = 5;
+            return item;
+          });
+        }
+        if (qualityResults == 2) {
+          this.poList = JSON.parse(JSON.stringify(this.inventoryList));
+        }
+        if (qualityResults == 3) {
+          this.poList = JSON.parse(JSON.stringify(this.oldList));
+        }
+        this.qualityResults = qualityResults;
+        this.setQualifiedNumber();
+      },
+      disposeTypeChange() {
+        if (this.disposeForm.disposeType == 6) {
+          this.disposeForm.keepSampleQuantity =
+            this.current?.measureQuantity || '';
+        }
+      },
+      // /* 表格数据源 */
+      async datasource() {
+        const arr = await getById(this.id);
+        this.oldList = JSON.parse(JSON.stringify(arr.poList));
+        this.poList = arr.poList;
+      },
+
+      //   async getRefluxTask() {
+      //     await refluxTask({
+      //       workOrderCode: this.workOrderCode
+      //     }).then((res) => {
+      //       this.refluxTaskList = res;
+      //     });
+      //   },
+
+      remove() {
+        let ids = this.selection.map((item) => item.id);
+        console.log(ids, 'ids');
+        this.poList = this.poList.filter((item) => !ids.includes(item.id));
+        this.setQualifiedNumber();
+      },
+      close() {
+        this.dialogVisible = false;
+        this.disposeType = '';
+        this.all = false;
+        this.formData.disposalStatus = '';
+      },
+      add() {
+        this.addDialogVisible = true;
+        this.$refs.table1.clearSelection();
+        this.addSelection = [];
+        if (this.inventoryList.length === 1) {
+          this.singleQuantity = this.inventoryList[0].measureQuantity || 0;
+        }
+      },
+      handleAddSelectionChange(selection) {
+        this.addSelection = selection;
+      },
+      handleAddSave() {
+        if (this.addSelection.length === 0) {
+          this.$message.warning('请选择数据');
+          return;
+        }
+        const poListTotal = this.poList.reduce(
+          (sum, item) => sum + Number(item.measureQuantity || 0),
+          0
+        );
+        let selectedTotal = 0;
+        if (this.inventoryList.length === 1) {
+          selectedTotal =
+            this.addSelection.length * Number(this.singleQuantity || 0);
+        } else {
+          selectedTotal = this.addSelection.reduce(
+            (sum, item) => sum + Number(item.measureQuantity || 0),
+            0
+          );
+        }
+        if (poListTotal + selectedTotal > this.total) {
+          this.$message.error('选中的计量数量之和加上已有数量不能超过总数');
+          return;
+        }
+        this.addSelection.forEach((item) => {
+          const newItem = JSON.parse(JSON.stringify(item));
+          if (this.inventoryList.length === 1) {
+            newItem.measureQuantity = Number(this.singleQuantity);
+          }
+          this.poList.push(newItem);
+        });
+        this.addDialogVisible = false;
+        this.setQualifiedNumber();
+      },
+      // // 处置
+      disposeFn(type, row) {
+        if (type == 1) {
+          this.all = true;
+        } else {
+          this.current = row;
+        }
+        this.formData = { ...row };
+        this.dialogVisible = true;
+        // let ids = this.current ? [this.current.id] : this.selection.map((item) => item.id);
+      },
+
+      async getQueryQualityInventory() {
+        const res = await queryQualityInventory({
+          qualityWorkerId: this.qualityWorkerId,
+          size: -1
+        });
+
+        if (res.list.length > 0) {
+          this.inventoryList = res.list;
+        }
+      },
+
+      async queryQualitySamplContent() {
+        const res = await queryQualitySamplContent({
+          qualityWorkerId: this.qualityWorkerId,
+          size: 1000
+        });
+        this.sampleList = res.list;
+      },
+
+      async handleDispose() {
+        this.$refs['disposeForm'].validate(async (valid) => {
+          let ids = this.selection.map((item) => item.id);
+          this.poList.forEach((item, index) => {
+            if (ids.includes(item.id)) {
+              this.$set(this.poList[index], 'disposalStatus', 1);
+
+              for (const key in this.disposeForm) {
+                this.$set(this.poList[index], key, this.disposeForm[key]);
+              }
+            }
+          });
+          this.dialogVisible = false;
+          this.setQualifiedNumber();
+        });
+      },
+      validate() {},
+      getValue() {
+        let unqualifiedProducts = {};
+        if (this.poList.length > 0) {
+          unqualifiedProducts.poList = this.poList.map((item) => {
+            item.qualityResults = 1;
+            item.qualityStatus = 1;
+            item.qualityWorkOrderId = this.qualityWorkerId;
+            return item;
+          });
+          [
+            'batchNo',
+            'brandNum',
+            'categoryCode',
+            'categoryId',
+            'categoryName',
+            'factoriesId',
+            'measureUnit',
+            'modelType',
+            'produceRoutingId',
+            'produceRoutingName',
+            'productCategory'
+          ].forEach((item) => {
+            unqualifiedProducts[item] = this.poList[0][item];
+          });
+
+          unqualifiedProducts.qualityType = this.qualityType;
+          unqualifiedProducts.qualityWorkOrderId = this.qualityWorkerId;
+          unqualifiedProducts.sourceCode = this.workOrderCode;
+          unqualifiedProducts.quantity = this.poList.reduce(
+            (total, item) => total + item.measureQuantity,
+            0
+          );
+          unqualifiedProducts.sourceType = this.workOrderId ? 1 : 0;
+
+          return unqualifiedProducts;
+        }
+        return null;
+      },
+      chooseWarehouse(item) {
+        console.log(item);
+        this.disposeForm.depotId = item.id;
+        this.disposeForm.depotName = item.name;
+      }
+    },
+    watch: {
+      'disposeForm.disposeType': {
+        handler(newVal, oldVal) {
+          if (newVal == 6) {
+            this.rules.depotId = [];
+          } else {
+            this.rules.depotId = [
+              { required: true, message: '请选择仓库', trigger: 'change' }
+            ];
+          }
+          this.disposeForm.sampleCondition = '';
+          this.disposeForm.sampleDate = '';
+          this.disposeForm.samplePlace = '';
+          this.disposeForm.sampleRemark = '';
+          this.disposeForm.producerManufacturer = '';
+          this.disposeForm.depotId = '';
+          this.disposeForm.depotName = '';
+          this.disposeForm.taskId = '';
+        }
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .unacceptedProductSelect {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+</style>

+ 8 - 30
src/views/inspectionReport/index.vue

@@ -85,16 +85,10 @@
       </ele-pro-table>
     </el-card>
 
-    <component
-      v-if="targetVisible"
-      :is="targetComponent"
-      :key="targetComponent"
-      :isView="isView"
-      :visible.sync="targetVisible"
-      :row="currentRow"
-      :item="currentItem"
+    <ReportTemplateWrapper
+      ref="reportTemplateWrapperRef"
       @reload="search"
-    ></component>
+    ></ReportTemplateWrapper>
 
     <process-submit-dialog
       api-fun-name="qmsReportApprovalAPI"
@@ -123,8 +117,7 @@
   import tabMixins from '@/mixins/tableColumnsMixin';
   import { getCategoryByCode } from '@/api/main/index';
   import { getList, deleteReport } from '@/api/inspectionReport';
-  import inspection_report1 from '../inspectionReport/template/inspection_report1.vue';
-  import inspection_report2 from '../inspectionReport/template/inspection_report2.vue';
+  import ReportTemplateWrapper from '../inspectionReport/components/reportTemplateWrapper.vue';
   import QualityReportDetail from '../inspectionReport/components/detailDialog.vue';
   import { recordingMethodList } from '@/utils/util.js';
 
@@ -133,10 +126,9 @@
     components: {
       search,
       jimureportBrowse,
-      inspection_report1,
-      inspection_report2,
       processSubmitDialog,
-      QualityReportDetail
+      QualityReportDetail,
+      ReportTemplateWrapper
     },
     data() {
       return {
@@ -144,7 +136,6 @@
         targetComponent: null,
         targetVisible: false,
         detailVisible: false,
-        isView: false,
         currentRow: {},
         currentItem: {},
         columns: [
@@ -457,23 +448,10 @@
         });
       },
       async openEdit(row) {
-        console.log(row);
-        this.isView = false;
-        this.targetComponent = row.reportTemplateCode;
-        this.currentRow = row;
-        this.$nextTick(() => {
-          this.targetVisible = true;
-        });
+        this.$refs.reportTemplateWrapperRef.open({ row, item: {} }, false);
       },
       openDetails(row) {
-        this.isView = true;
-        this.currentRow = row;
-        this.targetComponent = row.reportTemplateCode;
-        console.log('currentRow', this.currentRow, this.targetComponent);
-        this.$nextTick(() => {
-          this.targetVisible = true;
-          console.log('targetVisible~~~~', this.targetVisible);
-        });
+        this.$refs.reportTemplateWrapperRef.open({ row, item: {} }, true);
       },
       async deleteReportBtn(row) {
         try {

+ 308 - 598
src/views/inspectionReport/template/inspection_report1.vue

@@ -1,649 +1,359 @@
 <template>
-  <ele-modal
-    :visible="visible"
-    v-if="visible"
-    title="检测报告"
-    width="70%"
-    append-to-body
-    :before-close="cancel"
-    :maxable="true"
-  >
-    <div v-if="isView && processInstanceId" class="switch">
-      <div class="switch_left">
-        <ul>
-          <li
-            v-for="item in tabOptions"
-            :key="item.key"
-            :class="{ active: activeComp == item.key }"
-            @click="activeComp = item.key"
-          >
-            {{ item.name }}
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div
-      v-show="activeComp === 'main'"
-      id="printSection"
-      style="padding: 20px; background-color: white"
+  <div id="printSection" style="padding: 20px; background-color: white">
+    <h1
+      style="
+        text-align: center;
+        font-size: 24px;
+        margin-bottom: 20px;
+        font-weight: bold;
+      "
+      >检测报告</h1
     >
-      <h1
-        style="
-          text-align: center;
-          font-size: 24px;
-          margin-bottom: 20px;
-          font-weight: bold;
-        "
-        >检测报告</h1
-      >
 
-      <!-- 编号和报告单号 -->
-      <div style="margin-bottom: 20px">
-        <el-row>
-          <el-col :span="12">
-            <div style="display: flex; align-items: center">
-              <span style="font-weight: bold; margin-right: 10px">编号:</span>
-              <span style="flex: 1">{{ basicInfoData.code }}</span>
+    <!-- 编号和报告单号 -->
+    <div style="margin-bottom: 20px">
+      <el-row>
+        <el-col :span="12">
+          <div style="display: flex; align-items: center">
+            <span style="font-weight: bold; margin-right: 10px">编号:</span>
+            <span style="flex: 1">{{ basicInfoData.code }}</span>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div style="display: flex; align-items: center">
+            <span style="font-weight: bold; margin-right: 10px">报告单号:</span>
+            <span style="flex: 1">
+              <div v-if="isView">
+                {{ basicInfoData.reportNumber }}
+              </div>
+              <div v-else>
+                <el-input
+                  v-model="basicInfoData.reportNumber"
+                  placeholder="请输入报告编号"
+                ></el-input>
+              </div>
+            </span>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 基本信息表格 -->
+    <table
+      class="basic-info-table"
+      style="width: 100%; border-collapse: collapse; border: 1px solid #ccc"
+    >
+      <tbody>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检品名称</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.productName
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >批号/序列号</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.batchNo
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >规格型号</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px"
+            >{{ basicInfoData.specification }}/{{ basicInfoData.modelType }}</td
+          >
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >数量</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.total
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >请验日期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.pleaseVerifyDate
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >请验部门</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.pleaseVerifyDepartment
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >报告日期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-date-picker
+                v-model="basicInfoData.reportDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期"
+              />
             </div>
-          </el-col>
-          <el-col :span="12">
-            <div style="display: flex; align-items: center">
-              <span style="font-weight: bold; margin-right: 10px"
-                >报告单号:</span
-              >
-              <span style="flex: 1">
-                <div v-if="isView">
-                  {{ basicInfoData.reportNumber }}
-                </div>
-                <div v-else>
-                  <el-input
-                    v-model="basicInfoData.reportNumber"
-                    placeholder="请输入报告编号"
-                  ></el-input>
-                </div>
-              </span>
+            <div v-else>{{ basicInfoData.reportDate }}</div>
+          </td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >有效期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-date-picker
+                v-model="basicInfoData.expirationDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期"
+              />
+            </div>
+            <div v-else>{{ basicInfoData.expirationDate || '/' }}</div>
+          </td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >来源</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.source"
+                placeholder="请输入来源"
+              ></el-input>
             </div>
-          </el-col>
-        </el-row>
-      </div>
+            <div v-else>{{ basicInfoData.source }}</div>
+          </td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >储存条件</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.storageCondition"
+                placeholder="请输入储存条件"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.storageCondition }}</div>
+          </td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验依据</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" colspan="3">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.inspectionBasis"
+                placeholder="请输入检验依据"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.inspectionBasis }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
 
-      <!-- 基本信息表格 -->
-      <table
-        class="basic-info-table"
-        style="width: 100%; border-collapse: collapse; border: 1px solid #ccc"
-      >
-        <tbody>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检品名称</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.productName
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >批号/序列号</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.batchNo
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >规格型号</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px"
-              >{{ basicInfoData.specification }}/{{
-                basicInfoData.modelType
-              }}</td
-            >
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >数量</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.total
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >请验日期</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.pleaseVerifyDate
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >请验部门</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.pleaseVerifyDepartment
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >报告日期</td
+    <!-- 检验项目表格 -->
+    <table
+      class="inspection-items-table"
+      style="
+        width: 100%;
+        border-collapse: collapse;
+        border: 1px solid #ccc;
+        margin-bottom: 20px;
+      "
+    >
+      <thead>
+        <tr>
+          <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验项目</th
+          >
+          <th style="border: 1px solid #ccc; padding: 8px">标准规定</th>
+          <th style="border: 1px solid #ccc; padding: 8px; width: 150px"
+            >检测内容</th
+          >
+          <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验结果</th
+          >
+        </tr>
+      </thead>
+      <tbody>
+        <tr v-for="(item, index) in inspectionItems" :key="index">
+          <td
+            style="
+              width: 150px;
+              border: 1px solid #ccc;
+              padding: 8px;
+              min-height: 37px;
+            "
+            >{{ item.item }}</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            item.standardRegulations
+          }}</td>
+          <td style="border: 1px solid #ccc; padding: 8px; width: 150px">{{
+            item.qualityResultContent
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px">{{
+            item.results
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
+            >结论</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.conclusion"
+                placeholder="请输入结论"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.conclusion || '' }}</div>
+          </td>
+        </tr>
+        <tr>
+          <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
+            >备注</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.remarks"
+                placeholder="请输入备注"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.remarks || '' }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+    <!-- 签名区域 -->
+    <div style="margin-top: 20px">
+      <el-row :gutter="20" style="display: flex; align-items: center">
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >检验员/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
+                <el-input
+                  v-model="basicInfoData.inspector"
+                  placeholder="请输入检验员"
+                  style="width: 140px"
+                ></el-input>
                 <el-date-picker
-                  v-model="basicInfoData.reportDate"
+                  v-model="basicInfoData.inspectionTime"
                   type="date"
                   value-format="yyyy-MM-dd"
                   placeholder="选择日期"
+                  style="width: 160px"
                 />
               </div>
-              <div v-else>{{ basicInfoData.reportDate }}</div>
-            </td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >有效期</td
+              <div v-else
+                >{{ basicInfoData.inspector || '' }} /
+                {{ basicInfoData.inspectionTime || '' }}</div
+              >
+            </span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >复核人/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
+                <el-input
+                  v-model="basicInfoData.reviewer"
+                  placeholder="请输入复核人"
+                  style="width: 140px"
+                ></el-input>
                 <el-date-picker
-                  v-model="basicInfoData.expirationDate"
+                  v-model="basicInfoData.reviewTime"
                   type="date"
                   value-format="yyyy-MM-dd"
                   placeholder="选择日期"
+                  style="width: 160px"
                 />
               </div>
-              <div v-else>{{ basicInfoData.expirationDate || '/' }}</div>
-            </td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >来源</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.source"
-                  placeholder="请输入来源"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.source }}</div>
-            </td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >储存条件</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.storageCondition"
-                  placeholder="请输入储存条件"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.storageCondition }}</div>
-            </td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验依据</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px" colspan="3">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.inspectionBasis"
-                  placeholder="请输入检验依据"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.inspectionBasis }}</div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-
-      <!-- 检验项目表格 -->
-      <table
-        class="inspection-items-table"
-        style="
-          width: 100%;
-          border-collapse: collapse;
-          border: 1px solid #ccc;
-          margin-bottom: 20px;
-        "
-      >
-        <thead>
-          <tr>
-            <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验项目</th
-            >
-            <th style="border: 1px solid #ccc; padding: 8px">标准规定</th>
-            <th style="border: 1px solid #ccc; padding: 8px; width: 150px"
-              >检测内容</th
-            >
-            <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验结果</th
-            >
-          </tr>
-        </thead>
-        <tbody>
-          <tr v-for="(item, index) in inspectionItems" :key="index">
-            <td
-              style="
-                width: 150px;
-                border: 1px solid #ccc;
-                padding: 8px;
-                min-height: 37px;
-              "
-              >{{ item.item }}</td
-            >
-            <td style=" border: 1px solid #ccc; padding: 8px">{{
-              item.standardRegulations
-            }}</td>
-            <td style="border: 1px solid #ccc; padding: 8px;width: 150px;">{{
-              item.qualityResultContent
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px">{{
-              item.results
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
-              >结论</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.conclusion"
-                  placeholder="请输入结论"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.conclusion || '' }}</div>
-            </td>
-          </tr>
-          <tr>
-            <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
-              >备注</td
+              <div v-else
+                >{{ basicInfoData.reviewer || '' }} /
+                {{ basicInfoData.reviewTime || '' }}</div
+              >
+            </span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >审核人/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
                 <el-input
-                  v-model="basicInfoData.remarks"
-                  placeholder="请输入备注"
+                  v-model="basicInfoData.checker"
+                  placeholder="请输入审核人"
+                  style="width: 140px"
                 ></el-input>
+                <el-date-picker
+                  v-model="basicInfoData.approvedDate"
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  placeholder="选择日期"
+                  style="width: 160px"
+                />
               </div>
-              <div v-else>{{ basicInfoData.remarks || '' }}</div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-      <!-- 签名区域 -->
-      <div style="margin-top: 20px">
-        <el-row :gutter="20" style="display: flex; align-items: center">
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >检验员/日期:</span
+              <div v-else
+                >{{ basicInfoData.checker || '' }} /
+                {{ basicInfoData.approvedDate || '' }}</div
               >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.inspector"
-                    placeholder="请输入检验员"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.inspectionTime"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.inspector || '' }} /
-                  {{ basicInfoData.inspectionTime || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >复核人/日期:</span
-              >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.reviewer"
-                    placeholder="请输入复核人"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.reviewTime"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.reviewer || '' }} /
-                  {{ basicInfoData.reviewTime || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >审核人/日期:</span
-              >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.checker"
-                    placeholder="请输入审核人"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.approvedDate"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.checker || '' }} /
-                  {{ basicInfoData.approvedDate || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-        </el-row>
-      </div>
+            </span>
+          </div>
+        </el-col>
+      </el-row>
     </div>
-    <bpmDetail
-      v-if="activeComp === 'bpm' && processInstanceId"
-      :id="processInstanceId"
-    ></bpmDetail>
-    <template v-slot:footer>
-      <el-button v-if="isView" type="primary" @click="print" v-loading="loading"
-        >打印</el-button
-      >
-      <el-button v-if="!isView" type="primary" @click="save" v-loading="loading"
-        >确认</el-button
-      >
-      <el-button @click="cancel">关闭</el-button>
-    </template>
-  </ele-modal>
+  </div>
 </template>
 
 <script>
-  import {
-    queryInspectionReportData,
-    queryInspectionReportList,
-    generateReport
-  } from '@/api/inspectionReport';
-
-  import bpmDetail from '@/views/bpm/processInstance/detail.vue';
-  import { getCode } from '@/api/login';
-
   export default {
     name: 'QualityReport',
     props: {
       isView: {
         type: Boolean,
         default: false
-      },
-      visible: {
-        type: Boolean,
-        default: false
-      },
-      row: {
-        type: Object,
-        default: () => {}
-      },
-      item: {
-        type: Object,
-        default: () => {}
-      },
-      type: ''
-    },
-    components: {
-      bpmDetail
+      }
     },
+
+    components: {},
     data() {
       return {
-        // visible: false,
-        loading: false,
-        currentRow: {}, // 存储当前行数据
-        templateItem: {}, // 存储当前模板项数据
         // 基本信息数据
         basicInfoData: {},
 
         // 检验项目
-        inspectionItems: [],
-        tabOptions: [
-          { key: 'main', name: '业务详情' },
-          { key: 'bpm', name: '流程详情' }
-        ],
-        activeComp: 'main',
-        processInstanceId: '',
-        reportApprovalTaskVos: []
+        inspectionItems: []
       };
     },
-    watch: {
-      visible: {
-        handler: function (val) {
-          console.log('visible~~~', val);
-          if (val) {
-            this.open(this.row, this.item);
-          }
-        },
-        deep: true,
-        immediate: true
-      }
-    },
-    created() {
-      // 页面加载时可以在这里添加数据初始化逻辑
-    },
+    created() {},
     methods: {
-      /* 打开检测报告 */
-      async open(row, item) {
-        this.currentRow = row;
-        this.templateItem = item || row;
-        console.log('currentRow~~~', this.currentRow, this.templateItem);
-        // let api = this.type === '0' ? getDetailById : getById;
-        this.processInstanceId = row.reportProcessInstanceId;
-        this.reportApprovalTaskVos = row.reportApprovalTaskVos;
-
-        // try {
-        //   const res = await api(this.row.id);
-        //   this.processInstanceId = row.reportProcessInstanceId;
-        //   this.reportApprovalTaskVos = res.data.reportApprovalTaskVos;
-        // } catch (error) {
-        //   console.log('error~~~~', error);
-        // }
-
-        // this.visible = true;
-        if (this.currentRow.reportTemplateJson?.basicInfoData) {
-          this.basicInfoData =
-            this.currentRow.reportTemplateJson.basicInfoData || {};
-          this.inspectionItems =
-            this.currentRow.reportTemplateJson.inspectionItems || [];
-
-          const reviewTime =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 2
-            ]?.endTime?.split(' ')[0] || '';
-          const approvedDate =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 3
-            ]?.endTime?.split(' ')[0] || '';
-          const reviewer =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
-              ?.approvalUserName || '';
-          const checker =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
-              ?.approvalUserName || '';
-
-          this.$set(
-            this.basicInfoData,
-            'inspectionTime',
-            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewTime',
-            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'approvedDate',
-            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewer',
-            this.basicInfoData.reviewer || reviewer || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'checker',
-            this.basicInfoData.checker || checker || ''
-          );
-        } else {
-          this.getBasicInfo();
-          this.getInspectionItems();
-        }
+      /* 打开质检报告 */
+      async init(basicInfoData, inspectionItems) {
+        this.$set(this, 'basicInfoData', basicInfoData);
+        this.$set(this, 'inspectionItems', inspectionItems);
       },
-      getBasicInfo() {
-        queryInspectionReportData({
-          id: this.currentRow.id,
-          type: this.type
-        }).then((res) => {
-          this.basicInfoData = res;
 
-          const reviewTime =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 2
-            ]?.endTime?.split(' ')[0] || '';
-          const approvedDate =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 3
-            ]?.endTime?.split(' ')[0] || '';
-          const reviewer =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
-              ?.approvalUserName || '';
-          const checker =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
-              ?.approvalUserName || '';
-
-          this.$set(
-            this.basicInfoData,
-            'inspectionTime',
-            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewTime',
-            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'approvedDate',
-            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewer',
-            this.basicInfoData.reviewer || reviewer || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'checker',
-            this.basicInfoData.checker || checker || ''
-          );
-          if (!this.basicInfoData.reportNumber) {
-            getCode('quality_Inspection_report_number').then((res) => {
-              this.$set(this.basicInfoData, 'reportNumber', res);
-            });
-          }
-        });
-      },
-      getInspectionItems() {
-        queryInspectionReportList({
-          id: this.currentRow.id,
-          type: this.type
-        }).then((res) => {
-          this.inspectionItems = res;
-        });
-      },
-
-      cancel() {
-        // this.visible = false;
-        this.$emit('update:visible', false);
-      },
       /* 保存编辑 */
-      save() {
-        this.loading = true;
-        this.isView = true;
-
-        this.$nextTick(() => {
-          const printSection = document.getElementById('printSection');
-          const params = {
-            type: this.type,
-            id: this.currentRow.id,
-            reportTemplateId: this.templateItem.id,
-            reportTemplateCode:
-              this.templateItem.code || this.templateItem.reportTemplateCode,
-            reportTemplateName:
-              this.templateItem.name || this.templateItem.reportTemplateName,
-            reportTemplateJson: {
-              template: printSection.innerHTML,
-              basicInfoData: this.basicInfoData,
-              inspectionItems: this.inspectionItems
-            }
-          };
-          generateReport(params)
-            .then((res) => {
-              this.loading = false;
-              this.isView = false;
-
-              this.$message({
-                message: '保存成功',
-                type: 'success'
-              });
-              this.$emit('reload');
-              this.cancel();
-              // this.$emit('update:visible', false);
-              // this.visible = false;
-            })
-            .catch((err) => {
-              this.loading = false;
-              this.isView = false;
-
-              this.$message({
-                message: err.message,
-                type: 'error'
-              });
-            });
-        });
-      },
-      /* 打印 */
-      print() {
-        const printSection = document.getElementById('printSection');
-        console.log('printSection', printSection.innerHTML);
-        // 创建打印任务
-        const printWindow = window.open('', '_blank');
-        printWindow.document.open();
-        printWindow.document.write('<html><head><title>打印预览</title>');
-        printWindow.document.write(
-          '<link rel="stylesheet" href="your-stylesheet-url.css" type="text/css" />'
-        );
-        printWindow.document.write('</head><body>');
-        printWindow.document.write(printSection.innerHTML);
-        printWindow.document.write('</body></html>');
-        printWindow.document.close();
-        printWindow.onload = function () {
-          printWindow.print();
-        };
+      getValue() {
+        return this.basicInfoData;
       }
     }
   };

+ 319 - 599
src/views/inspectionReport/template/inspection_report2.vue

@@ -1,660 +1,380 @@
 <template>
-  <ele-modal
-    :visible="visible"
-    v-if="visible"
-    title="检测报告"
-    width="70%"
-    append-to-body
-    :before-close="cancel"
-    :maxable="true"
-  >
-    <div v-if="isView && processInstanceId" class="switch">
-      <div class="switch_left">
-        <ul>
-          <li
-            v-for="item in tabOptions"
-            :key="item.key"
-            :class="{ active: activeComp == item.key }"
-            @click="activeComp = item.key"
-          >
-            {{ item.name }}
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div
-      v-show="activeComp === 'main'"
-      id="printSection"
-      style="padding: 20px; background-color: white"
+  <div id="printSection" style="padding: 20px; background-color: white">
+    <h2 style="text-align: center; font-size: 24px; margin-bottom: 10px"
+      >湖南特瑞精密医疗器器械有限公司</h2
+    >
+    <h1
+      style="
+        text-align: center;
+        font-size: 24px;
+        margin-bottom: 20px;
+        font-weight: bold;
+      "
+      >成品检验报告</h1
     >
-      <h2 style="text-align: center; font-size: 24px; margin-bottom: 10px"
-        >湖南特瑞精密医疗器器械有限公司</h2
-      >
-      <h1
-        style="
-          text-align: center;
-          font-size: 24px;
-          margin-bottom: 20px;
-          font-weight: bold;
-        "
-        >成品检验报告</h1
-      >
 
-      <!-- 编号和报告单号 -->
-      <div style="margin-bottom: 5px">
-        <el-row style="display: flex">
-          <el-col :span="12" style="width: 50%">
-            <div style="display: flex; align-items: center">
-              <span style="font-weight: bold; margin-right: 10px"
-                >报告编号:</span
-              >
-              <span style="flex: 1">{{ basicInfoData.code }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12" style="width: 50%">
-            <div
-              style="
-                display: flex;
-                align-items: center;
-                justify-content: flex-end;
-              "
-            >
-              <span style="font-weight: bold; margin-right: 10px"
-                >表单编号:</span
-              >
+    <!-- 编号和报告单号 -->
+    <div style="margin-bottom: 5px">
+      <el-row style="display: flex">
+        <el-col :span="12" style="width: 50%">
+          <div style="display: flex; align-items: center">
+            <span style="font-weight: bold; margin-right: 10px">报告编号:</span>
+            <span style="flex: 1">{{ basicInfoData.code }}</span>
+          </div>
+        </el-col>
+        <el-col :span="12" style="width: 50%">
+          <div
+            style="
+              display: flex;
+              align-items: center;
+              justify-content: flex-end;
+            "
+          >
+            <span style="font-weight: bold; margin-right: 10px">表单编号:</span>
+
+            <span v-if="isView">
+              {{ basicInfoData.reportNumber }}
+            </span>
+            <span v-else>
+              <el-input
+                v-model="basicInfoData.reportNumber"
+                placeholder="请输入报告编号"
+              ></el-input>
+            </span>
+            <span style="font-weight: bold; margin-left: 3px">
+              <span> 版本:</span>
 
               <span v-if="isView">
-                {{ basicInfoData.reportNumber }}
+                {{ basicInfoData.version }}
               </span>
               <span v-else>
                 <el-input
-                  v-model="basicInfoData.reportNumber"
-                  placeholder="请输入报告编号"
+                  style="width: 120px"
+                  v-model="basicInfoData.version"
+                  placeholder="请输入版本"
                 ></el-input>
               </span>
-              <span style="font-weight: bold; margin-left: 3px">
-                版本:{{ basicInfoData.version }}</span
-              >
+            </span>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 基本信息表格 -->
+    <table
+      class="basic-info-table"
+      style="width: 100%; border-collapse: collapse; border: 1px solid #ccc"
+    >
+      <tbody>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >产品名称</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.productName
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >生产批号</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.batchNo
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >规格型号</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px"
+            >{{ basicInfoData.specification }}/{{ basicInfoData.modelType }}</td
+          >
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >灭菌批号</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px"
+            ><span style="flex: 1">
+              <div v-if="isView">
+                {{ basicInfoData.reportNumber1 }}
+              </div>
+              <div v-else>
+                <el-input
+                  v-model="basicInfoData.reportNumber1"
+                  placeholder="请输入报告编号"
+                ></el-input>
+              </div> </span
+          ></td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >产品数量</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px"
+            >{{ basicInfoData.total }}{{ basicInfoData.sampleMeasureUnit }}</td
+          >
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >抽检数量</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px"
+            >{{ basicInfoData.sampleQuantity
+            }}{{ basicInfoData.sampleMeasureUnit }}</td
+          >
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >包装规格</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            basicInfoData.packingSpecification
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >生产日期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-date-picker
+                v-model="basicInfoData.manufactureTime"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期"
+              />
             </div>
-          </el-col>
-        </el-row>
-      </div>
+            <div v-else>{{ basicInfoData.manufactureTime }}</div></td
+          >
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >有效期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-date-picker
+                v-model="basicInfoData.expirationDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期"
+              />
+            </div>
+            <div v-else>{{ basicInfoData.expirationDate || '/' }}</div>
+          </td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >报告日期</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">
+            <div v-if="!isView">
+              <el-date-picker
+                v-model="basicInfoData.reportDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期"
+              />
+            </div>
+            <div v-else>{{ basicInfoData.reportDate }}</div>
+          </td>
+        </tr>
+        <tr>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验依据</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" colspan="3">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.inspectionBasis"
+                placeholder="请输入检验依据"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.inspectionBasis }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
 
-      <!-- 基本信息表格 -->
-      <table
-        class="basic-info-table"
-        style="width: 100%; border-collapse: collapse; border: 1px solid #ccc"
-      >
-        <tbody>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >产品名称</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.productName
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >生产批号</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.batchNo
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >规格型号</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px"
-              >{{ basicInfoData.specification }}/{{
-                basicInfoData.modelType
-              }}</td
-            >
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >灭菌批号</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px"
-              ><span style="flex: 1">
-                <div v-if="isView">
-                  {{ basicInfoData.reportNumber1 }}
-                </div>
-                <div v-else>
-                  <el-input
-                    v-model="basicInfoData.reportNumber1"
-                    placeholder="请输入报告编号"
-                  ></el-input>
-                </div> </span
-            ></td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >产品数量</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px"
-              >{{ basicInfoData.total
-              }}{{ basicInfoData.sampleMeasureUnit }}</td
-            >
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >抽检数量</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px"
-              >{{ basicInfoData.sampleQuantity
-              }}{{ basicInfoData.sampleMeasureUnit }}</td
-            >
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >包装规格</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              basicInfoData.packingSpecification
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >生产日期</td
+    <!-- 检验项目表格 -->
+    <table
+      class="inspection-items-table"
+      style="
+        width: 100%;
+        border-collapse: collapse;
+        border: 1px solid #ccc;
+        margin-bottom: 20px;
+      "
+    >
+      <thead>
+        <tr>
+          <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验项目</th
+          >
+          <th style="border: 1px solid #ccc; padding: 8px">标准要求</th>
+          <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
+            >检验结果</th
+          >
+        </tr>
+      </thead>
+      <tbody>
+        <tr v-for="(item, index) in inspectionItems" :key="index">
+          <td
+            style="
+              width: 150px;
+              border: 1px solid #ccc;
+              padding: 8px;
+              min-height: 37px;
+            "
+            >{{ item.item }}</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px">{{
+            item.standardRegulations
+          }}</td>
+          <td style="width: 150px; border: 1px solid #ccc; padding: 8px">{{
+            item.results
+          }}</td>
+        </tr>
+        <tr>
+          <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
+            >结论</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.conclusion"
+                placeholder="请输入结论"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.conclusion || '' }}</div>
+          </td>
+        </tr>
+        <tr>
+          <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
+            >备注</td
+          >
+          <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
+            <div v-if="!isView">
+              <el-input
+                v-model="basicInfoData.remarks"
+                placeholder="请输入备注"
+              ></el-input>
+            </div>
+            <div v-else>{{ basicInfoData.remarks || '' }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+    <!-- 签名区域 -->
+    <div style="margin-top: 20px">
+      <el-row :gutter="20" style="display: flex; align-items: center">
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >检验员/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
+                <el-input
+                  v-model="basicInfoData.inspector"
+                  placeholder="请输入检验员"
+                  style="width: 140px"
+                ></el-input>
                 <el-date-picker
-                  v-model="basicInfoData.manufactureTime"
+                  v-model="basicInfoData.inspectionTime"
                   type="date"
                   value-format="yyyy-MM-dd"
                   placeholder="选择日期"
+                  style="width: 160px"
                 />
               </div>
-              <div v-else>{{ basicInfoData.manufactureTime }}</div></td
-            >
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >有效期</td
+              <div v-else
+                >{{ basicInfoData.inspector || '' }} /
+                {{ basicInfoData.inspectionTime || '' }}</div
+              >
+            </span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >复核人/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
+                <el-input
+                  v-model="basicInfoData.reviewer"
+                  placeholder="请输入复核人"
+                  style="width: 140px"
+                ></el-input>
                 <el-date-picker
-                  v-model="basicInfoData.expirationDate"
+                  v-model="basicInfoData.reviewTime"
                   type="date"
                   value-format="yyyy-MM-dd"
                   placeholder="选择日期"
+                  style="width: 160px"
                 />
               </div>
-              <div v-else>{{ basicInfoData.expirationDate || '/' }}</div>
-            </td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >报告日期</td
+              <div v-else
+                >{{ basicInfoData.reviewer || '' }} /
+                {{ basicInfoData.reviewTime || '' }}</div
+              >
+            </span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div style="display: flex; align-items: center; margin-bottom: 10px">
+            <span style="font-weight: bold; min-width: 100px"
+              >审核人/日期:</span
             >
-            <td style="border: 1px solid #ccc; padding: 8px">
-              <div v-if="!isView">
+            <span style="flex: 1">
+              <div v-if="!isView" style="display: flex; align-items: center">
+                <el-input
+                  v-model="basicInfoData.checker"
+                  placeholder="请输入审核人"
+                  style="width: 140px"
+                ></el-input>
                 <el-date-picker
-                  v-model="basicInfoData.reportDate"
+                  v-model="basicInfoData.approvedDate"
                   type="date"
                   value-format="yyyy-MM-dd"
                   placeholder="选择日期"
+                  style="width: 160px"
                 />
               </div>
-              <div v-else>{{ basicInfoData.reportDate }}</div>
-            </td>
-          </tr>
-          <tr>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验依据</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px" colspan="3">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.inspectionBasis"
-                  placeholder="请输入检验依据"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.inspectionBasis }}</div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-
-      <!-- 检验项目表格 -->
-      <table
-        class="inspection-items-table"
-        style="
-          width: 100%;
-          border-collapse: collapse;
-          border: 1px solid #ccc;
-          margin-bottom: 20px;
-        "
-      >
-        <thead>
-          <tr>
-            <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验项目</th
-            >
-            <th style="border: 1px solid #ccc; padding: 8px">标准要求</th>
-            <th style="width: 150px; border: 1px solid #ccc; padding: 8px"
-              >检验结果</th
-            >
-          </tr>
-        </thead>
-        <tbody>
-          <tr v-for="(item, index) in inspectionItems" :key="index">
-            <td
-              style="
-                width: 150px;
-                border: 1px solid #ccc;
-                padding: 8px;
-                min-height: 37px;
-              "
-              >{{ item.item }}</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px">{{
-              item.standardRegulations
-            }}</td>
-            <td style="width: 150px; border: 1px solid #ccc; padding: 8px">{{
-              item.results
-            }}</td>
-          </tr>
-          <tr>
-            <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
-              >结论</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.conclusion"
-                  placeholder="请输入结论"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.conclusion || '' }}</div>
-            </td>
-          </tr>
-          <tr>
-            <td style="width: 120px; border: 1px solid #ccc; padding: 8px"
-              >备注</td
-            >
-            <td style="border: 1px solid #ccc; padding: 8px" :colspan="2">
-              <div v-if="!isView">
-                <el-input
-                  v-model="basicInfoData.remarks"
-                  placeholder="请输入备注"
-                ></el-input>
-              </div>
-              <div v-else>{{ basicInfoData.remarks || '' }}</div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-      <!-- 签名区域 -->
-      <div style="margin-top: 20px">
-        <el-row :gutter="20" style="display: flex; align-items: center">
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >检验员/日期:</span
-              >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.inspector"
-                    placeholder="请输入检验员"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.inspectionTime"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.inspector || '' }} /
-                  {{ basicInfoData.inspectionTime || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >复核人/日期:</span
-              >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.reviewer"
-                    placeholder="请输入复核人"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.reviewTime"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.reviewer || '' }} /
-                  {{ basicInfoData.reviewTime || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-          <el-col :span="8">
-            <div
-              style="display: flex; align-items: center; margin-bottom: 10px"
-            >
-              <span style="font-weight: bold; min-width: 100px"
-                >审核人/日期:</span
+              <div v-else
+                >{{ basicInfoData.checker || '' }} /
+                {{ basicInfoData.approvedDate || '' }}</div
               >
-              <span style="flex: 1">
-                <div v-if="!isView" style="display: flex; align-items: center">
-                  <el-input
-                    v-model="basicInfoData.checker"
-                    placeholder="请输入审核人"
-                    style="width: 140px"
-                  ></el-input>
-                  <el-date-picker
-                    v-model="basicInfoData.approvedDate"
-                    type="date"
-                    value-format="yyyy-MM-dd"
-                    placeholder="选择日期"
-                    style="width: 160px"
-                  />
-                </div>
-                <div v-else
-                  >{{ basicInfoData.checker || '' }} /
-                  {{ basicInfoData.approvedDate || '' }}</div
-                >
-              </span>
-            </div>
-          </el-col>
-        </el-row>
-      </div>
+            </span>
+          </div>
+        </el-col>
+      </el-row>
     </div>
-    <bpmDetail
-      v-if="activeComp === 'bpm' && processInstanceId"
-      :id="processInstanceId"
-    ></bpmDetail>
-    <template v-slot:footer>
-      <el-button v-if="isView" type="primary" @click="print" v-loading="loading"
-        >打印</el-button
-      >
-      <el-button v-if="!isView" type="primary" @click="save" v-loading="loading"
-        >确认</el-button
-      >
-      <el-button @click="cancel">关闭</el-button>
-    </template>
-  </ele-modal>
+  </div>
 </template>
 
 <script>
-  import {
-    queryInspectionReportData,
-    queryInspectionReportList,
-    generateReport
-  } from '@/api/inspectionReport';
-  import bpmDetail from '@/views/bpm/processInstance/detail.vue';
-
-  import { getCode } from '@/api/login';
-
   export default {
     name: 'QualityReport',
     props: {
       isView: {
         type: Boolean,
         default: false
-      },
-      visible: {
-        type: Boolean,
-        default: false
-      },
-      row: {
-        type: Object,
-        default: () => {}
-      },
-      item: {
-        type: Object,
-        default: () => {}
-      },
-      type: ''
-    },
-    components: {
-      bpmDetail
+      }
     },
+
     data() {
       return {
-        // visible: false,
-        loading: false,
-        currentRow: {}, // 存储当前行数据
-        templateItem: {}, // 存储当前模板项数据
         // 基本信息数据
         basicInfoData: {},
 
         // 检验项目
-        inspectionItems: [],
-        tabOptions: [
-          { key: 'main', name: '业务详情' },
-          { key: 'bpm', name: '流程详情' }
-        ],
-        activeComp: 'main',
-        processInstanceId: '',
-        reportApprovalTaskVos: []
+        inspectionItems: []
       };
     },
-    watch: {
-      visible: {
-        handler: function (val) {
-          console.log('visible~~~', val);
-          if (val) {
-            this.open(this.row, this.item);
-          }
-        },
-        deep: true,
-        immediate: true
-      }
-    },
-    created() {
-      // 页面加载时可以在这里添加数据初始化逻辑
-    },
+
     methods: {
       /* 打开质检报告 */
-      async open(row, item) {
-        this.currentRow = row;
-        this.templateItem = item || row;
-        console.log('currentRow~~~', this.currentRow, this.templateItem);
-        this.processInstanceId = row.reportProcessInstanceId;
-        this.reportApprovalTaskVos = row.reportApprovalTaskVos;
-
-        // this.visible = true;
-        if (this.currentRow.reportTemplateJson?.basicInfoData) {
-          this.basicInfoData =
-            this.currentRow.reportTemplateJson.basicInfoData || {};
-          this.inspectionItems =
-            this.currentRow.reportTemplateJson.inspectionItems || [];
-
-          const reviewTime =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 2
-            ]?.endTime?.split(' ')[0] || '';
-          const approvedDate =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 3
-            ]?.endTime?.split(' ')[0] || '';
-          const reviewer =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
-              ?.approvalUserName || '';
-          const checker =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
-              ?.approvalUserName || '';
-
-          this.$set(
-            this.basicInfoData,
-            'inspectionTime',
-            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewTime',
-            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'approvedDate',
-            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewer',
-            this.basicInfoData.reviewer || reviewer || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'checker',
-            this.basicInfoData.checker || checker || ''
-          );
-        } else {
-          this.getBasicInfo();
-          this.getInspectionItems();
-        }
-      },
-      getBasicInfo() {
-        queryInspectionReportData({
-          id: this.currentRow.id,
-          type: this.type
-        }).then((res) => {
-          this.basicInfoData = res;
-          this.basicInfoData.reportCode = res.reportCode || '';
-          this.basicInfoData.version =
-            this.templateItem.versionSymbol +
-            this.templateItem.bigVersion +
-            this.templateItem.versionMark +
-            this.templateItem.smallVersion;
-          const reviewTime =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 2
-            ]?.endTime?.split(' ')[0] || '';
-          const approvedDate =
-            this.reportApprovalTaskVos?.[
-              this.reportApprovalTaskVos.length - 3
-            ]?.endTime?.split(' ')[0] || '';
-          const reviewer =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 2]
-              ?.approvalUserName || '';
-          const checker =
-            this.reportApprovalTaskVos?.[this.reportApprovalTaskVos.length - 3]
-              ?.approvalUserName || '';
-
-          this.$set(
-            this.basicInfoData,
-            'inspectionTime',
-            this.basicInfoData.inspectionTime?.split(' ')[0] || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewTime',
-            this.basicInfoData.reviewTime?.split(' ')[0] || reviewTime || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'approvedDate',
-            this.basicInfoData.approvedDate?.split(' ')[0] || approvedDate || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'reviewer',
-            this.basicInfoData.reviewer || reviewer || ''
-          );
-          this.$set(
-            this.basicInfoData,
-            'checker',
-            this.basicInfoData.checker || checker || ''
-          );
-          if (!this.basicInfoData.reportNumber) {
-            getCode('quality_Inspection_report_number').then((res) => {
-              this.$set(this.basicInfoData, 'reportNumber', res);
-            });
-          }
-        });
-      },
-      getInspectionItems() {
-        queryInspectionReportList({
-          id: this.currentRow.id,
-          type: this.type
-        }).then((res) => {
-          this.inspectionItems = res;
-        });
+      async init(basicInfoData, inspectionItems) {
+        this.$set(this, 'basicInfoData', basicInfoData);
+        this.$set(this, 'inspectionItems', inspectionItems);
       },
 
-      cancel() {
-        // this.visible = false;
-        this.$emit('update:visible', false);
-      },
       /* 保存编辑 */
-      save() {
-        this.loading = true;
-        this.isView = true;
-
-        this.$nextTick(() => {
-          const printSection = document.getElementById('printSection');
-
-          const params = {
-            id: this.currentRow.id,
-            type: this.type,
-            reportTemplateId: this.templateItem.id,
-            reportTemplateCode:
-              this.templateItem.code || this.templateItem.reportTemplateCode,
-            reportTemplateName:
-              this.templateItem.name || this.templateItem.reportTemplateName,
-            reportTemplateJson: {
-              template: printSection.innerHTML,
-              basicInfoData: this.basicInfoData,
-              inspectionItems: this.inspectionItems
-            }
-          };
-          generateReport(params)
-            .then((res) => {
-              this.loading = false;
-              this.isView = false;
-
-              this.$message({
-                message: '保存成功',
-                type: 'success'
-              });
-              this.$emit('reload');
-              this.cancel();
-              // this.$emit('update:visible', false);
-              // this.visible = false;
-            })
-            .catch((err) => {
-              this.loading = false;
-              this.isView = false;
-
-              this.$message({
-                message: err.message,
-                type: 'error'
-              });
-            });
-        });
-      },
-      /* 打印 */
-      print() {
-        const printSection = document.getElementById('printSection');
-        console.log('printSection', printSection.innerHTML);
-        // 创建打印任务
-        const printWindow = window.open('', '_blank');
-        printWindow.document.open();
-        printWindow.document.write('<html><head><title>打印预览</title>');
-        printWindow.document.write(
-          '<link rel="stylesheet" href="your-stylesheet-url.css" type="text/css" />'
-        );
-        printWindow.document.write('</head><body>');
-        printWindow.document.write(printSection.innerHTML);
-        printWindow.document.write('</body></html>');
-        printWindow.document.close();
-        printWindow.onload = function () {
-          printWindow.print();
-        };
+      getValue() {
+        return this.basicInfoData;
       }
     }
   };

+ 16 - 40
src/views/inspectionWork/components/inspectionWorkList.vue

@@ -41,9 +41,7 @@
       </template>
 
       <template v-slot:sourceCode="{ row }">
-   {{
-              row.qualityPlanCode ? row.qualityPlanCode : row.workOrderCode
-            }}
+        {{ row.qualityPlanCode ? row.qualityPlanCode : row.workOrderCode }}
       </template>
 
       <template v-slot:files="scope">
@@ -284,18 +282,11 @@
       ref="inspectionProjectTaskSendRef"
       @reload="search"
     ></inspectionProjectTaskSend>
-    <component
-      :is="targetComponent"
+    <ReportTemplateWrapper
       ref="targetComponentRef"
-      v-if="targetComponent"
-      :key="targetComponent"
-      :isView="isView"
-      :visible.sync="targetVisible"
-      :row="currentRow"
-      :item="currentItem"
-      @reload="search"
       :type="'0'"
-    ></component>
+      @reload="search"
+    ></ReportTemplateWrapper>
     <mesWorkOrder ref="mesWorkOrderRef"></mesWorkOrder>
     <certificate ref="certificateRef"></certificate>
   </div>
@@ -309,6 +300,7 @@
   import mesWorkOrder from './mesWorkOrder.vue';
   import processSubmitDialog from '@/components/processSubmitDialog/processSubmitDialog.vue';
   import inspectionProjectTaskSend from '@/views/inspectionProjectTask/components/inspectionProjectTaskSend.vue';
+  import ReportTemplateWrapper from '@/views/inspectionReport/components/reportTemplateWrapper.vue';
   import {
     getList,
     removeItem,
@@ -328,8 +320,7 @@
   import tabMixins from '@/mixins/tableColumnsMixin';
   import { getCategoryByCode } from '@/api/main/index';
   import { getQmsReportTemplatePageList } from '@/api/inspectionWork';
-  import inspection_report1 from '@/views/inspectionReport/template/inspection_report1.vue';
-  import inspection_report2 from '@/views/inspectionReport/template/inspection_report2.vue';
+
   import { inspectionProjectStatus } from '@/enum/dict.js';
   import { recordingMethodList } from '@/utils/util.js';
   import certificate from '@/views/certificateManagement/components/certificate.vue';
@@ -344,10 +335,10 @@
       processSubmitDialog,
       addSample,
       inspectionProjectTaskSend,
-      inspection_report1,
-      inspection_report2,
+
       mesWorkOrder,
-      certificate
+      certificate,
+      ReportTemplateWrapper
     },
     props: {
       // 是否只显示我的工单
@@ -360,11 +351,9 @@
       return {
         inspectionProjectStatus,
         cacheKeyUrl: 'qsm-c2e9664a-inspectionWork',
-        targetComponent: null,
-        isView: false,
+
         targetVisible: false,
-        currentRow: {},
-        currentItem: {},
+
         columns: [
           {
             width: 45,
@@ -653,8 +642,7 @@
         transferId: '',
         isReportApproval: 0,
         selection: [],
-        reportTemplateList: [],
-        templateArr: ['inspection_report1', 'ABBCCC']
+        reportTemplateList: []
       };
     },
     created() {
@@ -768,25 +756,13 @@
           });
       },
       generateReportApproval(row, item) {
-        this.targetComponent = item.code;
-        this.isView = false;
-        this.currentRow = row;
-        this.currentItem = item;
-        this.$nextTick(() => {
-          this.targetVisible = true;
-          console.log('targetVisible~~~~', this.targetVisible);
-        });
+        row.reportTemplateCode = item.code;
+        this.$refs.targetComponentRef.open({ row, item }, false);
       },
       async openReport(row) {
         const data = await getDetailById(row.id);
-        this.targetComponent = row.reportTemplateCode;
-        this.isView = true;
-        this.currentRow = row;
-        this.currentRow.reportApprovalTaskVos =
-          data.data.reportApprovalTaskVos || {};
-        this.$nextTick(() => {
-          this.targetVisible = true;
-        });
+        row.reportApprovalTaskVos = data.data.reportApprovalTaskVos || {};
+        this.$refs.targetComponentRef.open({ row, item: {} }, true);
       },
       selectionChangeHandle(val) {
         this.selection = val;

+ 4 - 4
src/views/sample/sampleRecord/components/addSample.vue

@@ -830,8 +830,8 @@
       },
 
       handleSampleSubmit() {
-        // this.$refs.ruleForm.validate((valid) => {
-        // if (valid) {
+        this.$refs.form.validate((valid) => {
+        if (valid) {
         let params = {
           conditionType: this.form.conditionType,
           quantity: this.form.quantity,
@@ -842,8 +842,8 @@
           (el) => el.id == this.form.packingUnit
         );
         this.sampleFn(params, specifications);
-        // }
-        // });
+        }
+        });
       },
 
       async sampleFn(data, specifications) {