Browse Source

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

lucw 7 months ago
parent
commit
b0ad73f7fa

+ 25 - 0
src/api/bpm/task.js

@@ -220,6 +220,31 @@ export async function updateNotifyMessageReadByIdAPI(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
+export async function queryTodo(query) {
+  const res = await request({
+    url: '/qms/quality_plan/queryTodo',
+    method: 'get',
+    params: query
+  });
+  if (res.data.code == 0) {
+    console.log(res);
+    console.log(res.data.data.planNum);
+    store.dispatch('user/setMenuBadge', {
+      path: '/inspectionPlan',
+      value: res.data.data.planNum || 0,
+      color: 'danger'
+    });
+
+    store.dispatch('user/setMenuBadge', {
+      path: '/inspectionWork',
+      value: res.data.data.workOrderNum || 0,
+      color: 'danger'
+    });
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
 //工作流自定义表单集合
 export async function getBpmCustomFormPage(query) {
   const res = await request({

+ 8 - 0
src/api/produce/workPlan.js

@@ -50,3 +50,11 @@ export async function planDetails(id) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+//转派
+export async function transferQualityWork(data) {
+  const res = await request.post('/qms/quality_work_order/transfer', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+}

+ 3 - 0
src/components/processSubmitDialog/processSubmitDialog.vue

@@ -3,11 +3,14 @@
     custom-class="ele-dialog-form long-dialog-form"
     :centered="true"
     :visible="processSubmitDialogFlag"
+    v-if="processSubmitDialogFlag"
     title="提交审核"
     append-to-body
     :close-on-click-modal="false"
     width="50%"
     :before-close="cancel"
+    :maxable="true"
+    :resizable="true"
   >
     <!--    <el-steps :active="active" align-center style="transform: scale(0.8)">-->
     <!--      <el-step title="流程发起"></el-step>-->

+ 7 - 0
src/views/produce/components/feeding/components/batchProductsBom.vue

@@ -204,6 +204,13 @@
             align: 'center',
             showOverflowTooltip: true
           },
+          {
+            minWidth: 120,
+            prop: 'categoryCode',
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           {
             minWidth: 120,
             prop: 'brandNu',

+ 9 - 1
src/views/produce/components/feeding/components/instanceBom.vue

@@ -148,9 +148,17 @@
               label: '序号',
               fixed: 'left'
             },
+            // {
+            //   minWidth: 120,
+            //   prop: 'code',
+            //   label: '编码',
+            //   align: 'center',
+            //   fixed: 'left',
+            //   showOverflowTooltip: true
+            // },
             {
               minWidth: 120,
-              prop: 'code',
+              prop: 'categoryCode',
               label: '编码',
               align: 'center',
               fixed: 'left',

+ 8 - 1
src/views/produce/components/jobBooking/components/batchPackagingGrouping.vue

@@ -572,9 +572,16 @@
             fixed: 'left'
           },
           areaCodeColumns,
+          // {
+          //   minWidth: 120,
+          //   prop: 'code',
+          //   label: '编码',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
           {
             minWidth: 120,
-            prop: 'code',
+            prop: 'categoryCode',
             label: '编码',
             align: 'center',
             showOverflowTooltip: true

+ 8 - 1
src/views/produce/components/jobBooking/components/batchSemiProductJobBom.vue

@@ -919,9 +919,16 @@
             fixed: 'left'
           },
           // areaCodeColumns,
+          // {
+          //   minWidth: 120,
+          //   prop: 'code',
+          //   label: '编码',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
           {
             minWidth: 120,
-            prop: 'code',
+            prop: 'categoryCode',
             label: '编码',
             align: 'center',
             showOverflowTooltip: true

+ 8 - 1
src/views/produce/components/jobBooking/components/semiProductJobBom.vue

@@ -758,9 +758,16 @@
             fixed: 'left'
           },
           // areaCodeColumns,
+          // {
+          //   minWidth: 120,
+          //   prop: 'code',
+          //   label: '编码',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
           {
             minWidth: 120,
-            prop: 'code',
+            prop: 'categoryCode',
             label: '编码',
             align: 'center',
             showOverflowTooltip: true

+ 46 - 9
src/views/produce/components/outsourcing/outsourceList.vue

@@ -7,10 +7,14 @@
     <div class="card_box">
       <el-descriptions>
         <el-descriptions-item label="委外名称">{{
-          outObj.name
+          outsourceData.name
         }}</el-descriptions-item>
         <el-descriptions-item label="委外类型">{{
-          outObj.type == 4 ? '带料委外' : '不带料委外'
+          outsourceData.type == 4 ? '带料委外' : '不带料委外'
+        }}</el-descriptions-item>
+
+        <el-descriptions-item label="委外数量">{{
+          outsourceData.formedNumLast
         }}</el-descriptions-item>
         <!-- <el-descriptions-item label="直接入库">{{ outObj.isInWarehouse == 1 ? '是' : '否' }}</el-descriptions-item> -->
         <el-descriptions-item label="直接入库">{{ '是' }}</el-descriptions-item>
@@ -128,6 +132,8 @@
             style="width: 100%; margin-top: 10px"
             stripe
             border
+            @select="handleRowSelect"
+            @select-all="handleSelectAll"
             @selection-change="selectionPickOut"
           >
             <el-table-column align="center" type="selection" width="55">
@@ -524,18 +530,19 @@
         // 	.clientEnvironmentId, // *1 主环境-601环境   2 soll-索尔环境    3 tg-碳谷环境
 
         seletedAll: false, //全选状态
-        checkListLen: 0,
 
         warehouseList: [],
         pickOutInListSelect: [],
         selectionIds: [],
-        newStepsList: []
+        newStepsList: [],
+        outsourceData: {}
       };
     },
 
     created() {
       // EventBus.$on('outEvent', this.handleEvent);
       // this.outsourceMaterialFn()
+      this.outsourceData = this.deepCopy(this.outObj);
     },
 
     computed: {
@@ -578,8 +585,10 @@
               it.feedQuantity = 1;
               it.categoryId = it.id;
               it.newWeight = it.weight;
+              it.checked = true;
               this.pickOutInList.push(this.deepCopy(it));
             });
+            this.changNumber(this.pickOutInList);
             this.selectionData();
           } else {
             if (item.length) {
@@ -664,6 +673,8 @@
 
         this.standardOutputList = res.standardOutputList;
 
+        this.changNumber(this.pickOutInList);
+
         // let param = {
         // 	taskId: this.outObj.taskId,
         // 	taskIds: this.outObj.taskIds,
@@ -697,6 +708,27 @@
         });
       },
 
+      changNumber(list) {
+        let total = 0;
+        if (list && list.length != 0) {
+          total = list.reduce(
+            (acc, pro) =>
+              acc + (pro.checked ? Number(pro.feedQuantity || 0) : 0),
+            0
+          );
+        }
+
+        this.outsourceData.formedNumLast = total;
+      },
+
+      handleRowSelect(selection, row) {
+        this.changNumber(selection);
+      },
+
+      handleSelectAll(selection) {
+        this.changNumber(selection);
+      },
+
       inputNum(item, index) {
         if (item.feedQuantity) {
           const totalWeight = Number(item.feedQuantity) * Number(item.weight);
@@ -706,14 +738,16 @@
           this.$set(this.pickOutInList[index], 'newWeight', item.weight);
           this.$forceUpdate();
         }
+
+        this.changNumber(this.pickOutInList);
       },
 
       // 仓库
-      getWarehouseFn() {
-        getWarehouseList().then((res) => {
-          this.warehouseList = res;
-        });
-      },
+      // getWarehouseFn() {
+      //   getWarehouseList().then((res) => {
+      //     this.warehouseList = res;
+      //   });
+      // },
 
       deleteData(item, index) {
         this.pickOutInList.splice(index, 1);
@@ -779,6 +813,7 @@
       },
       selectionPickOut(val) {
         this.pickOutInListSelect = val;
+        this.changNumber(val);
       },
 
       deleteOutput(index) {
@@ -796,8 +831,10 @@
           item.isSelection = '1';
           item.categoryId = item.id;
           item.newWeight = item.weight;
+          item.checked = true;
           this.pickOutInList.push(this.deepCopy(item));
           this.selectionData();
+          this.changNumber(this.pickOutInList);
           this.bomMaterialList.splice(index, 1);
           this.$forceUpdate();
         } else {

+ 1 - 1
src/views/produce/components/warehousing/components/detailsBom.vue

@@ -364,7 +364,7 @@
           },
           {
             minWidth: 120,
-            prop: 'extInfo.batchNo',
+            prop: 'batchNo',
             label: '批次号',
             align: 'center',
             showOverflowTooltip: true

+ 974 - 0
src/views/produce/components/workPlan/components/addSample.vue

@@ -0,0 +1,974 @@
+<template>
+  <ele-modal
+    :visible.sync="visible"
+    title="取样"
+    width="80%"
+    append-to-body
+    :maxable="true"
+  >
+    <el-form
+      ref="form"
+      :model="form"
+      :rules="rules"
+      label-width="120px"
+      class="el-form-box"
+    >
+      <header-title title="基本信息"></header-title>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="质检工单编码:" prop="code">
+            <el-input disabled v-model="form.code" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="质检工单名称:" prop="name">
+            <el-input disabled v-model="form.name" placeholder=" " />
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="8">
+          <el-form-item label="来源单号:" prop="sourceCode">
+            <el-input disabled v-model="form.sourceCode" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="类型:" prop="qualityType">
+            <DictSelection
+              dictName="质检计划类型"
+              v-model="form.qualityType"
+              disabled
+            ></DictSelection>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="编码:" prop="productCode">
+            <el-input disabled v-model="form.productCode" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="名称:" prop="productName">
+            <el-input disabled v-model="form.productName" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="批次号:" prop="batchNo">
+            <el-input disabled v-model="form.batchNo" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="规格:" prop="specification">
+            <el-input disabled v-model="form.specification" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="型号:" prop="modelType">
+            <el-input disabled v-model="form.modelType" placeholder=" " />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="牌号:" prop="brandNo">
+            <el-input disabled v-model="form.brandNo" placeholder=" " />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <header-title title="来源清单"></header-title>
+      <ele-pro-table
+        ref="sourceTable"
+        :columns="tableColumns"
+        :datasource="datasource"
+        :initLoad="false"
+        :needPage="false"
+        height="400px"
+        full-height="calc(100vh - 120px)"
+        :selection.sync="selection"
+      ></ele-pro-table>
+      <header-title title="取样信息"> </header-title>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="质检方式:" prop="qualityMode">
+            <DictSelection
+              dictName="取样类型"
+              v-model="form.qualityMode"
+            ></DictSelection>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="检验方法:" prop="sampleQuantity">
+            <el-select
+              style="width: 100%"
+              v-model="form.sampleQuantity"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in sampleQuantityList"
+                :label="item.label"
+                :value="item.value"
+                :key="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="form.qualityMode == '2'">
+        <el-col :span="8">
+          <el-form-item label="取样:" prop="sampleNumber">
+            <el-select
+              style="width: 100%"
+              v-model="form.conditionType"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in sampleNumberList"
+                :label="item.label"
+                :value="item.value"
+                :key="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="16">
+          <el-row>
+            <el-col :span="6" v-if="form.conditionType == 2">
+              <el-form-item prop="measureQ">
+                <el-input
+                  v-model="form.measureQ"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6" v-if="form.conditionType == 2">
+              <el-form-item prop="sampleUnit" label-width="0">
+                <DictSelection
+                  dictName="计量单位"
+                  clearable
+                  v-model="form.sampleUnit"
+                  filter-placeholder="请输入计量单位搜索"
+                  @change="changeSamUnit"
+                ></DictSelection>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8" v-if="form.conditionType == 2">
+              <el-form-item prop="portion" label="数量">
+                <el-input
+                  v-model="form.portion"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="10" v-if="form.conditionType == 1">
+              <el-form-item prop="portion" label="数量">
+                <el-input
+                  v-model="form.portion"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="10" v-if="form.conditionType == 1">
+              <el-form-item prop="packingUnit" label="单位">
+                <el-select v-model="form.packingUnit" placeholder="请选择">
+                  <el-option
+                    v-for="item in packingSpecificationOption"
+                    :key="item.id"
+                    :label="item.conversionUnit"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col
+              :span="4"
+              style="text-align: right"
+              v-if="form.conditionType == 2"
+            >
+              <el-button
+                type="primary"
+                size="mini"
+                @click="handleSampleSubmit"
+                style="margin-right: 12px"
+                >确认</el-button
+              >
+            </el-col>
+            <el-col
+              :span="4"
+              style="text-align: right"
+              v-if="form.conditionType == 1"
+            >
+              <el-button
+                type="primary"
+                size="mini"
+                @click="handleSampleSubmit"
+                style="margin-right: 12px"
+                >确认</el-button
+              >
+            </el-col>
+          </el-row>
+        </el-col>
+      </el-row>
+      <header-title title="样品信息"></header-title>
+      <ele-pro-table
+        ref="showSampleListTable"
+        :columns="tableColumns1"
+        :datasource="sampleList"
+        :needPage="false"
+        height="400px"
+        full-height="calc(100vh - 120px)"
+      ></ele-pro-table>
+    </el-form>
+
+    <template v-slot:footer>
+      <el-button type="primary" @click="save()" v-lodading="loading"
+        >确认</el-button
+      >
+
+      <el-button @click="cancel">关闭</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+  const defForm = {
+    code: '', //编码
+    name: '', //名称
+    conditionType: '',
+    measureQ: '',
+    sampleUnit: '',
+    portion: ''
+  };
+  import {
+    queryQualityInventory,
+    queryQualityTempleContent
+  } from '@/api/inspectionWork';
+  import { getCodeList } from '@/api/login';
+  export default {
+    components: {},
+    data() {
+      return {
+        form: { ...defForm },
+        visible: false,
+        loading: false,
+        rules: {
+          name: [
+            { required: true, message: '名称不能为空', trigger: 'change' }
+          ],
+          factoriesId: [
+            { required: true, message: '请选择工厂', trigger: 'change' }
+          ],
+          bomId: [
+            { required: true, message: '请选择BOM版本', trigger: 'change' }
+          ],
+          bomCategory: [
+            { required: true, message: '请选择BOM类型', trigger: 'change' }
+          ],
+          produceRoutingId: [
+            { required: true, message: '请选择工艺路线', trigger: 'change' }
+          ],
+          code: [{ required: true, message: '编码不能为空', trigger: 'change' }]
+        },
+        sampleQuantityList: [
+          { label: '依次检验', value: '1' },
+          { label: '分别检验', value: '2' }
+        ],
+        sampleNumberList: [
+          { label: '取整样', value: '1' },
+          { label: '取小样', value: '2' }
+        ],
+        selection: [],
+        tableColumns1: [
+          {
+            label: '样品编码',
+            prop: 'sampleCode',
+            width: '200',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            label: '编码',
+            prop: 'categoryCode',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            label: '名称',
+            prop: 'categoryName',
+            align: 'center'
+          },
+          { label: '批次号', prop: 'batchNo', align: 'center' },
+          { label: '发货条码', prop: 'barcodes', align: 'center' },
+          { label: '包装编码', prop: 'packageNo', align: 'center' },
+          { label: '包装数量', prop: 'packingQuantity', align: 'center' },
+          { label: '包装单位', prop: 'packingUnit', align: 'center' },
+          { label: '计量数量', prop: 'measureQuantity', align: 'center' },
+          { label: '计量单位', prop: 'measureUnit', align: 'center' },
+          {
+            label: '供应商名称',
+            prop: 'supplierName',
+            align: 'center',
+            width: '120'
+          },
+          {
+            label: '供应商代号',
+            prop: 'supplierCode',
+            align: 'center',
+            width: '120'
+          },
+          {
+            label: '物料代号',
+            prop: 'materielDesignation',
+            align: 'center',
+            slot: 'materielDesignation',
+            width: '120'
+          },
+          {
+            label: '客户代号',
+            prop: 'clientCode',
+            align: 'center',
+            slot: 'clientCode',
+            width: '120'
+          },
+          {
+            label: '刻码',
+            prop: 'engrave',
+            align: 'center',
+            slot: 'engrave',
+            width: '120'
+          },
+          {
+            label: '机型',
+            prop: 'modelKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '颜色',
+            prop: 'colorKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '重量',
+            prop: 'weight',
+            align: 'center',
+            slot: 'weight',
+            width: '120'
+          },
+          {
+            label: '重量单位',
+            prop: 'weightUnit',
+            align: 'center',
+            width: 100
+          },
+          { label: '仓库', prop: 'warehouseName', align: 'center', width: 100 },
+          { label: '货区', prop: 'areaName', align: 'center' },
+          { label: '货架', prop: 'goodsShelfName', align: 'center' },
+          { label: '货位', prop: 'goodsAllocationName', align: 'center' },
+          { label: '生产日期', prop: 'productionDate', align: 'center' },
+          { label: '采购日期', prop: 'purchaseDate', align: 'center' }
+        ],
+        tableColumns: [
+          {
+            columnKey: 'selection',
+            type: 'selection',
+            width: 45,
+            align: 'center'
+          },
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            label: '编码',
+            prop: 'categoryCode',
+            width: 150,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '名称',
+            prop: 'categoryName',
+            width: '150',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            label: '批次号',
+            prop: 'batchNo',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            label: '发货条码',
+            prop: 'barcodes',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '包装编码',
+            prop: 'packageNo',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          { label: '包装数量', prop: 'packingQuantity', align: 'center' },
+          { label: '包装单位', prop: 'packingUnit', align: 'center' },
+
+          { label: '计量数量', prop: 'measureQuantity', align: 'center' },
+          { label: '计量单位', prop: 'measureUnit', align: 'center' },
+          { label: '物料代号', prop: 'materielDesignation', align: 'center' },
+          { label: '客户代号', prop: 'clientCode', align: 'center' },
+          {
+            label: '供应商名称',
+            prop: 'supplierName',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            label: '供应商代号',
+            prop: 'supplierCode',
+            align: 'center',
+            width: '120',
+            showOverflowTooltip: true
+          },
+          { label: '刻码', prop: 'engrave', align: 'center' },
+          {
+            label: '机型',
+            prop: 'modelKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '颜色',
+            prop: 'colorKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          { label: '重量', prop: 'weight', align: 'center' },
+          { label: '重量单位', prop: 'weightUnit', align: 'center' },
+          {
+            label: '仓库',
+            prop: 'warehouseName',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          { label: '货区', prop: 'areaName', align: 'center' },
+          { label: '货架', prop: 'goodsShelfName', align: 'center' },
+          { label: '货位', prop: 'goodsAllocationName', align: 'center' },
+          {
+            label: '生产日期',
+            prop: 'productionDate',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            label: '采购日期',
+            prop: 'purchaseDate',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          }
+        ],
+        packingSpecificationOption: [],
+        sampleList: [],
+        schemeList: []
+      };
+    },
+
+    computed: {},
+    created() {},
+    methods: {
+      async open(row) {
+        this.visible = true;
+        row.sourceCode = row.qualityPlanCode || row.workOrderCode;
+        this.form = row;
+        this.queryQualityTempleContent();
+        this.$nextTick(() => {
+          this.$refs.sourceTable.reload({
+            page: 1,
+            where: { qualityWorkerId: row.id }
+          });
+        });
+      },
+      async queryQualityTempleContent() {
+        const res = await queryQualityTempleContent({
+          qualityWorkerId: this.form.id,
+          page: 1,
+          size: 10000
+        });
+        this.schemeList = res.list;
+      },
+      cancel() {
+        this.form = {
+          ...defForm
+        };
+        this.schemeList = [];
+        this.visible = false;
+      },
+      async datasource({ page, limit, where }) {
+        const res = await queryQualityInventory({
+          ...where,
+          pageNum: page,
+          size: -1
+        });
+        if (res.list.length == 0) {
+          return res;
+        }
+
+        let o = res.list[0];
+        let listArr = [];
+        if (o.measureUnit) {
+          listArr.push({
+            packageCellTotal: 1,
+            conversionUnit: o.measureUnit,
+            id: '111'
+          });
+        }
+        if (o.packingUnit) {
+          listArr.push({
+            packageCellTotal: o.measureQuantity - 0,
+            conversionUnit: o.packingUnit,
+            id: '222'
+          });
+        }
+
+        res.list.map((el) => {
+          el.weightProportion = el.weight
+            ? (el.weight / el.measureQuantity).toFixed(4)
+            : 0;
+          el.weightProportion = el.weightProportion - 0;
+        });
+        this.packingSpecificationOption = listArr;
+        return res;
+      },
+
+      handleSampleSubmit() {
+        // this.$refs.ruleForm.validate((valid) => {
+        // if (valid) {
+        let params = {
+          conditionType: this.form.conditionType,
+          measureQ: this.form.measureQ,
+          sampleUnit: this.form.sampleUnit,
+          portion: this.form.portion
+        };
+        let specifications = this.packingSpecificationOption.find(
+          (el) => el.id == this.form.packingUnit
+        );
+        this.sampleFn(params, specifications);
+        // }
+        // });
+      },
+
+      async sampleFn(data, specifications) {
+        this.sampleList = [];
+        if (!this.selection || this.selection.length == 0) {
+          this.$message.warning('请先选择样品!');
+          return;
+        }
+        const measureQ = data.measureQ || 1;
+        const unit = data.sampleUnit;
+        const sampleCount = Number(data.portion);
+        try {
+          if (
+            this.form.inspectionStandards === 1 ||
+            ([2, 3, 4, 5].includes(this.form.inspectionStandards) &&
+              this.form.conditionType == 2)
+          ) {
+            // 新增校验 数量  取整样 ***
+            if (this.form.conditionType == 1) {
+              let isFlag = this.validateSampleQuantity(
+                sampleCount,
+                specifications
+              );
+              if (!isFlag) return;
+            }
+            // ***
+            //抽检计量整样小样或者抽检计重小样
+            if (!this.validateMeasureQuantity(measureQ, unit, sampleCount))
+              return; //取样数量验证
+            if (unit === 'KG' && !this.validateWeight(measureQ, sampleCount))
+              return; // 若计量单位为重量,还需验证总重量是否足够
+            await this.getNewFullSampleList(
+              Math.ceil(sampleCount),
+              // sampleCount,
+              measureQ,
+              unit,
+              specifications
+            );
+            // 这里是取整样 非数量
+          } else if (
+            [2, 3, 4, 5].includes(this.form.inspectionStandards) &&
+            this.form.conditionType == 1
+          ) {
+            console.log('这里是取整样 吗');
+            //抽检取计重取整样
+            if (!this.validateSampleCount(sampleCount, specifications)) return;
+            await this.handleWeightFullSample(sampleCount, specifications);
+          }
+        } catch (error) {
+          console.error('取样处理失败:', error);
+          this.$message.error('取样处理失败');
+        }
+      },
+      validateWeight(measureQ, sampleCount) {
+        let totalMaxPossible = 0;
+        this.selection.forEach((item) => {
+          totalMaxPossible += item.measureQuantity / measureQ;
+        });
+
+        if (totalMaxPossible < sampleCount) {
+          // this.form.portion = totalMaxPossible;
+          this.$message.info(`最大取样条数为${totalMaxPossible}`);
+          return false;
+        }
+
+        let totalWeight = this.selection.reduce(
+          (sum, item) => sum + item.weight,
+          0
+        );
+        const weightUnit = this.selection[0].weightUnit;
+        if (weightUnit === 'G') totalWeight /= 1000;
+
+        if (measureQ * sampleCount > totalWeight) {
+          this.$message.info('取样计量重量不能大于总计量重量');
+          return false;
+        }
+
+        const invalidItem = this.selection.find((item) => {
+          const weight =
+            item.weightUnit === 'G' ? item.weight / 1000 : item.weight;
+          return weight < measureQ;
+        });
+
+        if (invalidItem) {
+          this.$message.info('勾选条目重量小于取样重量');
+          return false;
+        }
+
+        return true;
+      },
+
+      validateMeasureQuantity(measureQ, unit, sampleCount) {
+        if (this.form.conditionType == 2 && measureQ <= 0) {
+          this.$message.info('取样计量数量必须大于0');
+          return false;
+        }
+
+        const totalQuantity = this.selection.reduce(
+          (sum, item) => sum + item.measureQuantity,
+          0
+        );
+        if (
+          (this.selection[0].measureUnit === unit ||
+            this.form.conditionType == 1) &&
+          measureQ * sampleCount > totalQuantity
+        ) {
+          this.$message.info('取样计量数量不能大于总计量数量');
+          return false;
+        }
+
+        const invalidItem = this.selection.find(
+          (item) => item.measureQuantity < measureQ
+        );
+        if (invalidItem) {
+          this.$message.info('条目计量数量小于取样计量数量');
+          return false;
+        }
+
+        return true;
+      },
+
+      // 抽检取整样 校验
+      validateSampleCount(sampleCount, specifications) {
+        // 新增校验 ***
+        let isFlag = this.validateSampleQuantity(sampleCount, specifications);
+        if (!isFlag) {
+          return false;
+        }
+        // ***
+        const chooseNumber = this.selection.reduce((acc, pro) => {
+          return pro.measureQuantity ? acc + Number(pro.measureQuantity) : acc;
+        }, 0);
+        const invalidItem = chooseNumber < sampleCount;
+        // console.log(this.selection, 'this.selection');
+        // const invalidItem = this.selection.find(
+        //   (item) => item.measureQuantity < sampleCount
+        // );
+        if (invalidItem) {
+          this.$message.info('所选的条目计量数量小于取样计量数量');
+          return false;
+        }
+        // ***
+        return true;
+      },
+
+      async handleWeightFullSample(sampleCount, specifications) {
+        const dataList = [];
+        let currentNum = sampleCount - this.selection.length;
+        let currentNum1 = sampleCount;
+        for (const item of this.selection) {
+          const qualitySampleTemplateList = item.qualitySampleTemplateList
+            ?.length
+            ? JSON.parse(JSON.stringify(item.qualitySampleTemplateList))
+            : JSON.parse(
+                JSON.stringify(
+                  this.schemeList.map((item) => {
+                    item['qualityResults'] = 1;
+                    return item;
+                  })
+                )
+              );
+
+          if (sampleCount >= this.selection.length) {
+            dataList.push({
+              ...item,
+              measureQuantity: 1, //作为计量数量
+              sampleCode: await this.getSampleCode(),
+              qualitySampleTemplateList
+            });
+          } else {
+            if (dataList.length < sampleCount) {
+              dataList.push({
+                ...item,
+                measureQuantity: currentNum1 > 1 ? 1 : currentNum1, //作为计量数量
+                sampleCode: await this.getSampleCode(),
+                qualitySampleTemplateList
+              });
+              currentNum1 -= 1;
+            }
+          }
+        }
+        if (sampleCount > this.selection.length) {
+          dataList.forEach((item) => {
+            if (currentNum > 0) {
+              let data = this.selection.find((val) => val.id == item.id);
+              item['measureQuantity'] =
+                data.measureQuantity - 1 - currentNum > 0
+                  ? currentNum + 1
+                  : data.measureQuantity;
+              currentNum = currentNum - (data.measureQuantity - 1);
+            }
+          });
+        }
+        // 更改 从新计算 样品清单 取整样 数据
+        if (specifications && specifications.id) {
+          // let proportion = (obj.weight / obj.measureQuantity).toFixed(2);
+          dataList.map((el) => {
+            el.measureQuantity =
+              el.measureQuantity * specifications.packageCellTotal;
+            el.weight = this.formatNumber(
+              el.measureQuantity,
+              el.weightProportion
+            );
+          });
+        }
+        // 更改
+        this.sampleList = dataList;
+      },
+      // 小数点数据判断
+      formatNumber(a, b, maxDecimals = 4) {
+        if (a == 0 || b == 0 || !a || !b) {
+          return 0;
+        }
+        // 计算乘积
+        const product = a * b;
+        // 转换为固定小数位数,然后转换为数字以去除末尾零
+        const rounded = Number(product.toFixed(maxDecimals));
+        // 转换为字符串检查是否需要显示小数部分
+        const str = rounded.toString();
+        // 如果包含小数点
+        if (str.indexOf('.') !== -1) {
+          // 移除末尾的零和小数点(如果后面没有数字了)
+          return str.replace(/\.?0+$/, '');
+        }
+        return str;
+      },
+      //从来源数组取样到目标数组
+      async getNewFullSampleList(
+        sampleCount,
+        sampleQuantity,
+        sampleUnit,
+        specifications
+      ) {
+        const sourceArray = this.selection;
+        // 检查单位是否匹配
+        const isUnitMismatch =
+          sourceArray.length > 0 && sourceArray[0].measureUnit !== sampleUnit;
+
+        // 创建副本并计算初始可取样数量
+        const items = sourceArray.map((item) => ({
+          ...item,
+          remainingQuantity: isUnitMismatch
+            ? Infinity
+            : item['measureQuantity'], // 剩余可取样数量
+          maxPossible: item['measureQuantity'] / sampleQuantity // 最大取样次数
+        }));
+
+        const result = [];
+        let remainingCount = sampleCount;
+        let count = Math.ceil(remainingCount);
+        const codeList = await this.batchCodes(count);
+        let codeIdx = 0;
+        // 尽可能均匀地从各条目取样
+        while (remainingCount > 0) {
+          // 按剩余可取样比例排序
+          items.sort(
+            (a, b) =>
+              b.remainingQuantity / b['measureQuantity'] -
+              a.remainingQuantity / a['measureQuantity']
+          );
+
+          let distributed = false;
+
+          for (const item of items) {
+            // let values = remainingCount > 1 ? 1 : remainingCount;
+            if (
+              !isUnitMismatch ||
+              (item.remainingQuantity >= sampleQuantity && remainingCount > 0)
+            ) {
+              let qualitySampleTemplateList = [];
+              if (
+                item.qualitySampleTemplateList == undefined ||
+                item.qualitySampleTemplateList == null ||
+                item.qualitySampleTemplateList.length == 0
+              ) {
+                qualitySampleTemplateList = JSON.parse(
+                  JSON.stringify(this.schemeList)
+                );
+              } else {
+                qualitySampleTemplateList = item.qualitySampleTemplateList;
+              }
+              // 添加到结果数组
+              // let sampleCode = await this.getSampleCode();
+              let sampleCode = codeList[codeIdx];
+              if (
+                this.form.conditionType == 1 &&
+                this.form.inspectionStandards == 1
+              ) {
+                result.push({
+                  ...item,
+                  // measureQuantity: values,
+                  measureQuantity: 1,
+                  sampleCode,
+                  qualitySampleTemplateList
+                });
+              } else if (this.form.conditionType == 2) {
+                let weight = (item.weight / item.maxPossible).toFixed(2);
+                result.push({
+                  ...item,
+                  measureQuantity: sampleQuantity,
+                  measureUnit: sampleUnit,
+                  sampleCode,
+                  weight,
+                  qualitySampleTemplateList
+                });
+              }
+              // 更新剩余数量
+              if (!isUnitMismatch) {
+                item.remainingQuantity -= sampleQuantity;
+              }
+              remainingCount = (remainingCount - 1).toFixed(2);
+              codeIdx++;
+              distributed = true;
+            }
+          }
+
+          // 如果没有分配任何取样
+          if (!distributed) {
+            break;
+          }
+        }
+
+        // 判断是不是取整样
+        if (
+          this.form.conditionType == 1 &&
+          specifications &&
+          specifications.id
+        ) {
+          result.map((el) => {
+            el.measureQuantity =
+              el.measureQuantity * specifications.packageCellTotal;
+            el.weight = this.formatNumber(
+              el.measureQuantity,
+              el.weightProportion
+            );
+          });
+        }
+        this.sampleList = result;
+        if (this.sampleList.length > sampleCount) {
+          this.sampleList = this.sampleList.splice(0, sampleCount);
+        }
+      },
+      // 当计量类型 是数量的时候 取整样 校验
+      validateSampleQuantity(sampleCount, specifications) {
+        let packingUnit = this.selection[0].packingUnit?.trim() || '';
+        let totalS = 0;
+        let labelKey =
+          packingUnit == specifications.conversionUnit.trim()
+            ? 'packingQuantity'
+            : 'measureQuantity';
+        let labelName = labelKey == 'packingQuantity' ? '包装数量' : '计量数量';
+        totalS = this.selection.reduce((total, el) => total + el[labelKey], 0);
+
+        if (sampleCount > totalS) {
+          this.$message.info(
+            `所填的条目数量不能超过所选${labelName}总和${totalS}`
+          );
+          return false;
+        }
+        return true;
+      },
+      async batchCodes(count) {
+        if (count <= 0) return;
+        let params = { count };
+        const res = await getCodeList('sample_code', params);
+        return res;
+      },
+      /* 保存编辑 */
+      save() {
+        this.$refs.form.validate((valid) => {
+          if (valid) {
+            this.loading = true;
+            saveOrUpdate(this.form)
+              .then((res) => {
+                this.$message.success('操作成功');
+                this.cancel();
+                this.$emit('done');
+              })
+              .finally(() => {
+                this.loading = false;
+              });
+          }
+        });
+      }
+    }
+  };
+</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>

+ 13 - 1
src/views/produce/components/workPlan/components/baseInfo.vue

@@ -761,7 +761,19 @@
       // 人员选择
       changeExecutor(val) {
         this.$set(this.form, 'qualityIdList', val);
-        this.$forceUpdate();
+
+        if (val.length) {
+          this.form.qualityName = val
+            .map(
+              (item) =>
+                this.executorList.find((item2) => item2.id == item)?.name
+            )
+            .join(',');
+        } else {
+          this.form.qualityName = '';
+        }
+        // this.$set(this.form, 'qualityIdList', val);
+        // this.$forceUpdate();
         // if (val) {
         //   this.form.qualityId = val;
         //   this.form.qualityName = this.executorList.filter(

+ 61 - 0
src/views/produce/components/workPlan/components/newQualityContentTabs.vue

@@ -81,6 +81,7 @@
                       clearable
                       v-model="formData.sampleUnit"
                       size="mini"
+                      filter-placeholder="请输入计量单位搜索"
                       @change="changeSamUnit"
                     >
                     </DictSelection>
@@ -602,6 +603,36 @@
             slot: 'engrave',
             width: '120'
           },
+          {
+            label: '机型',
+            prop: 'modelKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '颜色',
+            prop: 'colorKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '型号',
+            prop: 'modelType',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '规格',
+            prop: 'specification',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '电压等级',
+            prop: 'voltage',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           {
             label: '重量',
             prop: 'weight',
@@ -742,6 +773,36 @@
             width: '120'
           },
           { label: '刻码', prop: 'engrave', align: 'center' },
+          {
+            label: '机型',
+            prop: 'modelKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '颜色',
+            prop: 'colorKey',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '型号',
+            prop: 'modelType',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '规格',
+            prop: 'specification',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '电压等级',
+            prop: 'voltage',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           { label: '重量', prop: 'weight', align: 'center' },
           { label: '重量单位', prop: 'weightUnit', align: 'center' },
           {

+ 479 - 0
src/views/produce/components/workPlan/components/pickOrderList/detailed.vue

@@ -0,0 +1,479 @@
+<template>
+  <div>
+    <ele-modal
+      title="领料列表"
+      :visible.sync="visible"
+      v-if="visible"
+      :before-close="handleClose"
+      :close-on-click-modal="false"
+      :maxable="true"
+      :close-on-press-escape="false"
+      id="formId"
+      append-to-body
+      width="80%"
+    >
+      <div class="tableZ_box">
+        <div class="row">
+          <div class="col">
+            <div class="name">领料时间</div>
+            <div class="content">{{ dataObj.createTime }}</div>
+          </div>
+          <div class="col">
+            <div class="name">领料单号</div>
+            <div class="content">{{ dataObj.code }}</div>
+          </div>
+
+          <div class="col">
+            <div class="name">领料人</div>
+            <div class="content">{{ dataObj.executorName }}</div>
+          </div>
+
+          <div class="col">
+            <div class="name">类型</div>
+            <div class="content" v-if="dataObj.type == 1">自建领料</div>
+            <div class="content" v-if="dataObj.type == 2">工单领料</div>
+            <div class="content" v-if="dataObj.type == 3">委外领料</div>
+          </div>
+        </div>
+      </div>
+
+      <div v-for="(item, index) in dataObj.orderInfoList" :key="index">
+        <ele-pro-table
+          ref="table"
+          :columns="columns"
+          :datasource="item.arr"
+          cache-key="detailed"
+          highlight-current-row
+          :need-page="false"
+          @fullscreen-change="fullscreenChangePick"
+          v-if="item.bomDetailDTOS.length > 0 || item.instanceList.length > 0"
+        >
+          <template v-slot:toolbar>
+            <div class="c_title"> 工单编号: {{ item.code }} </div>
+          </template>
+
+          <template v-slot:empty>
+            <div class="empty">暂无领料数据</div>
+          </template>
+
+          <template v-slot:index="{ row, $index }">
+            {{ $index + 1 }}
+          </template>
+          <template v-slot:rootCategoryLevelName="{ row, $index }">
+            <el-tag>{{ row.rootCategoryLevelName }}</el-tag>
+          </template>
+
+          <template v-slot:warehouseLeaderName="{ row }">
+            <span style="color: #faad14"> {{ row.warehouseLeaderName }} </span>
+          </template>
+
+          <template v-slot:demandQuantity="{ row }">
+            {{ row.demandQuantity }} {{ row.unit }}
+          </template>
+
+          <template v-slot:specification="{ row }">
+            <span>{{
+              row.specification ? row.specification : row.specifications
+            }}</span>
+          </template>
+        </ele-pro-table>
+      </div>
+      <div class="card_box" v-if="outboundDetailList.length != 0">
+        <div class="rx-bc">
+          <div class="item_box rx-bc">
+            <div class="time">出库单详情 </div>
+          </div>
+        </div>
+        <ele-pro-table
+          ref="table"
+          :columns="columnsTwo"
+          :max-height="tableHeightOut"
+          :datasource="outboundDetailList"
+          cache-key="detailed"
+          highlight-current-row
+          :need-page="false"
+          @fullscreen-change="fullscreenChangeOut"
+        >
+          <template v-slot:empty>
+            <div class="empty">暂无出库数据</div>
+          </template>
+
+          <template v-slot:index="{ row, $index }">
+            {{ $index + 1 }}
+          </template>
+
+          <template v-slot:rootCategoryLevelId="{ row, $index }">
+            {{ typeName[Number(row.rootCategoryLevelId)] }}
+          </template>
+
+          <template v-slot:status="{ row }">
+            <el-tag>已出库</el-tag>
+          </template>
+        </ele-pro-table>
+      </div>
+    </ele-modal>
+  </div>
+</template>
+<script>
+  import { getOutboundDetail } from '@/api/produce/picking.js';
+  export default {
+    props: {
+      detailedObj: {}
+    },
+    data() {
+      return {
+        visible: true,
+        dataObj: null,
+        outboundDetailList: [],
+        typeName: {
+          1: '物料',
+          2: '在制品',
+          3: '零部件',
+          4: '生产设备',
+          5: '模具',
+          6: '备品备件',
+          7: '周转车',
+          8: '舟皿',
+          9: '产品',
+          10: '消耗材料',
+          11: '干燥区',
+          12: '质检',
+          13: '包装材料',
+          14: '生产辅助设备',
+          15: '仪表计量设备',
+          16: '办公设备',
+          17: '客户',
+          18: '房屋、建筑物',
+          19: '供应商',
+          20: '工装夹具',
+          22: '工装夹具',
+          23: '半成品',
+          24: '会计科目',
+          25: '费用类型',
+          26: '周转盘',
+          27: '文档',
+          28: '废品',
+          99: '其他'
+        }
+      };
+    },
+
+    computed: {
+      columnsTwo() {
+        return [
+          ...[
+            {
+              width: 55,
+              type: 'index',
+              columnKey: 'index',
+              align: 'center',
+              label: '序号',
+              fixed: 'left'
+            },
+            {
+              minWidth: 120,
+              prop: 'categoryCode',
+              label: '编码',
+              align: 'center',
+              fixed: 'left',
+              showOverflowTooltip: true
+            },
+            {
+              width: 100,
+              prop: 'batchNo',
+              label: '批次号',
+              slot: 'batchNo',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 100,
+              prop: 'rootCategoryLevelId',
+              label: '领料类型',
+              slot: 'rootCategoryLevelId',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              minWidth: 140,
+              prop: 'name',
+              label: '名称',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'feedQuantity',
+              label: '数量',
+              slot: 'feedQuantity',
+              align: 'center'
+            },
+            {
+              width: 150,
+              prop: 'unit',
+              label: '单位',
+              slot: 'unit',
+              align: 'center'
+            },
+            {
+              width: 150,
+              prop: 'modelType',
+              label: '型号',
+              slot: 'modelType',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'specification',
+              label: '规格',
+              slot: 'specification',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'brandNum',
+              label: '牌号',
+              slot: 'brandNum',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'supplierName',
+              label: '供应商',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'status',
+              label: '状态',
+              slot: 'status',
+              align: 'center',
+              showOverflowTooltip: true
+            }
+          ]
+        ];
+      },
+      // 表格列配置
+      columns() {
+        return [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 120,
+            align: 'center',
+            showOverflowTooltip: true,
+            slot: 'index'
+          },
+          {
+            width: 120,
+            prop: 'batchNo',
+            slot: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'rootCategoryLevelName',
+            label: '领料类型',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'categoryCode',
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'categoryName',
+            label: '名称',
+            align: 'center',
+            minWidth: 150,
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'taskName',
+            label: '工序名称',
+            align: 'center',
+            minWidth: 150,
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'demandQuantity',
+            label: '数量',
+            align: 'center',
+            slot: 'demandQuantity',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'warehouseName',
+            label: '领料仓库',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'warehouseLeaderName',
+            slot: 'warehouseLeaderName',
+            label: '审核人',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'brandNo',
+            label: '牌号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'model',
+            label: '型号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            slot: 'specification',
+            label: '规格',
+            align: 'center',
+            showOverflowTooltip: true
+          }
+        ];
+      }
+    },
+
+    methods: {
+      handleClose() {
+        this.$emit('detailedClose');
+      },
+      async getOutboundDetailList() {
+        await getOutboundDetail({
+          pickOrderId: this.dataObj.id
+        }).then((res) => {
+          this.outboundDetailList = res;
+        });
+      }
+    },
+
+    created() {
+      let obj = JSON.parse(this.detailedObj);
+      obj.orderInfoList.forEach((o) => {
+        let _arr = [];
+        _arr = [...o.bomDetailDTOS, ...o.instanceList];
+        _arr = _arr.sort(
+          (a, b) => a.rootCategoryLevelId - b.rootCategoryLevelId
+        );
+        o['arr'] = _arr;
+      });
+
+      this.dataObj = obj;
+      this.getOutboundDetailList();
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .tableZ_box {
+    border: 1px solid #e3e5e5;
+    margin: 6px 0;
+
+    &:last-child {
+      border-bottom: none;
+    }
+
+    .row {
+      width: 100%;
+      display: flex;
+    }
+
+    .col {
+      width: calc(100% / 5);
+      display: flex;
+      align-items: center;
+      min-width: 200px;
+      min-height: 32px;
+      border-bottom: 1px solid #e3e5e5;
+      border-right: 1px solid #e3e5e5;
+
+      &:last-child {
+        border-right: none;
+      }
+
+      .name {
+        display: flex;
+        align-items: center;
+        padding: 4px;
+        width: 80px;
+        height: 100%;
+        background-color: #d0e4d5;
+        color: #000;
+      }
+
+      .content {
+        padding: 4px 6px;
+        color: #000;
+      }
+    }
+
+    .pd6 {
+      padding: 0 6px;
+    }
+  }
+  .tableZ_box {
+    .col {
+      width: calc(100% / 3);
+    }
+  }
+
+  .tag_box {
+    span {
+      display: inline-block;
+      padding: 2px 4px;
+      background: #e6f7ff;
+      margin: 0 4px;
+    }
+  }
+
+  .rx-bc {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 10px;
+  }
+
+  .item_box {
+    margin-top: 5px;
+    margin-bottom: 6px;
+    padding: 0 10px;
+
+    .round {
+      width: 20px;
+      height: 20px;
+      line-height: 20px;
+      border-radius: 50%;
+      background: #157a2c;
+      color: #fff;
+      text-align: center;
+      font-size: 12px;
+    }
+
+    .time {
+      color: #157a2c;
+      font-family: PingFang HK;
+      font-size: 14px;
+      font-style: normal;
+      font-weight: 500;
+      margin-left: 8px;
+    }
+  }
+</style>

+ 140 - 0
src/views/produce/components/workPlan/components/pickOrderList/index.vue

@@ -0,0 +1,140 @@
+<template>
+  <ele-pro-table
+    ref="table"
+    :columns="columns"
+    :datasource="list"
+    tool-class="ele-toolbar-form"
+    :needPage="false"
+    height="calc(100vh - 220px)"
+    full-height="calc(100vh - 120px)"
+  >
+    <template v-slot:code="{ row }">
+      <el-link type="primary" :underline="false" @click="handDetailed(row)">
+        {{ row.code }}
+      </el-link>
+    </template>
+
+    <template v-slot:joinWorkOrderCode="{ row }">
+      <el-tag type="warning" v-if="row.type == 1">自建领料单</el-tag>
+      <div v-else>{{ row.joinWorkOrderCode }}</div>
+    </template>
+
+    <template v-slot:type="{ row }">
+      <el-tag type="warning" v-if="row.type == 1">自建领料</el-tag>
+      <el-tag type="success" v-if="row.type == 2">工单领料</el-tag>
+      <el-tag type="info" v-if="row.type == 3">委外领料</el-tag>
+    </template>
+
+    <template v-slot:status="{ row }">
+      <el-tag
+        :type="['info', 'success', 'warning', 'danger'][row.status]"
+        effect="dark"
+        >{{ statusList[row.status] }}</el-tag
+      >
+    </template>
+    <detailed
+      @detailedClose="detailedClose"
+      v-if="detailedShow"
+      :detailedObj="detailedObj"
+    ></detailed>
+
+    <selfDetailed
+      @detailedClose="detailedClose"
+      v-if="selfDetailedShow"
+      :detailedObj="detailedObj"
+    ></selfDetailed>
+  </ele-pro-table>
+</template>
+
+<script>
+  import detailed from './detailed.vue';
+  import selfDetailed from './selfDetailed.vue';
+  export default {
+    props: {
+      list: {
+        type: Array,
+        default: () => []
+      }
+    },
+    data() {
+      return {
+        detailedShow: false,
+        detailedObj: null,
+        selfDetailedShow: false,
+        statusList: ['未领料', '领料中', '已出库', '已驳回'],
+        columns: [
+          {
+            prop: 'code',
+            slot: 'code',
+            label: '领料单编号',
+            align: 'center',
+            align: 'left'
+          },
+
+          {
+            prop: 'joinWorkOrderCode',
+            slot: 'joinWorkOrderCode',
+            label: '关联工单编号',
+            align: 'center'
+          },
+
+          {
+            prop: 'joinWarehouseName',
+            label: '领料仓库名称',
+            align: 'center'
+          },
+
+          {
+            prop: 'joinReviewerName',
+            label: '关联审核人',
+            align: 'center'
+          },
+
+          {
+            prop: 'executorName',
+            label: '领料人',
+            align: 'center'
+          },
+
+          {
+            prop: 'createTime',
+            label: '领料时间',
+            align: 'center'
+          },
+          {
+            prop: 'type',
+            slot: 'type',
+            label: '类型',
+            align: 'center'
+          },
+          {
+            prop: 'status',
+            slot: 'status',
+            label: '状态',
+            align: 'center',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    components: {
+      detailed,
+      selfDetailed
+    },
+    methods: {
+      handDetailed(row) {
+        this.detailedObj = JSON.stringify(row);
+        if (row.type == 1) {
+          this.selfDetailedShow = true;
+        } else {
+          this.detailedShow = true;
+        }
+      },
+
+      detailedClose() {
+        this.detailedShow = false;
+        this.selfDetailedShow = false;
+      }
+    }
+  };
+</script>

+ 365 - 0
src/views/produce/components/workPlan/components/pickOrderList/selfDetailed.vue

@@ -0,0 +1,365 @@
+<template>
+  <div>
+    <ele-modal
+      title="领料列表"
+      :visible.sync="visible"
+      :before-close="handleClose"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      :maxable="true"
+      width="80%"
+    >
+      <div class="tableZ_box">
+        <div class="row">
+          <div class="col">
+            <div class="name">领料时间</div>
+            <div class="content">{{ dataObj.createTime }}</div>
+          </div>
+          <div class="col">
+            <div class="name">领料单号</div>
+            <div class="content">{{ dataObj.code }}</div>
+          </div>
+
+          <div class="col">
+            <div class="name">领料人</div>
+            <div class="content">{{ dataObj.executorName }}</div>
+          </div>
+
+          <div class="col">
+            <div class="name">类型</div>
+            <div class="content" v-if="dataObj.type == 1">自建领料</div>
+            <div class="content" v-if="dataObj.type == 2">工单领料</div>
+            <div class="content" v-if="dataObj.type == 3">委外领料</div>
+          </div>
+        </div>
+      </div>
+
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="dataObj.detailList"
+        cache-key="detailed"
+        highlight-current-row
+        :need-page="false"
+      >
+        <template v-slot:empty>
+          <div class="empty">暂无领料数据</div>
+        </template>
+
+        <template v-slot:index="{ row, $index }">
+          {{ $index + 1 }} <el-tag>{{ row.rootCategoryLevelName }}</el-tag>
+        </template>
+
+        <template v-slot:demandQuantity="{ row }">
+          {{ row.demandQuantity }} {{ row.unit }}
+        </template>
+
+        <template v-slot:specification="{ row }">
+          {{ row.specification ? row.specification : row.specifications }}
+        </template>
+      </ele-pro-table>
+
+      <div class="card_box" v-if="outboundDetailList.length != 0">
+        <div class="rx-bc">
+          <div class="item_box rx-bc">
+            <div class="time">出库单详情 </div>
+          </div>
+        </div>
+        <ele-pro-table
+          ref="table"
+          :columns="columnsTwo"
+          :datasource="outboundDetailList"
+          cache-key="detailed"
+          highlight-current-row
+          :need-page="false"
+        >
+          <template v-slot:empty>
+            <div class="empty">暂无领料数据</div>
+          </template>
+
+          <template v-slot:index="{ row, $index }">
+            {{ $index + 1 }}
+          </template>
+
+          <template v-slot:status="{ row }">
+            <el-tag>已出库</el-tag>
+          </template>
+        </ele-pro-table>
+      </div>
+    </ele-modal>
+  </div>
+</template>
+<script>
+  export default {
+    props: {
+      detailedObj: {}
+    },
+    data() {
+      return {
+        visible: true,
+        dataObj: null,
+        outboundDetailList: []
+      };
+    },
+
+    computed: {
+      // 表格列配置
+      columns() {
+        return [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 120,
+            align: 'center',
+            showOverflowTooltip: true,
+            slot: 'index'
+          },
+          {
+            width: 100,
+            prop: 'batchNo',
+            label: '批次号',
+            slot: 'batchNo',
+            align: 'center'
+          },
+
+          {
+            prop: 'categoryCode',
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'categoryName',
+            label: '名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'demandQuantity',
+            label: '数量',
+            align: 'center',
+            slot: 'demandQuantity',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'warehouseName',
+            label: '领料仓库',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'warehouseLeaderName',
+            label: '审核人',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'brandNo',
+            label: '牌号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'model',
+            label: '型号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            label: '规格',
+            align: 'center',
+            slot: 'specification',
+            showOverflowTooltip: true
+          }
+        ];
+      },
+      columnsTwo() {
+        return [
+          ...[
+            {
+              width: 55,
+              type: 'index',
+              columnKey: 'index',
+              align: 'center',
+              label: '序号',
+              fixed: 'left'
+            },
+            {
+              minWidth: 120,
+              prop: 'categoryCode',
+              label: '编码',
+              align: 'center',
+              fixed: 'left',
+              showOverflowTooltip: true
+            },
+            {
+              width: 100,
+              prop: 'batchNo',
+              label: '批次号',
+              slot: 'batchNo',
+              align: 'center'
+            },
+            {
+              minWidth: 140,
+              prop: 'name',
+              label: '名称',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'feedQuantity',
+              label: '数量',
+              slot: 'feedQuantity',
+              align: 'center'
+            },
+            {
+              width: 150,
+              prop: 'unit',
+              label: '单位',
+              slot: 'unit',
+              align: 'center'
+            },
+            {
+              width: 150,
+              prop: 'modelType',
+              label: '型号',
+              slot: 'modelType',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'specification',
+              label: '规格',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'brandNum',
+              label: '牌号',
+              slot: 'brandNum',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'supplierName',
+              label: '供应商',
+              align: 'center',
+              showOverflowTooltip: true
+            },
+            {
+              width: 150,
+              prop: 'status',
+              label: '状态',
+              slot: 'status',
+              align: 'center',
+              showOverflowTooltip: true
+            }
+          ]
+        ];
+      }
+    },
+
+    methods: {
+      handleClose() {
+        this.$emit('detailedClose');
+      },
+      async getOutboundDetailList() {
+        await getOutboundDetail({
+          pickOrderId: this.dataObj.id
+        }).then((res) => {
+          this.outboundDetailList = res;
+        });
+      }
+    },
+
+    created() {
+      let obj = JSON.parse(this.detailedObj);
+      this.dataObj = obj;
+      this.getOutboundDetailList();
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .tableZ_box {
+    border: 1px solid #e3e5e5;
+    margin: 6px 0;
+
+    &:last-child {
+      border-bottom: none;
+    }
+
+    .row {
+      width: 100%;
+      display: flex;
+    }
+
+    .col {
+      width: calc(100% / 5);
+      display: flex;
+      align-items: center;
+      min-width: 200px;
+      min-height: 32px;
+      border-bottom: 1px solid #e3e5e5;
+      border-right: 1px solid #e3e5e5;
+
+      &:last-child {
+        border-right: none;
+      }
+
+      .name {
+        display: flex;
+        align-items: center;
+        padding: 4px;
+        width: 80px;
+        height: 100%;
+        background-color: #d0e4d5;
+        color: #000;
+      }
+
+      .content {
+        padding: 4px 6px;
+        color: #000;
+      }
+    }
+
+    .pd6 {
+      padding: 0 6px;
+    }
+  }
+  .tableZ_box {
+    .col {
+      width: calc(100% / 3);
+    }
+  }
+
+  .tag_box {
+    span {
+      display: inline-block;
+      padding: 2px 4px;
+      background: #e6f7ff;
+      margin: 0 4px;
+    }
+  }
+
+  .time {
+    color: #157a2c;
+    font-family: PingFang HK;
+    font-size: 14px;
+    font-style: normal;
+    font-weight: 500;
+    margin-left: 8px;
+  }
+</style>

+ 135 - 0
src/views/produce/components/workPlan/components/transfer.vue

@@ -0,0 +1,135 @@
+<template>
+  <el-dialog
+    :visible.sync="transferVisible"
+    width="35%"
+    @close="close"
+    append-to-body
+  >
+    <el-form ref="form" :model="form" label-width="150px" :rules="rules">
+      <el-form-item label="执行部门:" prop="groupId">
+        <deptSelect v-model="form.groupId" @changeGroup="searchDeptNodeClick" />
+      </el-form-item>
+
+      <el-form-item label="执行人员:" prop="qualityId">
+        <el-select
+          v-model="form.qualityId"
+          @change="changeExecutor"
+          filterable
+          style="width: 100%"
+        >
+          <el-option
+            v-for="item in executorList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="close">取 消 </el-button>
+      <el-button type="primary" @click="consfirm">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+  import deptSelect from '@/components/CommomSelect/dept-select.vue';
+  import { transferQualityWork } from '@/api/produce/workPlan.js';
+  import { getUserPage } from '@/api/system/organization';
+
+  export default {
+    name: 'Transfer',
+    props: {
+      transferVisible: {
+        type: Boolean,
+        default: false
+      },
+      id: {
+        type: String,
+        default: ''
+      }
+    },
+    components: {
+      deptSelect
+    },
+    data() {
+      return {
+        form: {
+          id: '',
+          groupId: '',
+          groupName: '',
+          qualityId: '',
+          qualityName: ''
+        },
+        rules: {
+          groupId: [
+            { required: true, message: '请选择执行部门', trigger: 'change' }
+          ],
+          qualityId: [
+            { required: true, message: '请选择执行人员:', trigger: 'change' }
+          ]
+        },
+        executorList: []
+      };
+    },
+    methods: {
+      searchDeptNodeClick(info, row) {
+        console.log(info, row);
+
+        if (info) {
+          const params = { groupId: info };
+          this.form.groupId = info;
+          this.form.groupName = row.name;
+          this.getUserList(params);
+        } else {
+          this.form.qualityId = null;
+          this.form.qualityName = null;
+          this.executorList = [];
+        }
+      },
+      // 获取审核人列表、巡点检人员
+      async getUserList(params) {
+        try {
+          let data = { pageNum: 1, size: -1 };
+          // 如果传了参数就是获取巡点检人员数据
+          if (params) {
+            data = Object.assign(data, params);
+          }
+          const res = await getUserPage(data);
+          this.executorList = res.list;
+          this.form.qualityId = null;
+          this.form.qualityName = null;
+        } catch (error) {}
+      },
+      changeExecutor(val) {
+        console.log(val);
+
+        if (val) {
+          this.form.qualityId = val;
+          this.form.qualityName = this.executorList.find(
+            (item) => item.id === val
+          ).name;
+        }
+      },
+      consfirm() {
+        this.$refs.form.validate(async (valid) => {
+          if (valid) {
+            await transferQualityWork(this.form);
+            this.$emit('success', this.form.id);
+          }
+        });
+        console.log(this.form);
+      },
+      close() {
+        this.$emit('update:transferVisible', false);
+      }
+    },
+    created() {
+      this.form.id = this.id;
+    }
+  };
+</script>
+
+<style lang="scss" scoped></style>

+ 32 - 6
src/views/produce/components/workPlan/details.vue

@@ -256,8 +256,9 @@
           const api = name == '计划' ? planDetails : getDetailById;
           const result = await api(id);
           console.log(result, 'result');
+          await this.getUserList({ groupId: result.data.groupId });
           const res = result.data;
-          await this.getUserList({ groupId: res.groupId });
+          console.log('res~~~~', res.qualityWorkOrderDetailVO);
           const qualityName = [];
           if (res.qualityId && this.executorList.length != 0) {
             res.qualityId.split(',').forEach((item) => {
@@ -276,13 +277,26 @@
             obj[item.prop] = res[item.prop];
           });
           this.form = obj;
+          this.form.status = res.status;
+          this.form.qualityWorkOrderDetailVO = res.qualityWorkOrderDetailVO;
+          this.accessory = res.accessory;
+          console.log(result, 'result');
+          if (name == '计划') {
+            this.form.total = result.data.productNumber || 0;
+          }
           this.fieldAssign(res, obj);
           this.sampleInfo(res);
+          console.log('this.form~~~~', this.form);
         } catch (err) {
           console.log(err, 'err');
         }
       },
       sampleInfo(res) {
+        this.$set(
+          this.form,
+          'sampleQualifiedNumber',
+          res.sampleQualifiedNumber
+        );
         this.$set(
           this.form,
           'sampleNoQualifiedNumber',
@@ -302,14 +316,26 @@
         this.$set(this.form, 'sampleQuantity', res.sampleQuantity);
         this.$set(this.form, 'sampleWeight', res.sampleWeight);
         this.$set(this.form, 'qualifiedNumber', res.qualifiedNumber);
-        this.$set(this.form, 'noQualifiedNumber', res.noQualifiedNumber);
+        this.$set(this.form, 'noQualifiedNumber', res.sampleNoQualifiedNumber);
         this.$set(this.form, 'remark', res.remark);
-        this.sourceData5 = res.unqualifiedDetail || [];
-        this.sourceData4 = res.qualitySampleList || [];
-        this.sourceData2 = res.qualitySampleList || [];
         this.sourceData3 = res.templateList || [];
         this.sourceData1 = res.qualityInventoryList || [];
-        this.disposeTypeList = res.disposeTypeList || [];
+        let name = this.$route.query.name;
+        // const result = name == '计划' ? res.qualityWorkOrderDetailVO : res;
+        let result = {};
+        if (name == '计划') {
+          this.sourceData4 = res.sampleList || [];
+          this.sourceData2 = res.sampleList || [];
+          result = res.qualityWorkOrderDetailVO
+            ? res.qualityWorkOrderDetailVO
+            : {};
+        } else {
+          result = res;
+          this.sourceData4 = res.qualitySampleList || [];
+          this.sourceData2 = res.qualitySampleList || [];
+        }
+        this.sourceData5 = result.unqualifiedDetail || [];
+        this.disposeTypeList = result.disposeTypeList || [];
       },
       async fieldAssign(res, obj) {
         if (res.qualityMode == 1) {

+ 246 - 120
src/views/produce/components/workPlan/edit.vue

@@ -10,7 +10,19 @@
     width="90%"
   >
     <div class="ele-body">
-      <el-card shadow="never">
+      <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>
+      <el-card shadow="never" v-show="activeComp == 'main'">
         <header-title title="基本信息">
           <el-button @click="cancel">返回</el-button>
           <el-button
@@ -38,6 +50,7 @@
           @changeNumber="changeNumber"
           @quantityAssignment="quantityAssignment"
           @changeInspectionStandardsModel="changeInspectionStandardsModel"
+          @quantityCalculation="quantityCalculation"
         ></base-info>
         <header-title title="样品信息"></header-title>
         <el-form label-width="110px">
@@ -127,9 +140,15 @@
           @getConditionType="getConditionType"
           @countQualityResults="countQualityResults"
           @setSchemeList="setSchemeList"
+          @sampleListChange="sampleListChange"
         />
       </el-card>
 
+      <pickOrderList
+        :list="form.orderInfoList"
+        v-show="activeComp == 'pickOrderListShow'"
+      ></pickOrderList>
+
       <sampleListDialog
         ref="detailRef"
         @handleConfirm="handleConfirm"
@@ -152,6 +171,7 @@
   import baseInfo from './components/baseInfo.vue';
   // import QualityContentTabs from './components/QualityContentTabs.vue';
   import QualityContentTabs from './components/newQualityContentTabs.vue';
+  import pickOrderList from './components/pickOrderList/index.vue'; //领料记录
 
   import { getCode, getCodeList } from '@/api/login';
   import {
@@ -176,7 +196,8 @@
       baseInfo,
       QualityContentTabs,
       sampleListDialog,
-      sampleDisposeDialog
+      sampleDisposeDialog,
+      pickOrderList
     },
     mixins: [dictMixins],
     computed: {
@@ -232,6 +253,11 @@
         };
       };
       return {
+        activeComp: 'main',
+        tabOptions: [
+          { key: 'main', name: '报工' },
+          { key: 'pickOrderListShow', name: '领料记录' }
+        ],
         rowData: null,
         defaultForm,
         sampleDisposeVisble: false,
@@ -283,7 +309,7 @@
             return;
           }
           // 计算重量跟数量
-          this.calculate(newVal);
+          this.setInspectionResults(newVal);
         },
         deep: true,
         immediate: true
@@ -304,6 +330,29 @@
       // }
     },
     methods: {
+      //合格与不合格数变化处理逻辑
+      quantityCalculation(val) {
+        this.$refs.tabsRef.setSampleList(val, this.form.total);
+      },
+      setInspectionResults(list) {
+        this.$nextTick(() => {
+          let qualityResults = this.form.qualityResults;
+          let showArrange = this.$refs.baseInfoRefs.showArrange;
+          if (showArrange == '1') return;
+          if (qualityResults == null || qualityResults == undefined) {
+            for (let i = 0; i < list.length; i++) {
+              let el = list[i];
+              if (el.qualityResults == 2) {
+                this.$set(this.form, 'qualityResults', 2);
+                return;
+              }
+            }
+            this.$set(this.form, 'qualityResults', 1);
+            console.log(list, 'list');
+            console.log(this.form.qualityResults, '质检结果');
+          }
+        });
+      },
       //
       calculate(list) {
         if (list.length == 0) {
@@ -349,20 +398,34 @@
           }
         }
 
-        let resultsTotal = this.form.total - sampleQuantity;
-        if (sampleQuantity == sampleQualifiedNumber) {
-          this.$set(this.form, 'qualifiedNumber', resultsTotal);
-          this.$set(this.form, 'noQualifiedNumber', 0);
-          this.$set(this.form, 'qualificationRate', '100%');
-          this.$set(this.form, 'noQualificationRate', '0');
-          this.$set(this.form, 'qualityResults', 1);
-        } else {
-          this.$set(this.form, 'noQualifiedNumber', resultsTotal);
-          this.$set(this.form, 'qualifiedNumber', 0);
-          this.$set(this.form, 'qualificationRate', '0');
-          this.$set(this.form, 'noQualificationRate', '100%');
-          this.$set(this.form, 'qualityResults', 2);
-        }
+        // let resultsTotal = this.form.total - sampleQuantity;
+        // if (sampleQuantity == sampleQualifiedNumber) {
+        //   this.$set(this.form, 'qualifiedNumber', resultsTotal);
+        //   this.$set(this.form, 'noQualifiedNumber', 0);
+        //   this.$set(this.form, 'qualificationRate', '100%');
+        //   this.$set(this.form, 'noQualificationRate', '0');
+        //   this.$set(this.form, 'qualityResults', 1);
+        // } else {
+        //   this.$set(this.form, 'noQualifiedNumber', resultsTotal);
+        //   this.$set(this.form, 'qualifiedNumber', 0);
+        //   this.$set(this.form, 'qualificationRate', '0');
+        //   this.$set(this.form, 'noQualificationRate', '100%');
+        //   this.$set(this.form, 'qualityResults', 2);
+        // }
+        this.$nextTick(() => {
+          let showArrange = this.$refs.baseInfoRefs.showArrange;
+          if (showArrange != '1' && sampleQuantity == sampleQualifiedNumber) {
+            this.$set(this.form, 'qualificationRate', '100%');
+            this.$set(this.form, 'noQualificationRate', '0');
+            this.$set(this.form, 'qualityResults', 1);
+          }
+
+          if (showArrange != '1' && sampleQuantity != sampleQualifiedNumber) {
+            this.$set(this.form, 'qualificationRate', '0');
+            this.$set(this.form, 'noQualificationRate', '100%');
+            this.$set(this.form, 'qualityResults', 2);
+          }
+        });
 
         this.$set(
           this.form,
@@ -382,7 +445,37 @@
           'sampleNoQualifiedNumber',
           sampleNoQualifiedNumber
         );
+
+        this.quantityAssignment();
       },
+
+      // 计算合格数不合格数
+      quantityAssignment() {
+        let noQualifiedNumber = 0;
+        let qualifiedNumber = 0;
+        let data = this.form;
+        let total = data.total - 0;
+        if (this.form.qualityResults == 2) {
+          noQualifiedNumber = total - (data.sampleQualifiedNumber - 0);
+          qualifiedNumber = total - noQualifiedNumber;
+        } else {
+          qualifiedNumber = total - (data.sampleNoQualifiedNumber - 0);
+          noQualifiedNumber = total - qualifiedNumber;
+        }
+        this.$set(this.form, 'qualifiedNumber', qualifiedNumber);
+        this.$set(this.form, 'noQualifiedNumber', noQualifiedNumber);
+        this.$set(
+          this.form,
+          'qualificationRate',
+          ((qualifiedNumber / total) * 100).toFixed(2) + '%'
+        );
+        this.$set(
+          this.form,
+          'noQualificationRate',
+          ((noQualifiedNumber / total) * 100).toFixed(2) + '%'
+        );
+      },
+
       //切换检验方式
       changeModel(val, flag) {
         this.$refs.tabsRef.tableSelClear();
@@ -1077,6 +1170,12 @@
         }
       },
 
+      sampleListChange(sampleList) {
+        this.$set(this, 'sampleList', sampleList);
+
+        // this.sampleList = sampleList;
+      },
+
       async queryQualitySamplContent() {
         const res = await queryQualitySamplContent({
           qualityWorkerId: this.dataWork.id,
@@ -1106,7 +1205,9 @@
       },
       async queryQualityTempleContent() {
         const res = await queryQualityTempleContent({
-          qualityWorkerId: this.dataWork.id
+          qualityWorkerId: this.dataWork.id,
+          page: 1,
+          size: 10000
         });
         console.log(res, 'resresresres');
         this.schemeList = res.list;
@@ -1380,12 +1481,19 @@
         });
         if (index != null) {
           this.$set(this.sampleList, index, list[0]);
+          this.countQualityResults();
         } else {
+          this.$set(this, 'sampleList', list);
           // this.$set(this.sampleList, null, list);
-          this.sampleList = list;
+          // this.sampleList = list;
           this.calculate(this.sampleList);
         }
         this.activeName = '2';
+
+        this.$refs.baseInfoRefs.quantityCalculation(
+          'noQualifiedNumber',
+          'noSetSampleList'
+        );
         // *** 选完批量质检调用
         // this.countQualityResults();
       },
@@ -1406,10 +1514,26 @@
           return;
         }
 
+        // if (this.schemeList.length != 0) {
+        //   this.sampleList.forEach((item) => {
+        //     if (item.qualitySampleTemplateList.length == 0) {
+        //       item.qualitySampleTemplateList.push(...this.schemeList);
+        //     }
+        //   });
+        // }
         if (this.schemeList.length != 0) {
-          this.sampleList.forEach((item) => {
+          this.sampleList.forEach((item, index) => {
             if (item.qualitySampleTemplateList.length == 0) {
-              item.qualitySampleTemplateList.push(...this.schemeList);
+              let arr = JSON.parse(JSON.stringify(this.schemeList));
+              arr.forEach((el) => {
+                el.qualityResults = item.qualityResults;
+              });
+
+              this.$set(
+                this.sampleList[index],
+                'qualitySampleTemplateList',
+                arr
+              );
             }
           });
         }
@@ -1453,7 +1577,10 @@
         this.sampleList = [];
         this.$refs.tabsRef.tabsChange('1');
         //检验标准 2计重 1计量
-        if (this.form.inspectionStandards == 2 && this.form.qualityMode == 1) {
+        if (
+          [2, 3, 4, 5].includes(this.form.inspectionStandards) &&
+          this.form.qualityMode == 1
+        ) {
           for (let i = 0; i < sData.length; i++) {
             let qualitySampleTemplateList = [];
             if (
@@ -1558,7 +1685,6 @@
                 (this.form.inspectionStandards == 1 ||
                   this.form.inspectionStandards == 2)
               ) {
-                console.log('进来2');
                 let weight = (item.weight / item.maxPossible).toFixed(2);
                 result.push({
                   ...item,
@@ -1844,104 +1970,104 @@
         );
         this.calculate(this.sampleList);
       },
-      calculate(list) {
-        if (list.length == 0) {
-          this.form.sampleQuantity = 0;
-          this.form.sampleWeight = 0;
-        }
-        let sampleQuantity = 0; // 样品数量
-        let sampleWeight = 0; // 样品重量
-        let sampleQualifiedNumber = 0; //  样品合格数
-        let sampleNoQualifiedNumber = 0; //  样品不合格数
-        list.forEach((el) => {
-          sampleQuantity += el.measureQuantity - 0;
-          sampleWeight += el.weight - 0;
-          if (el.qualityResults != 2) {
-            sampleQualifiedNumber += el.measureQuantity - 0;
-          } else {
-            sampleNoQualifiedNumber += el.measureQuantity - 0;
-          }
-        });
-
-        // 计算合格率和不合格率(百分比形式)
-        let sampleQualificationRate = '';
-        let sampleNoQualificationRate = '';
-        if (
-          (sampleQualifiedNumber || sampleQualifiedNumber == 0) &&
-          sampleQuantity !== 0
-        ) {
-          sampleQualificationRate =
-            ((sampleQualifiedNumber / sampleQuantity) * 100).toFixed(2) || '';
-          sampleNoQualificationRate =
-            ((sampleNoQualifiedNumber / sampleQuantity) * 100).toFixed(2) || '';
-        }
-        if (sampleQualificationRate || sampleQualificationRate == '0.00') {
-          if (isNaN(sampleQualificationRate)) {
-            sampleQualificationRate = '0%';
-          } else {
-            sampleQualificationRate = sampleQualificationRate + '%';
-          }
-        }
-        if (sampleNoQualificationRate || sampleNoQualificationRate == '0.00') {
-          if (isNaN(sampleNoQualificationRate)) {
-            sampleNoQualificationRate = '0%';
-          } else {
-            sampleNoQualificationRate = sampleNoQualificationRate + '%';
-          }
-        }
-        this.$nextTick(() => {
-          let showArrange = this.$refs.baseInfoRefs.showArrange;
-          if (showArrange != '1' && sampleQuantity == sampleQualifiedNumber) {
-            this.$set(this.form, 'qualificationRate', '100%');
-            this.$set(this.form, 'noQualificationRate', '0');
-            this.$set(this.form, 'qualityResults', 1);
-          }
-
-          if (showArrange != '1' && sampleQuantity != sampleQualifiedNumber) {
-            this.$set(this.form, 'qualificationRate', '0');
-            this.$set(this.form, 'noQualificationRate', '100%');
-            this.$set(this.form, 'qualityResults', 2);
-          }
-        });
-
-        // this.$set(this.form, 'resultsTotal', resultsTotal);
-        this.$set(
-          this.form,
-          'sampleQualificationRate',
-          sampleQualificationRate
-        );
-        this.$set(
-          this.form,
-          'sampleNoQualificationRate',
-          sampleNoQualificationRate
-        );
-        this.$set(this.form, 'sampleQuantity', sampleQuantity);
-        this.$set(this.form, 'sampleWeight', sampleWeight);
-        this.$set(this.form, 'sampleQualifiedNumber', sampleQualifiedNumber);
-        this.$set(
-          this.form,
-          'sampleNoQualifiedNumber',
-          sampleNoQualifiedNumber
-        );
-        // 数量赋值
-        this.quantityAssignment();
-      },
+      // calculate(list) {
+      //   if (list.length == 0) {
+      //     this.form.sampleQuantity = 0;
+      //     this.form.sampleWeight = 0;
+      //   }
+      //   let sampleQuantity = 0; // 样品数量
+      //   let sampleWeight = 0; // 样品重量
+      //   let sampleQualifiedNumber = 0; //  样品合格数
+      //   let sampleNoQualifiedNumber = 0; //  样品不合格数
+      //   list.forEach((el) => {
+      //     sampleQuantity += el.measureQuantity - 0;
+      //     sampleWeight += el.weight - 0;
+      //     if (el.qualityResults != 2) {
+      //       sampleQualifiedNumber += el.measureQuantity - 0;
+      //     } else {
+      //       sampleNoQualifiedNumber += el.measureQuantity - 0;
+      //     }
+      //   });
+
+      //   // 计算合格率和不合格率(百分比形式)
+      //   let sampleQualificationRate = '';
+      //   let sampleNoQualificationRate = '';
+      //   if (
+      //     (sampleQualifiedNumber || sampleQualifiedNumber == 0) &&
+      //     sampleQuantity !== 0
+      //   ) {
+      //     sampleQualificationRate =
+      //       ((sampleQualifiedNumber / sampleQuantity) * 100).toFixed(2) || '';
+      //     sampleNoQualificationRate =
+      //       ((sampleNoQualifiedNumber / sampleQuantity) * 100).toFixed(2) || '';
+      //   }
+      //   if (sampleQualificationRate || sampleQualificationRate == '0.00') {
+      //     if (isNaN(sampleQualificationRate)) {
+      //       sampleQualificationRate = '0%';
+      //     } else {
+      //       sampleQualificationRate = sampleQualificationRate + '%';
+      //     }
+      //   }
+      //   if (sampleNoQualificationRate || sampleNoQualificationRate == '0.00') {
+      //     if (isNaN(sampleNoQualificationRate)) {
+      //       sampleNoQualificationRate = '0%';
+      //     } else {
+      //       sampleNoQualificationRate = sampleNoQualificationRate + '%';
+      //     }
+      //   }
+      //   this.$nextTick(() => {
+      //     let showArrange = this.$refs.baseInfoRefs.showArrange;
+      //     if (showArrange != '1' && sampleQuantity == sampleQualifiedNumber) {
+      //       this.$set(this.form, 'qualificationRate', '100%');
+      //       this.$set(this.form, 'noQualificationRate', '0');
+      //       this.$set(this.form, 'qualityResults', 1);
+      //     }
+
+      //     if (showArrange != '1' && sampleQuantity != sampleQualifiedNumber) {
+      //       this.$set(this.form, 'qualificationRate', '0');
+      //       this.$set(this.form, 'noQualificationRate', '100%');
+      //       this.$set(this.form, 'qualityResults', 2);
+      //     }
+      //   });
+
+      //   // this.$set(this.form, 'resultsTotal', resultsTotal);
+      //   this.$set(
+      //     this.form,
+      //     'sampleQualificationRate',
+      //     sampleQualificationRate
+      //   );
+      //   this.$set(
+      //     this.form,
+      //     'sampleNoQualificationRate',
+      //     sampleNoQualificationRate
+      //   );
+      //   this.$set(this.form, 'sampleQuantity', sampleQuantity);
+      //   this.$set(this.form, 'sampleWeight', sampleWeight);
+      //   this.$set(this.form, 'sampleQualifiedNumber', sampleQualifiedNumber);
+      //   this.$set(
+      //     this.form,
+      //     'sampleNoQualifiedNumber',
+      //     sampleNoQualifiedNumber
+      //   );
+      //   // 数量赋值
+      //   this.quantityAssignment();
+      // },
       // 计算合格数不合格数
-      quantityAssignment() {
-        let noQualifiedNumber = 0;
-        let qualifiedNumber = 0;
-        let data = this.form;
-        let total = data.total - 0;
-        if (this.form.qualityResults == 2) {
-          noQualifiedNumber = total - (data.sampleQualifiedNumber - 0);
-          qualifiedNumber = total - noQualifiedNumber;
-        } else {
-          qualifiedNumber = total - (data.sampleNoQualifiedNumber - 0);
-          noQualifiedNumber = total - qualifiedNumber;
-        }
-        this.$set(this.form, 'qualifiedNumber', qualifiedNumber);
-        this.$set(this.form, 'noQualifiedNumber', noQualifiedNumber);
-      },
+      // quantityAssignment() {
+      //   let noQualifiedNumber = 0;
+      //   let qualifiedNumber = 0;
+      //   let data = this.form;
+      //   let total = data.total - 0;
+      //   if (this.form.qualityResults == 2) {
+      //     noQualifiedNumber = total - (data.sampleQualifiedNumber - 0);
+      //     qualifiedNumber = total - noQualifiedNumber;
+      //   } else {
+      //     qualifiedNumber = total - (data.sampleNoQualifiedNumber - 0);
+      //     noQualifiedNumber = total - qualifiedNumber;
+      //   }
+      //   this.$set(this.form, 'qualifiedNumber', qualifiedNumber);
+      //   this.$set(this.form, 'noQualifiedNumber', noQualifiedNumber);
+      // },
       closeDispose() {
         this.rowData = null;
         this.sampleDisposeVisble = false;

+ 124 - 10
src/views/produce/components/workPlan/index.vue

@@ -94,6 +94,15 @@
               @click="openEdit('edit', row)"
               >报工</el-link
             >
+
+            <el-link
+              type="primary"
+              :underline="false"
+              v-if="row.status == 0"
+              @click="openTransfer(row.id)"
+              >转派</el-link
+            >
+
             <el-link type="primary" :underline="false" @click="openNumber(row)"
               >合格证</el-link
             >
@@ -104,6 +113,30 @@
               :businessId="row.id"
               businessCode="qmsqualityinspectionprint"
             ></jimureportBrowse>
+
+            <!-- 质检报告审批  -->
+            <el-link
+              v-if="
+                row.status == 1 &&
+                isReportApproval == 1 &&
+                !row.reportApprovalStatus
+              "
+              type="primary"
+              :underline="false"
+              @click="reportApprovalSubmit(row)"
+              >质检报告审批</el-link
+            >
+
+            <el-popconfirm
+              class="ele-action"
+              title="确定要关闭吗?"
+              @confirm="close(row)"
+              v-if="row.status == 0 && row.qualityType == 2"
+            >
+              <template v-slot:reference>
+                <el-link type="warning" :underline="false"> 关闭 </el-link>
+              </template>
+            </el-popconfirm>
             <!-- <el-link type="primary" :underline="false">
             质检报告
           </el-link>-->
@@ -138,9 +171,27 @@
         @closeModel="closeModel"
       />
 
+      <transfer
+        v-if="transferVisible"
+        :transferVisible.sync="transferVisible"
+        @success="transferConfirm"
+        :id="transferId"
+      ></transfer>
+
+      <process-submit-dialog
+        api-fun-name="qmsReportApprovalAPI"
+        :processSubmitDialogFlag.sync="processSubmitDialogFlag"
+        :isCloseRefresh="false"
+        v-if="processSubmitDialogFlag"
+        ref="processSubmitDialogRef"
+        @reload="search"
+      ></process-submit-dialog>
+
       <edit ref="editRef" @close="close" @done="done" />
 
       <detailsOrder ref="detailsRef" />
+
+      <addSample ref="addSampleRef" @reload="search"></addSample>
     </div>
   </ele-modal>
 </template>
@@ -149,6 +200,9 @@
   import search from './components/search.vue';
   import edit from './edit.vue';
   import detailsOrder from './details.vue';
+  import addSample from './components/addSample.vue';
+  import processSubmitDialog from '@/components/processSubmitDialog/processSubmitDialog.vue';
+  import transfer from './components/transfer.vue';
   import jimureportBrowse from '@/components/jimureport/browseModal.vue';
   import {
     getList,
@@ -157,17 +211,23 @@
     verificationQualityInspector
   } from '@/api/inspectionWork';
   import dictMixins from '@/mixins/dictMixins';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import { queryTodo } from '@/api/bpm/task';
   import { getFile } from '@/api/system/file';
   import { getByCode } from '@/api/system/dictionary-data';
+  import { parameterGetByCode } from '@/api/system/dictionary-data';
 
   export default {
-    mixins: [dictMixins],
+    mixins: [dictMixins, tabMixins],
     components: {
       search,
       jimureportBrowse,
       Certificate,
       edit,
-      detailsOrder
+      detailsOrder,
+      processSubmitDialog,
+      addSample,
+      transfer
     },
     data() {
       return {
@@ -375,7 +435,11 @@
         visible: false,
         dataWork: {},
         sourceList: [],
-        listId: []
+        listId: [],
+        transferVisible: false,
+        transferId: '',
+        isReportApproval: 0,
+        processSubmitDialogFlag: false
       };
     },
     created() {
@@ -384,6 +448,7 @@
       // this.requestDict('取样类型');
       this.getTnspectionPlanType();
       this.getQualityMethodCode();
+      this.getCode();
       // this.getQualityModeList('quality_method_code');
       // this.getQualityTypeList('inspection_plan_type');
     },
@@ -468,7 +533,21 @@
       //   const res = await getByCode(code);
       // },
 
+      getCode() {
+        parameterGetByCode({
+          code: 'qms_report_approval'
+        }).then((res) => {
+          this.isReportApproval = res.value;
+        });
+      },
+
       async datasource({ page, limit }) {
+        try {
+          await queryTodo({});
+        } catch (err) {
+          console.error('调用queryTodo失败:', err);
+        }
+
         const res = await getList({
           produceSourceTaskId: this.dataWork.taskId,
           workOrderCodeList: this.listId,
@@ -499,13 +578,13 @@
       },
 
       async openEdit(type, row) {
-        if (type == 'edit') {
-          const code = await verificationQualityInspector(row.id);
-          if (code == '-1') {
-            console.log('不是报工人');
-            return;
-          }
-        }
+        // if (type == 'edit') {
+        //   const code = await verificationQualityInspector(row.id);
+        //   if (code == '-1') {
+        //     console.log('不是报工人');
+        //     return;
+        //   }
+        // }
 
         const req = {
           workOrderId: row.id,
@@ -575,6 +654,31 @@
         }
       },
 
+      reportApprovalSubmit(res) {
+        this.processSubmitDialogFlag = true;
+        this.$nextTick(async () => {
+          let params = {
+            businessId: res.id,
+            businessKey: 'qms_report_approval',
+            formCreateUserId: res.createUserId,
+            variables: {
+              businessCode: res.code,
+              businessName: res.name,
+              businessType: '质检报告单'
+            }
+          };
+          if (this.clientEnvironmentId == 5) {
+            const data = await getCategoryByCode(res.productCode);
+            if (data && data.categoryLevelCodePath?.includes('W3-209')) {
+              params.businessKey = 'qms_report_approval1';
+            } else {
+              params.businessKey = 'qms_report_approval';
+            }
+          }
+          this.$refs.processSubmitDialogRef.init(params);
+        });
+      },
+
       getQualityType(num) {
         const res = this.typeList.find((item) => item.value == num);
 
@@ -585,6 +689,16 @@
         const res = this.qualityMode.find((item) => item.value == num);
 
         return res ? res.label : '';
+      },
+
+      openTransfer(id) {
+        this.transferVisible = true;
+        this.transferId = id;
+      },
+      transferConfirm(id) {
+        this.transferVisible = false;
+        this.$message.success('转派成功');
+        this.done();
       }
     }
   };