Browse Source

质检报告 不合格处置

yusheng 2 days ago
parent
commit
106928d286

+ 53 - 0
src/api/bpm/components/qualityReportApproval/qualityReportApproval.js

@@ -40,3 +40,56 @@ export async function getCertifiById(id) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+
+// 根据检测工单id获取清单列表
+export async function queryQualityInventory(data) {
+  const res = await request.post(
+    '/qms/quality_work_order/query_quality_inventory',
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+}
+
+// 根据检测工单id获取检测样品列表
+export async function queryQualitySamplContent(data) {
+  const res = await request.post(
+    '/qms/quality_work_order/query_quality_sampl_content',
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+}
+
+export async function getById(id) {
+  const res = await request.get(`/qms/unqualifiedproducts/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 不合格品台账列表
+ */
+export async function getList(data) {
+  let par = new URLSearchParams(data);
+  const res = await request.get(`/qms/unqualifiedproducts/page?` + par, {});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 生成/修改检测报告
+export async function generateReport(data) {
+  const res = await request.post(
+    `/qms/quality_work_order/generateReport`,
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 198 - 11
src/views/bpm/handleTask/components/qualityReportApproval/detailDialog.vue

@@ -1,28 +1,105 @@
 <template>
   <div class="quality-report-container">
     <div v-if="template">
+      <div class="switch" v-if="businessType?.includes('检测报告单')">
+        <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="reportData.reportCode"
-        :key="reportData.reportCode"
-        :isView="true"
-        :basicInfoData="reportData"
-        :inspectionItems="reportDetail"
+        v-if="businessType?.includes('检测报告单')"
+        v-show="activeComp === 'main'"
+        :is="targetComponent"
+        :key="targetComponent"
+        :row="currentRow"
+        :item="currentItem"
       ></component> -->
-      <div v-html="template"> </div>
+      <div v-html="template" v-show="activeComp === 'main'"> </div>
+      <unqualifiedProduct
+        ref="unqualifiedProductRef"
+        v-show="activeComp == 'unqualifiedList'"
+        @setQualifiedNumber="setQualifiedNumber"
+        :total="basicInfoData.total"
+      ></unqualifiedProduct>
+
+      <div style="margin-top: 10px" v-if="businessType?.includes('检测报告单')">
+        结论:
+        <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>
     </div>
     <browse v-else :url="fileUrl"></browse>
   </div>
 </template>
 
 <script>
+  const defForm = {
+    poList: [],
+    unqualifiedProductsCode: '',
+    sourceCode: '',
+    batchNo: '',
+    brandNum: '',
+    categoryCode: '',
+    categoryId: '',
+    categoryName: '',
+    specification: '',
+    modelType: '',
+    produceRoutingId: '',
+    produceRoutingName: '',
+    taskId: '',
+    taskName: '',
+    quantity: '',
+    measureQuantity: '',
+    measureUnit: '',
+    weight: '',
+    weightUnit: '',
+    qualityType: ''
+  };
   import {
     getDetail,
     getListDetail,
     getDetailById,
+    getList,
     getCertifiById
   } from '@/api/bpm/components/qualityReportApproval/qualityReportApproval';
   import browse from '@/components/jimureport/browse.vue';
-  import { getJmPrintViewUrl } from '@/components/jimureport//api.js';
+  import unqualifiedProduct from './unqualifiedProduct.vue';
+  import { getJmPrintViewUrl } from '@/components/jimureport/api.js';
   import { getToken } from '@/utils/token-util';
   import {
     requestentrustGetById,
@@ -48,10 +125,22 @@
       }
     },
     components: {
-      browse
+      browse,
+      unqualifiedProduct
     },
     data() {
       return {
+        basicInfoData: {},
+        unqualifiedProducts: {
+          ...defForm
+        },
+        inspectionItems: [],
+        form: {},
+        tabOptions: [
+          { key: 'main', name: '业务详情' },
+          { key: 'unqualifiedList', name: '不合格品台账' }
+        ],
+        activeComp: 'main',
         // 质检报告数据
         template: '',
         fileUrl: ''
@@ -63,7 +152,7 @@
     methods: {
       async open() {
         let api = getDetailById;
-        console.log(this.businessType, 'this.businessType');
+
         if (this.businessType?.includes('质检任务单')) {
           api = taskmonadGetById;
         }
@@ -73,20 +162,118 @@
         if (this.businessType?.includes('合格证')) {
           api = getCertifiById;
         }
+
         const detail = await api(this.businessId);
+        this.form = detail.data;
         // this.reportData = detail;
         // this.showEditFlag = true;
         if (detail.data.reportTemplateJson?.template) {
           this.template = detail.data.reportTemplateJson.template;
+
+          this.inspectionItems = detail.data.reportTemplateJson.inspectionItems;
+          this.basicInfoData = detail.data.reportTemplateJson?.basicInfoData;
+          if (this.businessType?.includes('检测报告单')) {
+            this.initUnqualifiedProduct();
+            this.$nextTick(() => {
+              const table = document.querySelector('.inspection-items-table');
+              console.log(table, 'table');
+              if (!table) return;
+
+              // 获取表格主体内的所有行
+              const rows = table.querySelectorAll('tbody tr');
+              for (let row of rows) {
+                const cells = row.querySelectorAll('td');
+                // 遍历当前行的每个 td
+                for (let i = 0; i < cells.length; i++) {
+                  if (cells[i].textContent.trim() === '结论') {
+                    // 找到了“结论”所在的 td,取它后面的兄弟 td
+                    const nextTd = cells[i].nextElementSibling;
+                    if (nextTd) {
+                      // 保存原文本(可选)
+                      const originalText = nextTd.textContent.trim();
+                      // 替换内容为 input,并设置 id
+                      nextTd.innerHTML = `<input class="el-input__inner" style="width: 100%" id="conclusionInput" type="text" value="${originalText}" />`;
+                    }
+                    return; // 找到后结束循环
+                  }
+                }
+              }
+            });
+          }
         } else {
           // 组件挂载时加载数据
           // this.loadReportData();
           // this.loadListDetail();
-          console.log('this.businessCode~~~', this.businessCode);
+
           let url = await getJmPrintViewUrl('qmsqualityinspectionprint');
           this.fileUrl = `${url}?token=${getToken()}&id=${this.businessId}`;
-          console.log('fileUrl~~~', this.fileUrl);
         }
+      },
+
+      async initUnqualifiedProduct() {
+        const data = await getList({
+          sourceCode: this.basicInfoData.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.basicInfoData.code,
+            qualityWorkerId: this.basicInfoData.qualityWorkerId,
+            workOrderId: this.basicInfoData.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;
+        }
+      },
+      getTableValue() {
+        let unqualifiedProducts = this.$refs.unqualifiedProductRef.getValue();
+        if (unqualifiedProducts == 'isNodisposeType') {
+          return unqualifiedProducts;
+        }
+        this.basicInfoData.conclusion =
+          document.getElementById('conclusionInput').value;
+        const params = {
+          id: this.businessId,
+          type:0,
+          reportTemplateId: this.form.reportTemplateId,
+          reportTemplateCode: this.form.reportTemplateCode,
+          reportTemplateName: this.form.reportTemplateName,
+          unqualifiedProducts,
+          reportTemplateJson: {
+            template: this.template,
+            basicInfoData: this.basicInfoData,
+            inspectionItems: this.inspectionItems
+          }
+        };
+        return params;
+      },
+
+      selectResult() {
+        this.$refs.unqualifiedProductRef.selectResult(
+          this.basicInfoData.qualityResults
+        );
       }
     }
   };

+ 299 - 0
src/views/bpm/handleTask/components/qualityReportApproval/edit.vue

@@ -0,0 +1,299 @@
+<template>
+  <ele-modal :visible.sync="visible" :title="title" width="40vw" append-to-body :maxable="true">
+    <div class="title">{{ title == '返工' || title == '返修' ? '原' : '' }}产品信息</div>
+    <el-table :data="poList" border>
+      <el-table-column label="产品名称" align="center" prop="categoryName">
+      </el-table-column>
+      <el-table-column label="产品编码" align="center" prop="categoryCode">
+      </el-table-column>
+      <!-- <el-table-column label="刻码" align="center" prop="engravingCode">
+        </el-table-column> -->
+      <!--      <el-table-column label="规格" align="center" prop="specification">-->
+      <!--      </el-table-column>-->
+      <el-table-column label="数量" align="center" prop="unqualifiedQuantity">
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime">
+      </el-table-column>
+      <el-table-column label="创建人" align="center" prop="reviewerName">
+      </el-table-column>
+      <el-table-column label="入库仓库" align="center" prop="deptId" v-if="title != '返工返修'">
+        <template slot-scope="scope">
+          <el-select v-model="scope.row.deptId">
+            <el-option v-for="item in warehouseList" :key="item.id" :value="item.id" :label="item.name"
+              @click.native="handleChangeDepot(scope.row, item)"></el-option>
+          </el-select>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="title" v-if="title == '返工' || title == '返修'">返工返修产品信息</div>
+    <el-form ref="form" label-width="90px" class="create-form" v-if="title == '返工' || title == '返修'">
+      <el-table :data="newPoList" border height="20vh">
+        <el-table-column label="序号" align="center" width="60">
+          <template slot-scope="scope">
+            <span>{{ scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="产品名称" align="center" prop="productNameNew">
+        </el-table-column>
+        <el-table-column label="产品编码" align="center" prop="productCodeNew">
+        </el-table-column>
+        <!-- <el-table-column label="刻码" align="center" prop="engravingCode">
+        </el-table-column> -->
+        <!-- <el-table-column label="型号" align="center" prop="model">
+        </el-table-column> -->
+        <el-table-column label="规格" align="center" prop="specificationNew">
+        </el-table-column>
+
+        <el-table-column label="数量" align="center" prop="sumNew">
+          <template slot-scope="scope">
+            <el-form-item label-width="0px" :prop="'newPoList.' + scope.$index + '.sumNew'">
+              <el-input v-model.number="scope.row.sumNew" size="small" oninput="value=value.replace(/[^\d]/g,'')"
+                style="width: 100%" placeholder="输入数量" @input="inputNumber(scope.row)"></el-input>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" align="center" width="70">
+          <template slot-scope="scope">
+            <el-link type="danger" :underline="false" @click="handleDeleteItem(scope.$index)">
+              删除
+            </el-link>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+    <div class="add-product" @click="addEquipment" v-if="title == '返工' || title == '返修'">
+      <i class="el-icon-circle-plus-outline"></i>
+    </div>
+
+    <template v-slot:footer>
+      <el-button @click="cancel">取消</el-button>
+
+      <el-button type="primary" @click="save" :loading="loading">
+        提交
+      </el-button>
+    </template>
+
+    <!-- 选择产品
+    <EquipmentDialog ref="equipmentRefs" @choose="confirmChoose" :type="2">
+    </EquipmentDialog> -->
+  </ele-modal>
+</template>
+
+<script>
+// import EquipmentDialog from './EquipmentDialog.vue';
+  import { getWarehouseList } from '@/api/bpm/components/saleManage/saleorder.js';
+
+export default {
+  components: {
+    // EquipmentDialog
+  },
+  data() {
+    return {
+      poList: [],
+      newPoList: [],
+      visible: false,
+      loading: false,
+      title: '',
+      originLong: '',
+      originHeight: '',
+      type: '',
+      warehouseList: []
+    };
+  },
+
+  computed: {},
+  created() {
+    getWarehouseList({ params: { status: 1 } }).then((res) => {
+      this.warehouseList = res;
+    });
+  },
+  methods: {
+    open(row, type) {
+      console.log(row, 'row', type)
+
+      this.visible = true;
+      this.poList = row;
+      this.type = type;
+      this.title = type == 1 ? '返工' : type == 2 ? '返修' : type == 3 ? '报废' : '';
+      // if (
+      //   !row[0].productName.includes('板材') &&
+      //   !row[0].productName.includes('砌块')
+      // ) {
+      //   return;
+      // }
+      this._calcVolume(this.poList[0].specification);
+    },
+    handleChangeDepot(row, item) {
+      row.depotName = item.name;
+    },
+    cancel() {
+      this.visible = false;
+    },
+    // 删除产品
+    handleDeleteItem(index, id) {
+      this.$confirm('确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancleButtonText: '取消',
+        type: 'warning'
+      })
+        .then((res) => {
+          this.newPoList.splice(index, 1);
+        })
+        .catch(() => { });
+    },
+    addEquipment() {
+      this.$refs.equipmentRefs.open();
+    },
+    /* 保存编辑 */
+    save() {
+      let isSumNew = true;
+      let isDepotId = true;
+
+      let data = this.title == '报废' ? this.poList : this.newPoList;
+
+      this.poList.forEach((item) => {
+        if (this.title != '返工' && !item.deptId || this.title == '返修' && !item.deptId) {
+          console.log(item, 'item')
+          isDepotId = false;
+        }
+      });
+      if (!isDepotId) {
+        this.$message.error('请选择入库仓库');
+        return;
+      }
+
+      if (this.newPoList.length == 0) {
+        this.$message.error('产品列表不能为空');
+        return;
+      }
+      this.newPoList.forEach((item) => {
+        if (this.title == '返工' && item.sumNew == '' || this.title == '返修' && item.sumNew == '') {
+          isSumNew = false;
+        }
+      });
+
+      if (!isSumNew) {
+        this.$message.error('数量不能为空');
+        return;
+      }
+      this.$emit('success', { data, type: this.type });
+      this.cancel();
+    },
+    // 封装计算体积方法
+    _calcVolume(string) {
+      let modelArr = string?.split('*');
+      if (modelArr) {
+        let originLong = Number(modelArr[0]);
+        let originWide = Number(modelArr[1]);
+        let originHeight = modelArr[2].substr(0, modelArr[2].indexOf('cm'));
+        this.originLong = originLong;
+        this.originHeight = originHeight;
+        return originLong * originWide * originHeight;
+      }
+    },
+    // 封装计算修补信息规格*块数的总体积
+    _calcModelVSWordcount() {
+      // 计算修补规格体积
+      let cutedVolume = 0;
+      let sumVolume = 0;
+      this.newPoList.map((item) => {
+        if (item.sumNew > 0 && item.specificationNew) {
+          cutedVolume =
+            this._calcVolume(item.specificationNew) * Number(item.sumNew);
+          sumVolume += cutedVolume;
+        }
+      });
+      return sumVolume;
+    },
+    // 输入块数计算规格体积是否超出原规格体积
+    inputNumber(row) {
+      if (
+        !row.productNameNew.includes('板材') &&
+        !row.productNameNew.includes('砌块')
+      ) {
+        return;
+      }
+      // 计算原规格体积
+      let originVolume = 0;
+      let sumVolume = 0;
+      originVolume = this._calcVolume(this.poList[0].specification);
+      console.log(originVolume, 'originVolume');
+      // 计算修补总体积
+      sumVolume = this._calcModelVSWordcount();
+      console.log(sumVolume, 'sumVolume');
+
+      if (sumVolume > originVolume) {
+        row.sumNew = 0;
+        this.$alert('修补规格总体积不能大于原规格体积!');
+      }
+    },
+    // 判断产品规格
+    modelChange(row) {
+      // 判断修补规格高度不能大于原规格高度
+      if (!row.name.includes('板材') && !row.name.includes('砌块')) {
+        return true;
+      }
+      let currentLong = Number(row.specification?.split('*')[0]);
+      let currentHeight = row.specification?.split('*')[2];
+      currentHeight = Number(
+        currentHeight.substr(0, currentHeight.indexOf('cm'))
+      );
+      if (currentLong > this.originLong) {
+        this.$alert('修补规格长度不能大于原规格长度!');
+        return false;
+      }
+      if (currentHeight > this.originHeight) {
+        this.$alert('修补规格高度不能大于原规格高度!');
+        return false;
+      }
+      return true;
+    },
+    // 确定选择
+    confirmChoose(data) {
+      console.log(data, 'data');
+      let list = [];
+      let is = true;
+      if (data.length > 0) {
+        list = JSON.parse(JSON.stringify(data)).map((item) => {
+          is = this.modelChange(item);
+          return {
+            productCodeNew: item.code,
+            productNameNew: item.name,
+            // productUnitWeight: item.netWeight,
+            // weightUnit: item.weightUnit,
+            specificationNew: item.specification,
+            sumNew: ''
+          };
+        });
+        if (!is) {
+          return;
+        }
+        this.newPoList = this.newPoList.concat(list);
+      }
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.basic-details-title {
+  margin: 10px 0;
+}
+
+.title {
+  font-size: 16px;
+  line-height: 45px;
+}
+
+.add-product {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  font-size: 30px;
+  color: #1890ff;
+  margin: 10px 0;
+  cursor: pointer;
+}
+</style>

+ 21 - 11
src/views/bpm/handleTask/components/qualityReportApproval/submit.vue

@@ -1,11 +1,7 @@
 <template>
   <el-col :span="16" :offset="6">
     <el-form label-width="100px" ref="formRef" :model="form">
-      <el-form-item
-        label="审批建议"
-        style="margin-bottom: 20px"
-   
-      >
+      <el-form-item label="审批建议" style="margin-bottom: 20px">
         <el-input
           type="textarea"
           v-model="form.reason"
@@ -66,7 +62,7 @@
     rejectTask,
     cancelTask
   } from '@/api/bpm/task';
-
+  import { generateReport } from '@/api/bpm/components/qualityReportApproval/qualityReportApproval';
   // 流程实例的详情页,可用于审批
   export default {
     name: '',
@@ -83,6 +79,9 @@
       },
       taskDefinitionKey: {
         default: ''
+      },
+      businessType: {
+        default: ''
       }
     },
     data() {
@@ -105,10 +104,15 @@
       },
 
       async handleAudit(status) {
-        // let userInfo = this.userOptions.find(
-        //   (item) => item.id == this.form.userId
-        // );
-
+        if (this.businessType?.includes('检测报告单')) {
+          const data = await this.getTableValue();
+          if (data == 'isNodisposeType') {
+            this.$message.warning('有不合格品未处置,请检查!');
+            return;
+          }
+          await generateReport(data);
+          console.log(data, 'dasdsa');
+        }
         let API = !!status ? approveTaskWithVariables : rejectTask;
         await API({
           id: this.taskId,
@@ -136,7 +140,13 @@
           title: status === 0 ? '驳回' : ''
         });
       },
-
+      getTableValue() {
+        return new Promise((resolve, reject) => {
+          this.$emit('getTableValue', async (data) => {
+            resolve(await data);
+          });
+        });
+      },
       //更多
       handleCommand(command) {
         if (command === 'cancel') {

+ 910 - 0
src/views/bpm/handleTask/components/qualityReportApproval/unqualifiedProduct.vue

@@ -0,0 +1,910 @@
+<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="showBtn">
+          <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>
+    <Edit ref="edit" @success="save" />
+    <ele-modal
+      :visible.sync="addDialogVisible"
+      width="60%"
+      append-to-body
+      title="选择"
+    >
+      <el-table
+        :data="inventoryList"
+        @selection-change="handleAddSelectionChange"
+        row-key="id"
+      >
+        <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="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 './edit.vue';
+  import { getWarehouseList } from '@/api/bpm/components/saleManage/saleorder.js';
+  import dictMixins from '@/mixins/dictMixins';
+
+  import {
+    queryQualitySamplContent,
+    queryQualityInventory,
+    getById
+  } from '@/api/bpm/components/qualityReportApproval/qualityReportApproval';
+  export default {
+    components: {
+      Edit
+    },
+    props: {
+      total: {
+        type: Number,
+        default: 0
+      }
+    },
+    mixins: [dictMixins],
+    data() {
+      return {
+        cacheKeyUrl: 'qsm-c2e9664a-unqualifiedList-detailList',
+        key: '',
+        warehouseList: [],
+        activeComp: 'main',
+        addDialogVisible: false,
+        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: '退货' }
+        ],
+        //来料
+        disposalStatusListType: [
+          {
+            value: 5,
+            label: '让步接收'
+          },
+          {
+            value: 9,
+            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: [],
+        addSelection: []
+      };
+    },
+    computed: {
+      showBtn() {
+        return true;
+      },
+      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 || '';
+        }
+      },
+      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();
+      },
+      add() {
+        this.addDialogVisible = true;
+        this.addSelection = [];
+        if (this.inventoryList.length === 1) {
+          this.singleQuantity = this.inventoryList[0].measureQuantity || 0;
+        }
+      },
+
+      // /* 表格数据源 */
+      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 = '';
+      },
+      // // 处置
+      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 = {};
+        let isNodisposeType = false;
+        if (this.poList.length > 0) {
+          unqualifiedProducts.poList = this.poList.map((item) => {
+            if (!item.disposeType) {
+              isNodisposeType = true;
+            }
+            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 isNodisposeType ? 'isNodisposeType' : 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>

+ 2 - 1
src/views/bpm/handleTask/index.vue

@@ -53,6 +53,7 @@
               :id="listData?.id"
               :taskDefinitionKey="listData?.taskDefinitionKey"
               :fromUser="processInstance.startUser?.nickname"
+              :businessType="listData?.businessType"
               @handleAudit="handleAudit"
               @getTableValue="getTableValue"
               @handleUpdateAssignee="handleUpdateAssignee(item)"
@@ -350,7 +351,7 @@
           businessId: '', // 业务id
           businessCode: '', //业务编码
           taskDefinitionKey: '',
-          businessType:'',
+          businessType: '',
           taskId: '' //任务编码
         },