yusheng hai 1 ano
pai
achega
802e928ce8

+ 1158 - 0
src/BIZComponents/inventoryTable.vue

@@ -0,0 +1,1158 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table
+      ref="table"
+      :needPage="false"
+      :columns="columns"
+      :toolkit="[]"
+      :datasource="form.datasource"
+      cache-key="systemRoleTable17"
+      class="time-form"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <div class="headbox">
+          <div>
+            <!--           <el-button-->
+            <!--             size="small"-->
+            <!--             type="primary"-->
+            <!--             icon="el-icon-plus"-->
+            <!--             class="ele-btn-icon"-->
+            <!--             @click="handlAdd"-->
+            <!--             v-if="!isContractId"-->
+            <!--           >-->
+            <!--             新增-->
+            <!--           </el-button>-->
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-plus"
+              class="ele-btn-icon"
+              @click="handParent('', -1)"
+              v-if="!isContractId"
+            >
+              新增
+            </el-button>
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-plus"
+              class="ele-btn-icon"
+              v-if="!isContractId"
+              @click="handlAdd"
+            >
+              新增临时产品
+            </el-button>
+            <el-button
+              size="small"
+              type="primary"
+              class="ele-btn-icon"
+              @click="save"
+              v-if="!isContractId && isDrawer"
+            >
+              保存
+            </el-button>
+          </div>
+          <div class="pricebox">
+            <span class="amount">总计:{{ allPrice }}元</span>
+        
+            <el-form-item
+              style="width: 300px"
+              v-if="isDiscountTotalPrice"
+              label="优惠后总金额:"
+              prop="discountTotalPrice"
+              :rules="{
+                required: true,
+                message: '请输入优惠后总金额',
+                trigger: 'change'
+              }"
+            >
+              <el-input
+                type="number"
+                :min="0"
+                :max="allPrice"
+                :disabled="!allPrice"
+                v-model="discountTotalPrice"
+                style="width: 180px"
+                placeholder="请输入"
+                @input="discountInputByOrder(form.discountTotalPrice)"
+              >
+                <template slot="append">元</template>
+              </el-input>
+            </el-form-item>
+          </div>
+        </div>
+      </template>
+      <template v-slot:productName="{ row, $index }">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + $index + '.productName'"
+          :rules="{
+            required: true,
+            message: '请输入',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            :disabled="isContractId || row.productCode"
+            v-model="row.productName"
+            placeholder="请输入"
+            style="width: 60%; margin-right: 10px"
+          ></el-input>
+          <el-button
+            size="small"
+            type="primary"
+            @click.native="handParent(row, $index)"
+            >选择
+          </el-button>
+        </el-form-item>
+      </template>
+      <template v-slot:headerCustomerMark="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:customerMark="{ row, $index }">
+        <el-form-item
+          :prop="'datasource.' + $index + '.customerMark'"
+      
+        >
+          <el-input v-model="row.customerMark" placeholder="请输入"></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:headerProductName="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:productCode="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productCode'"
+        >
+          <el-input v-model="scope.row.productCode" :disabled="true"></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:productCategoryName="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productCategoryName'"
+        >
+          <el-input v-model="scope.row.productCategoryName" disabled></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:totalCount="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.totalCount'"
+          :rules="{
+            required: isTotalCount?true:false,
+            message: '请输入单价',
+            trigger: 'change'
+          }"
+          
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.totalCount"
+            type="number"
+            placeholder="请输入"
+            @input="changeCount(scope.row, scope.$index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template
+        v-slot:headerTotalCount="{ column }"
+
+      >
+        <span :class="{'is-required':isTotalCount}">{{ column.label }}</span>
+      </template>
+      <template v-slot:totalPrice="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.totalPrice'"
+        >
+          {{ (Number(scope.row.totalPrice) || 0).toFixed(2) }}元
+        </el-form-item>
+      </template>
+
+      <template v-slot:productBrand="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productBrand'"
+        >
+          <el-input
+            v-model="scope.row.productBrand"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+
+      <template v-slot:modelType="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.modelType'"
+        >
+          <el-input
+            v-model="scope.row.modelType"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:specification="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.specification'"
+        >
+          <el-input
+            v-model="scope.row.specification"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+
+      <template v-slot:guaranteePeriod="scope">
+        <div class="period">
+          <div class="borderleftnone">
+            <el-form-item
+              style="margin-bottom: 20px"
+              :prop="'datasource.' + scope.$index + '.guaranteePeriod'"
+              :rules="{
+                required: true,
+                pattern: numberReg,
+                message: '请输入质保期',
+                trigger: 'blur'
+              }"
+            >
+              <el-input
+                :disabled="isContractId"
+                v-model="scope.row.guaranteePeriod"
+                @change="
+                  setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
+                "
+                placeholder="请输入"
+              ></el-input>
+            </el-form-item>
+          </div>
+          <div class="borderrightnone">
+            <DictSelection
+              dictName="质保期单位"
+              clearable
+              v-model="scope.row.guaranteePeriodUnitCode"
+              :disabled="isContractId"
+              @change="
+                setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
+              "
+            >
+            </DictSelection>
+          </div>
+        </div>
+      </template>
+      <template v-slot:measuringUnit="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.measuringUnit'"
+        >
+          <el-input
+            v-model="scope.row.measuringUnit"
+            :disabled="scope.row.productCode"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:remark="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.remark'"
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.remark"
+            type="textarea"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:singlePrice="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.singlePrice'"
+          :rules="{
+            required: isSinglePrice?true:false,
+            message: '请输入单价',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.singlePrice"
+            placeholder="请输入"
+            type="number"
+            @input="changeCount(scope.row, scope.$index)"
+          >
+            <template slot="append">元</template>
+          </el-input>
+        </el-form-item>
+      </template>
+      <template
+        v-slot:headerSinglePrice="{ column }"
+       
+      >
+        <span :class="isSinglePrice?'is-required':''">{{ column.label }}</span>
+      </template>
+      <template v-slot:headerCustomerExpectDeliveryDeadline="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:technicalAnswerName="{ row, $index }">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + $index + '.technicalAnswerName'"
+        >
+          <el-input
+            v-model="row.technicalAnswerName"
+            placeholder="请输入"
+            :disabled="isContractId"
+            @click.native="handHead(row, $index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technicalParams="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.technicalParams'"
+        >
+          <el-input
+            type="textarea"
+            v-model="scope.row.technicalParams"
+            :disabled="isContractId"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technicalDrawings="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.technicalDrawings'"
+        >
+          <fileMain
+            v-model="scope.row.technicalDrawings"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:customerReqFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.customerReqFiles'"
+        >
+          <fileMain
+            v-model="scope.row.customerReqFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:industryArtFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.industryArtFiles'"
+          :rules="{
+            required: false,
+            message: '请输入',
+            trigger: 'change'
+          }"
+        >
+          <fileMain
+            v-model="scope.row.industryArtFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:otherFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '. otherFiles'"
+        >
+          <fileMain
+            v-model="scope.row.otherFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:produceDeliveryDeadline="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.produceDeliveryDeadline'"
+        >
+          <el-date-picker
+            style="width: 140px"
+            v-model="scope.row.produceDeliveryDeadline"
+            :disabled="isContractId"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:customerExpectDeliveryDeadline="scope">
+        <el-form-item
+          :rules="{
+            required: true,
+            message: '请选择客户期望交期',
+            trigger: 'change'
+          }"
+          :prop="
+            'datasource.' + scope.$index + '.customerExpectDeliveryDeadline'
+          "
+        >
+          <el-date-picker
+            style="width: 140px"
+            :disabled="isContractId"
+            v-model="scope.row.customerExpectDeliveryDeadline"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+
+      <template v-slot:guaranteePeriodDeadline="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.guaranteePeriodDeadline'"
+        >
+          <el-date-picker
+            style="width: 140px"
+            :disabled="isContractId"
+            v-model="scope.row.guaranteePeriodDeadline"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:singleWeight="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+         
+          :prop="'datasource.' + scope.$index + '.singleWeight'"
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.singleWeight"
+            @input="changeCount(scope.row, scope.$index)"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technologyRouteName="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.technologyRouteName'"
+          :rules="{
+            required: false,
+            message: '请选择',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            v-model="scope.row.technologyRouteName"
+            :disabled="isContractId"
+            placeholder="请选择"
+            @click.native="openVersion(scope.$index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:pricingWay="scope">
+        <el-form-item :prop="'datasource.' + scope.$index + '.pricingWay'">
+          <el-select v-model="scope.row.pricingWay" placeholder="请选择">
+            <el-option
+              v-for="item in pricingWayList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+              @click.native="changeCount(scope.row, scope.$index)"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </template>
+
+      <!-- 操作列 -->
+      <template v-slot:action="scope">
+        <el-popconfirm
+          class="ele-action"
+          title="确定要删除吗?"
+          @confirm="remove(scope.$index)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
+    </ele-pro-table>
+    <product-list
+      ref="productListRef"
+      classType="1"
+      :is-get-inventory-total="true"
+      @changeParent="changeParent"
+    ></product-list>
+    <head-list ref="headRef" @changeParent="changeAnswer"></head-list>
+    <ProductionVersion
+      ref="versionRefs"
+      @changeProduct="changeProduct"
+    ></ProductionVersion>
+  </el-form>
+</template>
+<script>
+  import { numberReg } from 'ele-admin';
+  import productList from '@/BIZComponents/product-list.vue';
+  import dictMixins from '@/mixins/dictMixins';
+  import fileUpload from '@/components/upload/fileUpload';
+  import headList from '@/BIZComponents/user-select/user-select.vue';
+  import ProductionVersion from '@/components/ProductionVersion2/index.vue';
+  import { getByCode } from '@/api/system/dictionary-data';
+  import fileMain from '@/components/addDoc/index.vue';
+  import { pricingWayList } from '@/enum/dict.js';
+  import { changeCount } from '@/BIZComponents/setProduct.js';
+  import { getInventoryTotalAPI } from '@/api/bpm/components/wms/index.js';
+  const dayjs = require('dayjs');
+
+  export default {
+    mixins: [dictMixins],
+    components: {
+      fileMain,
+      productList,
+      fileUpload,
+      headList,
+      ProductionVersion
+    },
+    props: {
+      pageName: {
+        default: '',
+        type: String
+      },
+      isDiscountTotalPrice: {
+        default: false,
+        type: Boolean
+      },
+  
+      isGuaranteePeriod: {
+        default: true,
+        type: Boolean
+      },
+
+      customerMark: {
+        default: '',
+        type: String
+      },
+
+      isContractId: {
+        type: Boolean,
+        default: false
+      },
+      
+      isSinglePrice: { //单价必填
+        type: Boolean,
+        default: true
+      },
+      isTotalCount: { //数量必填
+        type: Boolean,
+        default: true
+      },
+      
+      isDrawer: {
+        type: Boolean,
+        default: false
+      }
+    },
+    data() {
+      const defaultForm = {
+        key: null,
+        endTime: '',
+        isFirst: 0,
+        name: '',
+        startTime: '',
+        workHour: '',
+        guaranteePeriodUnitCode: '',
+        technicalDrawings: []
+      };
+      return {
+        allPrice: 0,
+        discountTotalPrice: 0,
+        numberReg,
+        defaultForm,
+        form: {
+          datasource: []
+        },
+        pricingWayList,
+        rules: {},
+        dictList: {},
+        columns: [
+          {
+            width: 45,
+            type: 'index',
+            columnKey: 'index',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            width: 280,
+            prop: 'productName',
+            label: '名称',
+            slot: 'productName',
+            headerSlot: 'headerProductName',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'productCode',
+            label: '编码',
+            slot: 'productCode',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'productCategoryName',
+            label: '类型',
+            slot: 'productCategoryName',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'productBrand',
+            label: '牌号',
+            slot: 'productBrand',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'modelType',
+            label: '型号',
+            slot: 'modelType',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'specification',
+            label: '规格',
+            slot: 'specification',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'imgCode',
+            align: 'center',
+            label: '图号/件号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'produceType',
+            align: 'center',
+            label: '生产类型',
+            showOverflowTooltip: true,
+            formatter: (row, column) => {
+              return row.produceType && row.produceType.length
+                ? row.produceType
+                    .map((item) => this.getDictV('productionType', item + ''))
+                    .join(',')
+                : '';
+            }
+          },
+          {
+            width: 120,
+            prop: 'approvalNumber',
+            align: 'center',
+            label: '批准文号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'packingSpecification',
+            align: 'center',
+            label: '包装规格',
+            showOverflowTooltip: true
+          },
+          {
+            width: 200,
+            prop: 'customerMark',
+            label: '客户代号',
+            slot: 'customerMark',
+            align: 'center'
+          },
+          {
+            width: 150,
+            prop: 'totalCount',
+            label: '数量',
+            slot: 'totalCount',
+            headerSlot: 'headerTotalCount',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'availableCountBase',
+            label: '库存数量',
+            slot: 'availableCountBase',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'measuringUnit',
+            label: '计量单位',
+            slot: 'measuringUnit',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'singleWeight',
+            label: '单重',
+            slot: 'singleWeight',
+            headerSlot: 'headerSingleWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'totalWeight',
+            label: '总重',
+            slot: 'totalWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'weightUnit',
+            label: '重量单位',
+            slot: 'weightUnit',
+            align: 'center'
+          },
+
+          {
+            width: 160,
+            prop: 'pricingWay',
+            label: '计价方式',
+            slot: 'pricingWay',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'singlePrice',
+            label: '单价',
+            slot: 'singlePrice',
+            headerSlot: 'headerSinglePrice',
+            align: 'center'
+          },
+
+          {
+            width: 120,
+            prop: 'totalPrice',
+            label: '合计',
+            slot: 'totalPrice',
+            align: 'center'
+          },
+
+          {
+            width: 160,
+            prop: 'customerExpectDeliveryDeadline',
+            label: '客户期望交期',
+            slot: 'customerExpectDeliveryDeadline',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'produceDeliveryDeadline',
+            label: '生产交付交期',
+            slot: 'produceDeliveryDeadline',
+
+            align: 'center'
+          },
+
+          {
+            width: 200,
+            prop: 'guaranteePeriod',
+            label: '质保期',
+            slot: 'guaranteePeriod',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'guaranteePeriodDeadline',
+            label: '质保期截止日期',
+            slot: 'guaranteePeriodDeadline',
+            show: this.isGuaranteePeriod,
+            align: 'center'
+          },
+
+          {
+            width: 220,
+            prop: 'customerReqFiles',
+            label: '客户需求',
+            slot: 'customerReqFiles',
+            align: 'center'
+          },
+          {
+            width: 130,
+            prop: 'technicalAnswerName',
+            label: '技术答疑人',
+            slot: 'technicalAnswerName',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'technicalParams',
+            label: '技术参数',
+            slot: 'technicalParams',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technicalDrawings',
+            label: '技术图纸',
+            slot: 'technicalDrawings',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technologyRouteName',
+            label: '工艺路线',
+            slot: 'technologyRouteName',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'industryArtFiles',
+            label: '工艺附件',
+            slot: 'industryArtFiles',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'otherFiles',
+            label: '其他附件',
+            slot: 'otherFiles',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'remark',
+            label: '备注',
+            slot: 'remark',
+            align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 120,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            fixed: 'right',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    computed: {
+      canHandl() {
+        return this.form.datasource.length;
+      }
+    },
+
+    created() {
+      this.getDictList('productionType');
+    },
+    methods: {
+      getDictV(code, val) {
+        if (!this.dictList[code]) return '';
+        return this.dictList[code].find((item) => item.value == val)?.label;
+      },
+      async getDictList(code) {
+        let { data: res } = await getByCode(code);
+        this.dictList[code] = res.map((item) => {
+          let values = Object.keys(item);
+          return {
+            value: values[0],
+            label: item[values[0]]
+          };
+        });
+      },
+      downloadFile(file) {
+        getFile({ objectName: file.storePath }, file.name);
+      },
+      openVersion(index) {
+        this.$refs.versionRefs.open(index);
+      },
+      //工艺路线
+      changeProduct(data, index) {
+        this.$set(
+          this.form.datasource[index],
+          'technologyRouteName',
+          data.name
+        );
+        this.$set(this.form.datasource[index], 'technologyRouteId', data.id);
+      },
+      setDeliveryDays(row, index, type, isAll) {
+        if (isAll) {
+          this.form.datasource.forEach((item, i) => {
+            let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+              item.guaranteePeriodUnitCode
+            );
+
+            this.$set(
+              this.form.datasource[i],
+              'guaranteePeriodDeadline',
+              guaranteePeriodUnitName != 'second'
+                ? this.setDay(item.guaranteePeriod, guaranteePeriodUnitName)
+                : ''
+            );
+            // }
+          });
+          return;
+        }
+
+        if (type == 'guaranteePeriod') {
+          let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+            row.guaranteePeriodUnitCode
+          );
+          this.$set(
+            this.form.datasource[index],
+            'guaranteePeriodDeadline',
+            guaranteePeriodUnitName != 'second'
+              ? this.setDay(row.guaranteePeriod, guaranteePeriodUnitName)
+              : ''
+          );
+        }
+      },
+      guaranteePeriodUnit(code) {
+        return code == 3
+          ? 'day'
+          : code == 4
+          ? 'month'
+          : code == 5
+          ? 'year'
+          : 'second';
+      },
+      setDay(addDay, dateType = 'day') {
+        return dayjs(this.contractStartDate || new Date())
+          .add(addDay, dateType)
+          .format('YYYY-MM-DD');
+      },
+      // 返回列表数据
+      getTableValue() {
+        let comitDatasource = this.form.datasource;
+        if (comitDatasource.length === 0) return [];
+        comitDatasource.forEach((v) => {
+          if (v.guaranteePeriodUnitCode) {
+            v.guaranteePeriodUnitName = this.getDictValue(
+              '保质期单位',
+              v.guaranteePeriodUnitCode
+            );
+          }
+          v.technicalDrawings = v.technicalDrawings ? v.technicalDrawings : [];
+          v.customerReqFiles = v.customerReqFiles || [];
+          v.industryArtFiles = v.industryArtFiles || [];
+          v.otherFiles = v.otherFiles || [];
+        });
+        return comitDatasource;
+      },
+      getPrice() {
+        return [this.allPrice, this.form.discountTotalPrice];
+      },
+      //改变数量
+      changeCount(row, index) {
+        const { allPrice, arr } = changeCount(row, index, this.form.datasource);
+        this.form.datasource=arr
+        this.allPrice=allPrice||0
+  
+      
+      },
+      setCustomerMark(customerMark) {
+        this.form.datasource.forEach((item) => {
+          item['customerMark'] = customerMark;
+          this.$forceUpdate();
+        });
+      },
+     
+      //修改回显
+      async putTableValue(data) {
+        let productList =
+          (data &&
+            (data.quoteProductList || data.productList || data.detailList)) ||
+          [];
+        if (productList) {
+          productList.forEach((item) => {
+            item.guaranteePeriodUnitCode = item.guaranteePeriodUnitCode
+              ? item.guaranteePeriodUnitCode + ''
+              : '';
+
+            let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+              item.guaranteePeriodUnitCode
+            );
+            if (item.guaranteePeriod && item.guaranteePeriodUnitCode) {
+              item['guaranteePeriodDeadline'] =
+                item['guaranteePeriodDeadline'] ||
+                guaranteePeriodUnitName != 'second'
+                  ? this.setDay(item.guaranteePeriod, guaranteePeriodUnitName)
+                  : '';
+            }
+          });
+          this.form.datasource = productList;
+          this.changeCount()
+
+          let codeList = this.form.datasource.map((item) => item.productCode);
+          //获取仓库库存
+          let inventoryTotalList = await getInventoryTotalAPI(codeList);
+          this.form.datasource.forEach((item) => {
+            let find =
+              inventoryTotalList.find((key) => key.code == item.productCode) ||
+              {};
+            item.availableCountBase = find.availableCountBase;
+          });
+          this.$refs.table.reload();
+        }
+      },
+
+      //计算单重
+
+      //选择产品
+      handParent(row, index) {
+        let item = {
+          id: row.productCode
+        };
+        this.$refs.productListRef.open(item, index);
+      },
+      //选择技术人回调
+      changeAnswer(obj, idx) {
+        this.$set(this.form.datasource[idx], 'technicalAnswerId', obj.id);
+        this.$set(this.form.datasource[idx], 'technicalAnswerName', obj.name);
+      },
+      handHead(row, index) {
+        let item = {
+          id: row.technicalAnswerId
+        };
+        this.$refs.headRef.open(item, index);
+      },
+      //选择产品回调
+      changeParent(obj, idx) {
+        obj.forEach((item, index) => {
+          let i = idx == -1 ? index : idx;
+          let row = JSON.parse(JSON.stringify(this.defaultForm));
+          row.key = this.form.datasource.length + 1;
+          let parasm = idx == -1 ? row : this.form.datasource[i];
+
+          this.$set(parasm, 'productId', item.id);
+          this.$set(parasm, 'categoryName', item.name);
+          this.$set(parasm, 'productCategoryId', item.categoryLevelId);
+          this.$set(parasm, 'productBrand', item.brandNum);
+          this.$set(parasm, 'productCategoryName', item.categoryLevelPath);
+          this.$set(parasm, 'productCode', item.code);
+          this.$set(parasm, 'productName', item.name);
+          this.$set(parasm, 'modelType', item.modelType);
+          this.$set(parasm, 'availableCountBase', item.availableCountBase);
+          this.$set(parasm, 'measuringUnit', item.measuringUnit);
+          this.$set(parasm, 'specification', item.specification);
+          this.$set(parasm, 'weightUnit', item.weightUnit);
+          this.$set(parasm, 'singleWeight', item.roughWeight);
+          this.$set(parasm, 'pricingWay', 1);
+
+          this.$set(parasm, 'imgCode', item.imgCode);
+          this.$set(parasm, 'produceType', item.produceType);
+          this.$set(parasm, 'approvalNumber', item.extField.approvalNumber);
+          this.$set(
+            parasm,
+            'packingSpecification',
+            item.extField.packingSpecification
+          );
+          this.$set(parasm, 'customerMark', this.customerMark);
+
+          if (idx == -1) {
+            this.form.datasource.push(row);
+          }
+        });
+      },
+      remove(index) {
+        this.form.datasource.splice(index, 1);
+        this.setSort();
+      },
+      // 清空表格
+      restTable() {
+        this.form.datasource = [];
+      },
+      // 重新排序
+      setSort() {
+        this.form.datasource.forEach((n, index) => {
+          n.key = index + 1;
+        });
+      },
+      // 添加
+      handlAdd() {
+        let item = JSON.parse(JSON.stringify(this.defaultForm));
+        item.key = this.form.datasource.length + 1;
+        this.form.datasource.push(item);
+      },
+
+      validateForm(callback) {
+        //开始表单校验
+        this.$refs.form.validate((valid, obj) => {
+          if (obj) {
+            let messages = Object.keys(obj).map((key) => obj[key][0]);
+            if (messages.length > 0) {
+              this.$message.warning(messages[0].message);
+            }
+          }
+          callback(valid);
+        });
+      },
+      save() {
+        this.$emit('save');
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      padding-right: 30px;
+    }
+  }
+
+  .time-form .el-form-item {
+    margin-bottom: 0 !important;
+  }
+
+  ::v-deep .period {
+    display: flex;
+
+    .borderleftnone {
+      .el-input--medium .el-input__inner {
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      }
+    }
+
+    .borderrightnone {
+      .el-input--medium .el-input__inner {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+      }
+    }
+  }
+
+  ::v-deep .time-form tbody > tr:hover > td {
+    background-color: transparent !important;
+  }
+
+  ::v-deep .time-form .el-table tr {
+    background-color: #ffffff;
+  }
+
+  .pricebox {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    font-weight: bold;
+  }
+</style>

+ 433 - 0
src/BIZComponents/inventoryTableDetails.vue

@@ -0,0 +1,433 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table
+      ref="table"
+      :needPage="false"
+      :columns="columns"
+      :toolkit="[]"
+      :datasource="form.datasource"
+      cache-key="systemRoleTable17"
+      class="time-form"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <div class="headbox">
+          <div class="pricebox">
+            <span class="amount">总计:{{ allPrice }}元</span>
+            <span class="amount" v-if="isDiscountTotalPrice">优惠后总金额:{{ discountTotalPrice }}元</span>
+          </div>
+        </div>
+      </template>
+    </ele-pro-table>
+  </el-form>
+</template>
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+
+  import fileMain from '@/components/addDoc/index.vue';
+  import { pricingWayList } from '@/enum/dict.js';
+
+  const dayjs = require('dayjs');
+
+  export default {
+    mixins: [dictMixins],
+    components: {
+      fileMain
+    },
+    props: {
+      isDiscountTotalPrice: {
+        default: false,
+        type: Boolean
+      },
+      isDiscount: {
+        //折让
+        type: Boolean,
+        default: true
+      },
+    },
+    data() {
+      return {
+        allPrice: 0,
+        discountTotalPrice: 0,
+
+        form: {
+          datasource: []
+        },
+
+        columns: [
+          {
+            width: 45,
+            type: 'index',
+            columnKey: 'index',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            width: 280,
+            prop: 'productName',
+            label: '名称',
+            slot: 'productName',
+            headerSlot: 'headerProductName',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'productCode',
+            label: '编码',
+            slot: 'productCode',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'productCategoryName',
+            label: '类型',
+            slot: 'productCategoryName',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'productBrand',
+            label: '牌号',
+            slot: 'productBrand',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'modelType',
+            label: '型号',
+            slot: 'modelType',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'specification',
+            label: '规格',
+            slot: 'specification',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'imgCode',
+            align: 'center',
+            label: '图号/件号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'produceType',
+            align: 'center',
+            label: '生产类型',
+            showOverflowTooltip: true,
+            formatter: (row, column) => {
+              return row?.produceType?.map((item) =>{
+               return this.getDictValue('生产类型', item)
+              })?.toString()
+            }
+          },
+          {
+            width: 120,
+            prop: 'approvalNumber',
+            align: 'center',
+            label: '批准文号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'packingSpecification',
+            align: 'center',
+            label: '包装规格',
+            showOverflowTooltip: true
+          },
+          {
+            width: 200,
+            prop: 'customerMark',
+            label: '客户代号',
+            slot: 'customerMark',
+            align: 'center'
+          },
+          {
+            width: 150,
+            prop: 'totalCount',
+            label: '数量',
+            slot: 'totalCount',
+            headerSlot: 'headerTotalCount',
+            align: 'center'
+          },
+          // {
+          //   width: 120,
+          //   prop: 'availableCountBase',
+          //   label: '库存数量',
+          //   slot: 'availableCountBase',
+          //   align: 'center'
+          // },
+          {
+            width: 120,
+            prop: 'measuringUnit',
+            label: '计量单位',
+            slot: 'measuringUnit',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'singleWeight',
+            label: '单重',
+            slot: 'singleWeight',
+            headerSlot: 'headerSingleWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'totalWeight',
+            label: '总重',
+            slot: 'totalWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'weightUnit',
+            label: '重量单位',
+            slot: 'weightUnit',
+            align: 'center'
+          },
+
+          {
+            width: 160,
+            prop: 'pricingWay',
+            label: '计价方式',
+            slot: 'pricingWay',
+            align: 'center',
+            formatter: (row, column) => {
+              return row.pricingWay == 1 ? '数量' : '重量';
+            }
+          },
+          {
+            width: 200,
+            prop: 'singlePrice',
+            label: '单价',
+            slot: 'singlePrice',
+            headerSlot: 'headerSinglePrice',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'discountSinglePrice',
+            label: '折让单价',
+            align: 'center',
+            show:this.isDiscount
+          },
+          {
+            width: 120,
+            prop: 'totalPrice',
+            label: '合计',
+            slot: 'totalPrice',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'discountTotalPrice',
+            label: '折让合计',
+            align: 'center',
+            show:this.isDiscount
+          },
+          {
+            width: 160,
+            prop: 'customerExpectDeliveryDeadline',
+            label: '客户期望交期',
+            slot: 'customerExpectDeliveryDeadline',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'produceDeliveryDeadline',
+            label: '生产交付交期',
+            slot: 'produceDeliveryDeadline',
+
+            align: 'center'
+          },
+
+          {
+            width: 200,
+            prop: 'guaranteePeriod',
+            label: '质保期',
+            slot: 'guaranteePeriod',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'guaranteePeriodDeadline',
+            label: '质保期截止日期',
+            slot: 'guaranteePeriodDeadline',
+            align: 'center'
+          },
+
+          {
+            width: 220,
+            prop: 'customerReqFiles',
+            label: '客户需求',
+            slot: 'customerReqFiles',
+            align: 'center'
+          },
+          {
+            width: 130,
+            prop: 'technicalAnswerName',
+            label: '技术答疑人',
+            slot: 'technicalAnswerName',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'technicalParams',
+            label: '技术参数',
+            slot: 'technicalParams',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technicalDrawings',
+            label: '技术图纸',
+            slot: 'technicalDrawings',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technologyRouteName',
+            label: '工艺路线',
+            slot: 'technologyRouteName',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'industryArtFiles',
+            label: '工艺附件',
+            slot: 'industryArtFiles',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'otherFiles',
+            label: '其他附件',
+            slot: 'otherFiles',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'remark',
+            label: '备注',
+            slot: 'remark',
+            align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 120,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            fixed: 'right',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    computed: {},
+
+    created() {
+      this.requestDict('生产类型');
+
+    },
+    methods: {
+
+
+      setDay(addDay, dateType = 'day') {
+        return dayjs(this.contractStartDate || new Date())
+          .add(addDay, dateType)
+          .format('YYYY-MM-DD');
+      },
+      // 返回列表数据
+      getTableValue() {
+        let comitDatasource = this.form.datasource;
+        if (comitDatasource.length === 0) return [];
+        comitDatasource.forEach((v) => {
+          if (v.guaranteePeriodUnitCode) {
+            v.guaranteePeriodUnitName = this.getDictValue(
+              '保质期单位',
+              v.guaranteePeriodUnitCode
+            );
+          }
+          v.technicalDrawings = v.technicalDrawings ? v.technicalDrawings : [];
+          v.customerReqFiles = v.customerReqFiles || [];
+          v.industryArtFiles = v.industryArtFiles || [];
+          v.otherFiles = v.otherFiles || [];
+        });
+        return comitDatasource;
+      },
+
+      //修改回显
+      async putTableValue(data) {
+        let productList =
+          (data &&
+            (data.quoteProductList || data.productList || data.detailList)) ||
+          [];
+        if (productList) {
+          this.form.datasource = productList;
+          this.allPrice = data.totalPrice;
+
+          this.$refs.table.reload();
+        }
+      },
+
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      padding-right: 30px;
+    }
+  }
+
+  .time-form .el-form-item {
+    margin-bottom: 0 !important;
+  }
+
+  ::v-deep .period {
+    display: flex;
+
+    .borderleftnone {
+      .el-input--medium .el-input__inner {
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      }
+    }
+
+    .borderrightnone {
+      .el-input--medium .el-input__inner {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+      }
+    }
+  }
+
+  ::v-deep .time-form tbody > tr:hover > td {
+    background-color: transparent !important;
+  }
+
+  ::v-deep .time-form .el-table tr {
+    background-color: #ffffff;
+  }
+
+  .pricebox {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    font-weight: bold;
+  }
+</style>

+ 50 - 0
src/BIZComponents/setProduct.js

@@ -0,0 +1,50 @@
+
+
+//改变数量
+export function changeCount(row, index, arr) {
+  if(row){
+    singleWeightChange(row, index);
+  }
+  return getNumTotalPrice(arr);
+}
+
+
+//计算总金额
+function getNumTotalPrice(arr) {
+  let sum = 0;
+  arr.forEach((r, index) => {
+    if (r.singlePrice && r.totalCount) {
+      r.totalPrice = getAllPrice(r);
+      r.discountTotalPrice = r.totalPrice;
+      sum += Number(r.totalPrice);
+    } else {
+      r.totalPrice = 0;
+      r.discountTotalPrice = 0;
+    }
+  });
+  return { allPrice: isNaN(sum) ? 0 : sum.toFixed(2), arr };
+}
+
+//获取合计
+function getAllPrice(row) {
+  let num = 0;
+  if (row.pricingWay == 1) {
+    //按数量计价计算总金额
+    num = Number(row.singlePrice) * Number(row.totalCount);
+  }
+  if (row.pricingWay == 2) {
+    //按重量计价计算总金额
+    num =
+      Number(row.singlePrice) *
+      Number(row.totalCount) *
+      Number(row.singleWeight);
+  }
+  return isNaN(num) ? '' : num.toFixed(2);
+}
+function singleWeightChange(row) {
+  if (row && row.singleWeight && row.totalCount) {
+    row.totalWeight = (row.singleWeight * row.totalCount).toFixed(2) || 0;
+  } else {
+    row.totalWeight = '';
+  }
+}

+ 5 - 0
src/enum/dict.js

@@ -133,3 +133,8 @@ export const proStatusEnum = [
   { value: 3, label: '已完成' },
   { value: 4, label: '已终止' }
 ];
+// 计价方式
+export const pricingWayList= [
+  { id: 1, name: '按数量计价' },
+  { id: 2, name: '按重量计价' }
+]

+ 1 - 1
src/views/bpm/done/index.vue

@@ -155,7 +155,7 @@
             minWidth: 150
           },
           {
-            prop: 'processInstance.businessCode',
+            prop: 'businessCode',
             label: '单据编码',
             align: 'center',
             showOverflowTooltip: true,

+ 31 - 14
src/views/bpm/handleTask/components/businessOpportunity/addOpportunityDialog.vue

@@ -84,7 +84,7 @@
             </DictSelection>
           </el-form-item>
         </el-col> -->
-        <el-col :span="8">
+        <!-- <el-col :span="8">
           <el-form-item
             label="计价方式"
             prop="pricingWay"
@@ -94,17 +94,16 @@
             </el-radio-group>
           </el-form-item>
 
-        </el-col>
+        </el-col> -->
         <el-col :span="8" style="height: 58px">
-
           <el-form-item prop="files" label="附件">
             <fileMain v-model="form.files"></fileMain>
-<!--            <fileUpload-->
-<!--              v-model="form.files"-->
-<!--              module="main"-->
-<!--              :showLib="false"-->
-<!--              :limit="5"-->
-<!--            />-->
+            <!--            <fileUpload-->
+            <!--              v-model="form.files"-->
+            <!--              module="main"-->
+            <!--              :showLib="false"-->
+            <!--              :limit="5"-->
+            <!--            />-->
           </el-form-item>
         </el-col>
         <el-col :span="16">
@@ -125,6 +124,7 @@
       ref="inventoryTable"
       :isDeliveryDeadline="false"
       :isGuaranteePeriod="false"
+      :isDiscount="false"
       pageName="businessOpportunity"
       :pricing-way="form.pricingWay"
     ></inventoryTable>
@@ -163,9 +163,11 @@
   import { getDetail } from '@/api/bpm/components/saleManage/businessOpportunity';
 
   import { copyObj } from '@/utils/util';
-  import inventoryTable from '@/views/bpm/handleTask/components/contractBook/inventoryTable.vue';
+  import inventoryTable from '@/BIZComponents/inventoryTable.vue';
+
   import fileUpload from '@/components/upload/fileUpload';
-  import fileMain from "@/components/addDoc/index.vue";
+  import fileMain from '@/components/addDoc/index.vue';
+  import {contactDetail} from '@/api/bpm/components/saleManage/contact';
 
   export default {
     props: {
@@ -208,8 +210,8 @@
         delDetailIds: [],
         PersonnelDetailIds: [],
         pricingWayList: [
-          {id: 1, name: '按数量计价'},
-          {id: 2, name: '按重量计价'}
+          { id: 1, name: '按数量计价' },
+          { id: 2, name: '按重量计价' }
         ],
         visible: false,
         title: '',
@@ -324,6 +326,17 @@
       changeParent(obj) {
         this.$set(this.form, 'contactId', obj.id);
         this.$set(this.form, 'contactName', obj.name);
+        this.getContactDetail(1);
+      },
+      //获取客户
+      async getContactDetail(type) {
+        const { base } = await contactDetail(this.form.contactId);
+        this.customerMark = base.serialNo;
+        if (type) {
+          this.$nextTick(() => {
+            this.$refs.inventoryTable.setCustomerMark(this.customerMark);
+          });
+        }
       },
       //选择负责人回调
       changeHead(obj) {
@@ -347,10 +360,13 @@
       async getDetailData(id) {
         this.loading = true;
         const data = await getDetail(id);
+
         this.loading = false;
         if (data) {
+          this.form = data;
+          this.getContactDetail()
+
           this.$nextTick(() => {
-            this.form = data;
             this.$refs.inventoryTable &&
               this.$refs.inventoryTable.putTableValue(data);
           });
@@ -412,6 +428,7 @@
 
             return;
           }
+          this.form.totalPrice= this.$refs.inventoryTable.getPrice()[0]
           const commitData = {
             opportunity: this.form,
             competAnalysisList: this.form.competAnalysisList,

+ 69 - 43
src/views/bpm/handleTask/components/businessOpportunity/opportunityDetailDialog.vue

@@ -30,15 +30,15 @@
           </el-form-item>
         </el-col>
         <el-col :span="8">
-            <el-form-item label="赢单率:" prop="winRate">
-              {{detailData.winRate? detailData.winRate + '%' : '' }}
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="预算:" prop="budget">
-              {{ detailData.budget? detailData.budget + '万元':'' }}
-            </el-form-item>
-          </el-col>
+          <el-form-item label="赢单率:" prop="winRate">
+            {{ detailData.winRate ? detailData.winRate + '%' : '' }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="预算:" prop="budget">
+            {{ detailData.budget ? detailData.budget + '万元' : '' }}
+          </el-form-item>
+        </el-col>
         <el-col :span="8">
           <el-form-item label="预计结单日期:" prop="expectedClosingDate">
             {{ detailData.expectedClosingDate }}
@@ -51,25 +51,25 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="附件:" prop="files">
-            <fileMain v-model="detailData.files" type="view" ></fileMain>
-<!--            <div v-if="detailData.files && detailData.files?.length">-->
-<!--              <el-link-->
-<!--                v-for="link in detailData.files"-->
-<!--                :key="link.id"-->
-<!--                type="primary"-->
-<!--                :underline="false"-->
-<!--                @click="downloadFile(link)"-->
-<!--              >-->
-<!--                {{ link.name }}</el-link-->
-<!--              >-->
-<!--            </div>-->
+            <fileMain v-model="detailData.files" type="view"></fileMain>
+            <!--            <div v-if="detailData.files && detailData.files?.length">-->
+            <!--              <el-link-->
+            <!--                v-for="link in detailData.files"-->
+            <!--                :key="link.id"-->
+            <!--                type="primary"-->
+            <!--                :underline="false"-->
+            <!--                @click="downloadFile(link)"-->
+            <!--              >-->
+            <!--                {{ link.name }}</el-link-->
+            <!--              >-->
+            <!--            </div>-->
           </el-form-item>
         </el-col>
-        <el-col :span="8">
+        <!-- <el-col :span="8">
           <el-form-item label="计费方式:" prop="pricingWay">
             {{ detailData.pricingWay == 1 ? '按数量计费' : '按重量计费' }}
           </el-form-item>
-        </el-col>
+        </el-col> -->
         <el-col :span="16">
           <el-form-item label="备注:" prop="remark">
             {{ detailData.remark }}
@@ -81,23 +81,36 @@
     <headerTitle title="产品清单"></headerTitle>
 
     <inventoryTable
-    pageName="businessOpportunity"
-      v-if="['productionSupervisorApprove1','technicianApprove','techLeaderApprove','productionSupervisorApprove2','salesManagerApprove'].includes(taskDefinitionKey)"
+      pageName="businessOpportunity"
+      v-if="
+        [
+          'productionSupervisorApprove1',
+          'technicianApprove',
+          'techLeaderApprove',
+          'productionSupervisorApprove2',
+          'salesManagerApprove'
+        ].includes(taskDefinitionKey)
+      "
       ref="inventoryTable"
-      :taskDefinitionKey=taskDefinitionKey
-      :isDeliveryDeadline="false"
-      :isGuaranteePeriod="false"
-      :isCustomerMark="false"
-      :pricingWay="detailData.pricingWay"
+      
+      :customerMark="customerMark"
     ></inventoryTable>
 
     <inventoryTabledetail
-     v-if="!['productionSupervisorApprove1','technicianApprove','techLeaderApprove','productionSupervisorApprove2','salesManagerApprove'].includes(taskDefinitionKey)"
+      v-if="
+        ![
+          'productionSupervisorApprove1',
+          'technicianApprove',
+          'techLeaderApprove',
+          'productionSupervisorApprove2',
+          'salesManagerApprove'
+        ].includes(taskDefinitionKey)
+      "
       ref="inventoryTabledetailRef"
       :isDeliveryDeadline="false"
       :isGuaranteePeriod="false"
       :isCustomerMark="false"
-     :pricingWay="detailData.pricingWay"
+      :pricingWay="detailData.pricingWay"
     ></inventoryTabledetail>
     <!-- <el-card
       shadow="never"
@@ -134,10 +147,12 @@
   import { getDetail } from '@/api/bpm/components/saleManage/businessOpportunity';
   import { getFile } from '@/api/system/file';
   import dictMixins from '@/mixins/dictMixins';
-  import inventoryTable from '@/views/bpm/handleTask/components/contractBook/inventoryTable.vue';
-  import inventoryTabledetail from '@/views/bpm/handleTask/components/contractBook/inventoryTabledetail.vue';
-  import fileMain from "@/components/addDoc/index.vue";
+  // import inventoryTable from './saleGeneralityInventoryTable.vue';
+  import inventoryTable from '@/BIZComponents/inventoryTable.vue';
 
+  import inventoryTabledetail from '@/views/bpm/handleTask/components/contractBook/inventoryTabledetail.vue';
+  import fileMain from '@/components/addDoc/index.vue';
+  import {contactDetail} from '@/api/bpm/components/saleManage/contact';
   export default {
     mixins: [dictMixins],
     components: {
@@ -156,6 +171,7 @@
     data() {
       return {
         visible: false,
+        customerMark:'',
         title: '详情',
         row: {},
         activeName: 'base',
@@ -286,7 +302,7 @@
             label: '销售总金额',
             slot: 'totalPrice',
             formatter: (_row, _column, cellValue) => {
-              return _row.totalPrice? _row.totalPrice + '元':'';
+              return _row.totalPrice ? _row.totalPrice + '元' : '';
             }
           },
           {
@@ -307,7 +323,9 @@
             label: '质保期',
             slot: 'guaranteePeriod',
             formatter: (_row, _column, cellValue) => {
-              return (_row.guaranteePeriod||'') + _row.guaranteePeriodUnitName;
+              return (
+                (_row.guaranteePeriod || '') + _row.guaranteePeriodUnitName
+              );
             }
           },
           // {
@@ -340,7 +358,9 @@
             label: '技术图纸',
             slot: 'technicalDrawings',
             formatter: (_row, _column, cellValue) => {
-              return (_row.guaranteePeriod||'') + _row.guaranteePeriodUnitName;
+              return (
+                (_row.guaranteePeriod || '') + _row.guaranteePeriodUnitName
+              );
             }
           },
           {
@@ -365,14 +385,20 @@
 
         this.loading = false;
         this.detailData = data;
-        console.log(this.detailData.pricingWay);
-        if (this.detailData ) {
+        this.getContactDetail()
+        if (this.detailData) {
           this.$refs.inventoryTable &&
             this.$refs.inventoryTable.putTableValue(this.detailData);
           this.$refs.inventoryTabledetailRef &&
             this.$refs.inventoryTabledetailRef.putTableValue(this.detailData);
         }
       },
+      //获取客户
+      async getContactDetail(type) {
+        const { base } = await contactDetail(this.detailData.contactId);
+        this.customerMark = base.serialNo;
+  
+      },
       getValidate() {
         return Promise.all([
           new Promise((resolve, reject) => {
@@ -386,13 +412,13 @@
           })
         ]);
       },
-    async getTableValue() {
+      async getTableValue() {
         try {
           await this.getValidate();
           return this.$refs.inventoryTable.getTableValue();
-        }catch (error) {
+        } catch (error) {
           console.log(error);
-          return Promise.resolve([])
+          return Promise.resolve([]);
         }
       }
     }

+ 1104 - 0
src/views/bpm/handleTask/components/businessOpportunity/saleGeneralityInventoryTable.vue

@@ -0,0 +1,1104 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table
+      ref="table"
+      :needPage="false"
+      :columns="columns"
+      :toolkit="[]"
+      :datasource="form.datasource"
+      cache-key="systemRoleTable17"
+      class="time-form"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <div class="headbox">
+          <div>
+            <!-- <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-plus"
+              class="ele-btn-icon"
+              @click="handParent('', -1)"
+              v-if="!isContractId"
+            >
+              新增
+            </el-button> -->
+          </div>
+          <div class="pricebox">
+            <span class="amount">总计:{{ allPrice }}元</span>
+          
+          </div>
+        </div>
+      </template>
+      <template v-slot:productName="{ row, $index }">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + $index + '.productName'"
+          :rules="{
+            required: true,
+            message: '请输入',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            :disabled="isContractId || row.productCode"
+            v-model="row.productName"
+            placeholder="请输入"
+            style="width: 60%; margin-right: 10px"
+          ></el-input>
+          <el-button
+            size="small"
+            type="primary"
+            @click.native="handParent(row, $index)"
+            >选择
+          </el-button>
+        </el-form-item>
+      </template>
+      <template v-slot:headerCustomerMark="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:customerMark="{ row, $index }">
+        <el-form-item
+          :prop="'datasource.' + $index + '.customerMark'"
+          
+        >
+          <el-input v-model="row.customerMark" placeholder="请输入"></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:headerProductName="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:productCode="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productCode'"
+        >
+          <el-input v-model="scope.row.productCode" :disabled="true"></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:productCategoryName="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productCategoryName'"
+        >
+          <el-input v-model="scope.row.productCategoryName" disabled></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:totalCount="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.totalCount'"
+          
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.totalCount"
+            type="number"
+            placeholder="请输入"
+            @input="changeCount(scope.row, scope.$index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template
+        v-slot:headerTotalCount="{ column }"
+        v-if="pageName != 'businessOpportunity'"
+      >
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template
+        v-slot:headerSingleWeight="{ column }"
+        v-if="pageName != 'businessOpportunity'"
+      >
+        <span :class="{ 'is-required': pricingWay == 2 }">{{
+          column.label
+        }}</span>
+      </template>
+      <template v-slot:totalPrice="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.totalPrice'"
+        >
+          {{ (Number(scope.row.totalPrice) || 0).toFixed(2) }}元
+        </el-form-item>
+      </template>
+
+      <template v-slot:productBrand="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.productBrand'"
+        >
+          <el-input
+            v-model="scope.row.productBrand"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+
+      <template v-slot:modelType="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.modelType'"
+        >
+          <el-input
+            v-model="scope.row.modelType"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:specification="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.specification'"
+        >
+          <el-input
+            v-model="scope.row.specification"
+            :disabled="scope.row.productCode"
+          ></el-input>
+        </el-form-item>
+      </template>
+
+      <template v-slot:guaranteePeriod="scope">
+        <div class="period">
+          <div class="borderleftnone">
+            <el-form-item
+              style="margin-bottom: 20px"
+              :prop="'datasource.' + scope.$index + '.guaranteePeriod'"
+              :rules="{
+                required: true,
+                pattern: numberReg,
+                message: '请输入质保期',
+                trigger: 'blur'
+              }"
+            >
+              <el-input
+                :disabled="isContractId"
+                v-model="scope.row.guaranteePeriod"
+                @change="
+                  setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
+                "
+                placeholder="请输入"
+              ></el-input>
+            </el-form-item>
+          </div>
+          <div class="borderrightnone">
+            <DictSelection
+              dictName="质保期单位"
+              clearable
+              v-model="scope.row.guaranteePeriodUnitCode"
+              :disabled="isContractId"
+              @change="
+                setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
+              "
+            >
+            </DictSelection>
+          </div>
+        </div>
+      </template>
+      <template v-slot:measuringUnit="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.measuringUnit'"
+        >
+          <el-input
+            v-model="scope.row.measuringUnit"
+            :disabled="scope.row.productCode"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:remark="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.remark'"
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.remark"
+            type="textarea"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:singlePrice="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.singlePrice'"
+         
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.singlePrice"
+            placeholder="请输入"
+            type="number"
+            @input="changeCount(scope.row, scope.$index)"
+          >
+            <template slot="append">元</template>
+          </el-input>
+        </el-form-item>
+      </template>
+      <template
+        v-slot:headerSinglePrice="{ column }"
+        v-if="pageName != 'businessOpportunity'"
+      >
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:headerCustomerExpectDeliveryDeadline="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:technicalAnswerName="{ row, $index }">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + $index + '.technicalAnswerName'"
+        >
+          <el-input
+            v-model="row.technicalAnswerName"
+            placeholder="请输入"
+            :disabled="isContractId"
+            @click.native="handHead(row, $index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technicalParams="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.technicalParams'"
+        >
+          <el-input
+            type="textarea"
+            v-model="scope.row.technicalParams"
+            :disabled="isContractId"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technicalDrawings="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.technicalDrawings'"
+        >
+          <fileMain
+            v-model="scope.row.technicalDrawings"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:customerReqFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.customerReqFiles'"
+        >
+          <fileMain
+            v-model="scope.row.customerReqFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:industryArtFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.industryArtFiles'"
+          :rules="{
+            required: false,
+            message: '请输入',
+            trigger: 'change'
+          }"
+        >
+          <fileMain
+            v-model="scope.row.industryArtFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:otherFiles="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '. otherFiles'"
+        >
+          <fileMain
+            v-model="scope.row.otherFiles"
+            :type="isContractId ? 'view' : ''"
+          ></fileMain>
+        </el-form-item>
+      </template>
+      <template v-slot:produceDeliveryDeadline="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.produceDeliveryDeadline'"
+        >
+          <el-date-picker
+            style="width: 140px"
+            v-model="scope.row.produceDeliveryDeadline"
+            :disabled="isContractId"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:customerExpectDeliveryDeadline="scope">
+        <el-form-item
+          :rules="{
+            required: true,
+            message: '请选择客户期望交期',
+            trigger: 'change'
+          }"
+          :prop="
+            'datasource.' + scope.$index + '.customerExpectDeliveryDeadline'
+          "
+        >
+          <el-date-picker
+            style="width: 140px"
+            :disabled="isContractId"
+            v-model="scope.row.customerExpectDeliveryDeadline"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+
+      <template v-slot:guaranteePeriodDeadline="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.guaranteePeriodDeadline'"
+        >
+          <el-date-picker
+            style="width: 140px"
+            :disabled="isContractId"
+            v-model="scope.row.guaranteePeriodDeadline"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:singleWeight="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          
+          :prop="'datasource.' + scope.$index + '.singleWeight'"
+        >
+          <el-input
+            :disabled="isContractId"
+            v-model="scope.row.singleWeight"
+            @input="changeCount(scope.row, scope.$index)"
+            placeholder="请输入"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:technologyRouteName="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.technologyRouteName'"
+          :rules="{
+            required: false,
+            message: '请选择',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            v-model="scope.row.technologyRouteName"
+            :disabled="isContractId"
+            placeholder="请选择"
+            @click.native="openVersion(scope.$index)"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:pricingWay="scope">
+        <el-form-item :prop="'datasource.' + scope.$index + '.pricingWay'">
+          <el-select v-model="scope.row.pricingWay" placeholder="请选择">
+            <el-option
+              v-for="item in pricingWayList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+              @click.native="changeCount(scope.row, scope.$index)"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </template>
+
+      <!-- 操作列 -->
+      <template v-slot:action="{ row }">
+        <el-popconfirm
+          class="ele-action"
+          title="确定要删除吗?"
+          @confirm="remove(row)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
+    </ele-pro-table>
+    <product-list
+      ref="productListRef"
+      classType="1"
+      :is-get-inventory-total="true"
+      @changeParent="changeParent"
+    ></product-list>
+    <head-list ref="headRef" @changeParent="changeAnswer"></head-list>
+    <ProductionVersion
+      ref="versionRefs"
+      @changeProduct="changeProduct"
+    ></ProductionVersion>
+  </el-form>
+</template>
+<script>
+  import { numberReg } from 'ele-admin';
+  import productList from '@/BIZComponents/product-list.vue';
+  import dictMixins from '@/mixins/dictMixins';
+  import fileUpload from '@/components/upload/fileUpload';
+  import headList from '@/BIZComponents/user-select/user-select.vue';
+  import ProductionVersion from '@/components/ProductionVersion2/index.vue';
+  import { getInventoryTotalAPI } from '@/api/bpm/components/wms/index.js';
+
+  import { getByCode } from '@/api/system/dictionary-data';
+  import fileMain from '@/components/addDoc/index.vue';
+  import { pricingWayList } from '@/enum/dict.js';
+  import { changeCount } from '@/BIZComponents/setProduct.js';
+
+  const dayjs = require('dayjs');
+
+  export default {
+    mixins: [dictMixins],
+    components: {
+      fileMain,
+      productList,
+      fileUpload,
+      headList,
+      ProductionVersion
+    },
+    props: {
+      pageName: {
+        default: '',
+        type: String
+      },
+      isDiscountTotalPrice: {
+        default: false,
+        type: Boolean
+      },
+      isDeliveryDeadline: {
+        default: true,
+        type: Boolean
+      },
+      isGuaranteePeriod: {
+        default: true,
+        type: Boolean
+      },
+      isCustomerMark: {
+        default: true,
+        type: Boolean
+      },
+      customerMark: {
+        default: '',
+        type: String
+      },
+
+      isContractId: {
+        type: Boolean,
+        default: false
+      },
+      pricingWay: {
+        type: [Number, String],
+        default: 1
+      },
+      isDrawer: {
+        type: Boolean,
+        default: false
+      }
+    },
+    data() {
+      const defaultForm = {
+        key: null,
+        endTime: '',
+        isFirst: 0,
+        name: '',
+        startTime: '',
+        workHour: '',
+        guaranteePeriodUnitCode: '',
+        technicalDrawings: []
+      };
+      return {
+        allPrice: 0,
+        discountTotalPrice: 0,
+        numberReg,
+        defaultForm,
+        form: {
+          datasource: []
+        },
+        pricingWayList,
+        rules: {},
+        dictList: {},
+        columns: [
+          {
+            width: 45,
+            type: 'index',
+            columnKey: 'index',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            width: 280,
+            prop: 'productName',
+            label: '名称',
+            slot: 'productName',
+            headerSlot: 'headerProductName',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'productCode',
+            label: '编码',
+            slot: 'productCode',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'productCategoryName',
+            label: '类型',
+            slot: 'productCategoryName',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'productBrand',
+            label: '牌号',
+            slot: 'productBrand',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'modelType',
+            label: '型号',
+            slot: 'modelType',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'specification',
+            label: '规格',
+            slot: 'specification',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'imgCode',
+            align: 'center',
+            label: '图号/件号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'produceType',
+            align: 'center',
+            label: '生产类型',
+            showOverflowTooltip: true,
+            formatter: (row, column) => {
+              return row.produceType && row.produceType.length
+                ? row.produceType
+                    .map((item) => this.getDictV('productionType', item + ''))
+                    .join(',')
+                : '';
+            }
+          },
+          {
+            width: 120,
+            prop: 'approvalNumber',
+            align: 'center',
+            label: '批准文号',
+            showOverflowTooltip: true
+          },
+          {
+            width: 120,
+            prop: 'packingSpecification',
+            align: 'center',
+            label: '包装规格',
+            showOverflowTooltip: true
+          },
+          {
+            width: 200,
+            prop: 'customerMark',
+            label: '客户代号',
+            slot: 'customerMark',
+            align: 'center'
+          },
+          {
+            width: 150,
+            prop: 'totalCount',
+            label: '数量',
+            slot: 'totalCount',
+            headerSlot: 'headerTotalCount',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'availableCountBase',
+            label: '库存数量',
+            slot: 'availableCountBase',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'measuringUnit',
+            label: '计量单位',
+            slot: 'measuringUnit',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'singleWeight',
+            label: '单重',
+            slot: 'singleWeight',
+            headerSlot: 'headerSingleWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'totalWeight',
+            label: '总重',
+            slot: 'totalWeight',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'weightUnit',
+            label: '重量单位',
+            slot: 'weightUnit',
+            align: 'center'
+          },
+
+          {
+            width: 160,
+            prop: 'pricingWay',
+            label: '计价方式',
+            slot: 'pricingWay',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'singlePrice',
+            label: '单价',
+            slot: 'singlePrice',
+            headerSlot: 'headerSinglePrice',
+            align: 'center'
+          },
+
+          {
+            width: 120,
+            prop: 'totalPrice',
+            label: '合计',
+            slot: 'totalPrice',
+            align: 'center'
+          },
+
+          {
+            width: 160,
+            prop: 'customerExpectDeliveryDeadline',
+            label: '客户期望交期',
+            slot: 'customerExpectDeliveryDeadline',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 160,
+            prop: 'produceDeliveryDeadline',
+            label: '生产交付交期',
+            slot: 'produceDeliveryDeadline',
+
+            align: 'center'
+          },
+
+          {
+            width: 200,
+            prop: 'guaranteePeriod',
+            label: '质保期',
+            slot: 'guaranteePeriod',
+            headerSlot: 'headerCustomerExpectDeliveryDeadline',
+            align: 'center'
+          },
+          {
+            width: 200,
+            prop: 'guaranteePeriodDeadline',
+            label: '质保期截止日期',
+            slot: 'guaranteePeriodDeadline',
+            show: this.isGuaranteePeriod,
+            align: 'center'
+          },
+
+          {
+            width: 220,
+            prop: 'customerReqFiles',
+            label: '客户需求',
+            slot: 'customerReqFiles',
+            align: 'center'
+          },
+          {
+            width: 130,
+            prop: 'technicalAnswerName',
+            label: '技术答疑人',
+            slot: 'technicalAnswerName',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'technicalParams',
+            label: '技术参数',
+            slot: 'technicalParams',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technicalDrawings',
+            label: '技术图纸',
+            slot: 'technicalDrawings',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'technologyRouteName',
+            label: '工艺路线',
+            slot: 'technologyRouteName',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'industryArtFiles',
+            label: '工艺附件',
+            slot: 'industryArtFiles',
+            align: 'center'
+          },
+          {
+            width: 240,
+            prop: 'otherFiles',
+            label: '其他附件',
+            slot: 'otherFiles',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'remark',
+            label: '备注',
+            slot: 'remark',
+            align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 120,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            fixed: 'right',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    computed: {
+      canHandl() {
+        return this.form.datasource.length;
+      }
+    },
+
+    created() {
+      this.getDictList('productionType');
+    },
+    methods: {
+      getDictV(code, val) {
+        if (!this.dictList[code]) return '';
+        return this.dictList[code].find((item) => item.value == val)?.label;
+      },
+      async getDictList(code) {
+        let { data: res } = await getByCode(code);
+        this.dictList[code] = res.map((item) => {
+          let values = Object.keys(item);
+          return {
+            value: values[0],
+            label: item[values[0]]
+          };
+        });
+      },
+
+      openVersion(index) {
+        this.$refs.versionRefs.open(index);
+      },
+      //工艺路线
+      changeProduct(data, index) {
+        this.$set(
+          this.form.datasource[index],
+          'technologyRouteName',
+          data.name
+        );
+        this.$set(this.form.datasource[index], 'technologyRouteId', data.id);
+      },
+      setDeliveryDays(row, index, type, isAll) {
+        if (isAll) {
+          this.form.datasource.forEach((item, i) => {
+            let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+              item.guaranteePeriodUnitCode
+            );
+
+            this.$set(
+              this.form.datasource[i],
+              'guaranteePeriodDeadline',
+              guaranteePeriodUnitName != 'second'
+                ? this.setDay(item.guaranteePeriod, guaranteePeriodUnitName)
+                : ''
+            );
+            // }
+          });
+          return;
+        }
+
+        if (type == 'guaranteePeriod') {
+          let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+            row.guaranteePeriodUnitCode
+          );
+          this.$set(
+            this.form.datasource[index],
+            'guaranteePeriodDeadline',
+            guaranteePeriodUnitName != 'second'
+              ? this.setDay(row.guaranteePeriod, guaranteePeriodUnitName)
+              : ''
+          );
+        }
+      },
+      guaranteePeriodUnit(code) {
+        return code == 3
+          ? 'day'
+          : code == 4
+          ? 'month'
+          : code == 5
+          ? 'year'
+          : 'second';
+      },
+      setDay(addDay, dateType = 'day') {
+        return dayjs(this.contractStartDate || new Date())
+          .add(addDay, dateType)
+          .format('YYYY-MM-DD');
+      },
+      // 返回列表数据
+      getTableValue() {
+        let comitDatasource = this.form.datasource;
+        if (comitDatasource.length === 0) return [];
+        comitDatasource.forEach((v) => {
+          if (v.guaranteePeriodUnitCode) {
+            v.guaranteePeriodUnitName = this.getDictValue(
+              '保质期单位',
+              v.guaranteePeriodUnitCode
+            );
+          }
+          v.technicalDrawings = v.technicalDrawings ? v.technicalDrawings : [];
+          v.customerReqFiles = v.customerReqFiles || [];
+          v.industryArtFiles = v.industryArtFiles || [];
+          v.otherFiles = v.otherFiles || [];
+        });
+        return comitDatasource;
+      },
+      getPrice() {
+        return [this.allPrice, this.form.discountTotalPrice];
+      },
+      //改变数量
+      changeCount(row, index) {
+        const { allPrice, arr } = changeCount(row, index, this.form.datasource);
+        this.form.datasource = arr;
+        this.allPrice = allPrice || 0;
+      },
+      setCustomerMark(customerMark) {
+        this.form.datasource.forEach((item) => {
+          item['customerMark'] = customerMark;
+          this.$forceUpdate();
+        });
+      },
+
+      //修改回显
+      async putTableValue(data) {
+        let productList =
+          (data &&
+            (data.quoteProductList || data.productList || data.detailList)) ||
+          [];
+        if (productList) {
+          productList.forEach((item) => {
+            item.guaranteePeriodUnitCode = item.guaranteePeriodUnitCode
+              ? item.guaranteePeriodUnitCode + ''
+              : '';
+
+            let guaranteePeriodUnitName = this.guaranteePeriodUnit(
+              item.guaranteePeriodUnitCode
+            );
+            if (item.guaranteePeriod && item.guaranteePeriodUnitCode) {
+              item['guaranteePeriodDeadline'] =
+                item['guaranteePeriodDeadline'] ||
+                guaranteePeriodUnitName != 'second'
+                  ? this.setDay(item.guaranteePeriod, guaranteePeriodUnitName)
+                  : '';
+            }
+          });
+          this.form.datasource = productList;
+          this.changeCount();
+          let codeList = this.form.datasource.map((item) => item.productCode);
+          //获取仓库库存
+          let inventoryTotalList = await getInventoryTotalAPI(codeList);
+          this.form.datasource.forEach((item) => {
+            let find =
+              inventoryTotalList.find((key) => key.code == item.productCode) ||
+              {};
+            item.availableCountBase = find.availableCountBase;
+          });
+          this.$refs.table.reload();
+        }
+      },
+
+      //计算单重
+
+      //选择产品
+      handParent(row, index) {
+        let item = {
+          id: row.productCode
+        };
+        this.$refs.productListRef.open(item, index);
+      },
+      //选择技术人回调
+      changeAnswer(obj, idx) {
+        this.$set(this.form.datasource[idx], 'technicalAnswerId', obj.id);
+        this.$set(this.form.datasource[idx], 'technicalAnswerName', obj.name);
+      },
+      handHead(row, index) {
+        let item = {
+          id: row.technicalAnswerId
+        };
+        this.$refs.headRef.open(item, index);
+      },
+      //选择产品回调
+      changeParent(obj, idx) {
+        obj.forEach((item, index) => {
+          let i = idx == -1 ? index : idx;
+          let row = JSON.parse(JSON.stringify(this.defaultForm));
+          row.key = this.form.datasource.length + 1;
+          let parasm = idx == -1 ? row : this.form.datasource[i];
+
+          this.$set(parasm, 'productId', item.id);
+          this.$set(parasm, 'categoryName', item.name);
+          this.$set(parasm, 'productCategoryId', item.categoryLevelId);
+          this.$set(parasm, 'productBrand', item.brandNum);
+          this.$set(parasm, 'productCategoryName', item.categoryLevelPath);
+          this.$set(parasm, 'productCode', item.code);
+          this.$set(parasm, 'productName', item.name);
+          this.$set(parasm, 'modelType', item.modelType);
+          this.$set(parasm, 'availableCountBase', item.availableCountBase);
+          this.$set(parasm, 'measuringUnit', item.measuringUnit);
+          this.$set(parasm, 'specification', item.specification);
+          this.$set(parasm, 'weightUnit', item.weightUnit);
+          this.$set(parasm, 'singleWeight', item.roughWeight);
+          this.$set(parasm, 'pricingWay', 1);
+
+          this.$set(parasm, 'imgCode', item.imgCode);
+          this.$set(parasm, 'produceType', item.produceType);
+          this.$set(parasm, 'approvalNumber', item.extField.approvalNumber);
+          this.$set(
+            parasm,
+            'packingSpecification',
+            item.extField.packingSpecification
+          );
+          this.$set(parasm, 'customerMark', this.customerMark);
+
+          if (idx == -1) {
+            this.form.datasource.push(row);
+          }
+        });
+      },
+      remove(row) {
+        let index = this.form.datasource.findIndex((n) => n.key == row.key);
+        if (index !== -1) {
+          this.form.datasource.splice(index, 1);
+          this.setSort();
+        }
+      },
+      // 清空表格
+      restTable() {
+        this.form.datasource = [];
+      },
+      // 重新排序
+      setSort() {
+        this.form.datasource.forEach((n, index) => {
+          n.key = index + 1;
+        });
+      },
+      // 添加
+      handlAdd() {
+        let item = JSON.parse(JSON.stringify(this.defaultForm));
+        item.key = this.form.datasource.length + 1;
+        this.form.datasource.push(item);
+      },
+
+      validateForm(callback) {
+        //开始表单校验
+        this.$refs.form.validate((valid, obj) => {
+          if (obj) {
+            let messages = Object.keys(obj).map((key) => obj[key][0]);
+            if (messages.length > 0) {
+              this.$message.warning(messages[0].message);
+            }
+          }
+          callback(valid);
+        });
+      },
+      save() {
+        this.$emit('save');
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      padding-right: 30px;
+    }
+  }
+
+  .time-form .el-form-item {
+    margin-bottom: 0 !important;
+  }
+
+  ::v-deep .period {
+    display: flex;
+
+    .borderleftnone {
+      .el-input--medium .el-input__inner {
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+      }
+    }
+
+    .borderrightnone {
+      .el-input--medium .el-input__inner {
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+      }
+    }
+  }
+
+  ::v-deep .time-form tbody > tr:hover > td {
+    background-color: transparent !important;
+  }
+
+  ::v-deep .time-form .el-table tr {
+    background-color: #ffffff;
+  }
+
+  .pricebox {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    font-weight: bold;
+  }
+</style>

+ 3 - 2
src/views/bpm/handleTask/components/quotation/addDialog.vue

@@ -298,7 +298,8 @@
 <script>
   import { emailReg, numberReg } from 'ele-admin';
   import { acceptUnpackoptions } from '@/enum/dict';
-  import inventoryTable from '@/views/bpm/handleTask/components/contractBook/inventoryTable.vue';
+  import inventoryTable from '@/BIZComponents/inventoryTable.vue';
+
 
   import fileUpload from '@/components/upload/fileUpload';
   import dictMixins from '@/mixins/dictMixins';
@@ -594,7 +595,7 @@
           let commitData = Object.assign({}, this.form, {
             settlementModeName,
             quoteProductList: this.$refs.inventoryTable.getTableValue(),
-            totalPrice: this.$refs.inventoryTable.getTotalPrice()
+            totalPrice: this.$refs.inventoryTable.getPrice()[0]
           });
           return commitData;
           // UpdateInformation(commitData)

+ 3 - 2
src/views/bpm/handleTask/components/quotation/detailDialog.vue

@@ -182,9 +182,10 @@
   import { getFile } from '@/api/system/file';
   import dictMixins from '@/mixins/dictMixins';
   import { copyObj } from '@/utils/util';
-  import inventoryTable from '@/views/bpm/handleTask/components/contractBook/inventoryTable.vue';
+  // import inventoryTable from '@/views/bpm/handleTask/components/contractBook/inventoryTable.vue';
+  import inventoryTabledetail from '@/BIZComponents/inventoryTableDetails.vue';
+  import inventoryTable from '@/BIZComponents/inventoryTable.vue';
 
-  import inventoryTabledetail from '@/views/bpm/handleTask/components/contractBook/inventoryTabledetail.vue';
 
   import { getDetail } from '@/api/bpm/components/saleManage/quotation';
   import fileMain from "@/components/addDoc/index.vue";